/*=========================================================================== // // dd_vmware.c // // PW display driver for eCos under VMWARE // //=========================================================================== //=========================================================================== // This file is part of PW graphic library. // Copyright (C) 2006 Peter Dennett // // PW is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 or (at your option) any later version. // // PW is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // // You should have received a copy of the GNU General Public License along // with PW; if not, write to the Free Software Foundation, Inc., // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. // // As a special exception, if other files instantiate templates or use macros // or inline functions from this file, or you compile this file and link it // with other works to produce a work based on this file, this file does not // by itself cause the resulting work to be covered by the GNU General Public // License. However the source code for this file must still be made available // in accordance with section (3) of the GNU General Public License. // // This exception does not invalidate any other reasons why a work based on // this file might be covered by the GNU General Public License. //=========================================================================== //=========================================================================== // // Author(s): Peter Dennett // //=========================================================================== */ #include "../../vmware/vmware-vga.c" #include /* Cyg_ErrNo, ENOENT */ #include /* cyg_io_handle_t */ #include /* select() functions */ #include /* open() */ #include /* read() */ #include /* rand() */ #include #include #define VMW_BLACK 0 #define VMW_WHITE 255 static pVMWareVGA pVMWARE=0; // Display info static Pw_DD dd; static Pw_LLD lld; static Pw_Display dpy; // -------------------------------------------------------------------------- static void draw_point(Pw_GC* gc, Pw_Coord x, Pw_Coord y) { int color = (Pw_GCGetColor(gc) == pw_black_pixel) ? VMW_BLACK : VMW_WHITE; vmwareDrawPoint(pVMWARE, x, y, color); return; } static void draw_points(Pw_GC* gc, Pw_Coord x, Pw_Coord y, Pw_Byte bits) { Pw_uInt w; Pw_Byte mask = 0x80; uint32 color = (Pw_GCGetColor(gc) == pw_black_pixel) ? VMW_BLACK : VMW_WHITE; for (w = 0; w < 8; w++) { if ((bits & mask) != 0) vmwareDrawPoint(pVMWARE, (uint32)x, (uint32)y, color); x++; mask >>= 1; } return; } static void draw_hor_line(Pw_GC* gc, Pw_Coord x1, Pw_Coord y1, Pw_Coord x2) { uint32 color = (Pw_GCGetColor(gc) == pw_black_pixel) ? VMW_BLACK : VMW_WHITE; while (x1 <= x2) vmwareDrawPoint(pVMWARE, (uint32)x1++, (uint32)y1, color); return; } static void draw_ver_line(Pw_GC* gc, Pw_Coord x1, Pw_Coord y1, Pw_Coord y2) { uint32 color = (Pw_GCGetColor(gc) == pw_black_pixel) ? VMW_BLACK : VMW_WHITE; while (y1 <= y2) vmwareDrawPoint(pVMWARE, (uint32)x1, (uint32)y1++, color); return; } static void fill_rect(Pw_GC* gc, Pw_Coord x, Pw_Coord y, Pw_Coord w, Pw_Coord h) { Pw_Coord y2, x1, x2; x1 = x; x2 = x1 + w - 1; y2 = y + h - 1; while (y <= y2) draw_hor_line(gc, x1, y++, x2); return; } static void display_refresh(Pw_Display* dpy, Pw_Rectangle* area) { vmwareSendSVGACmdUpdateFullScreen(pVMWARE); return; } static Pw_Int display_get_xinput_value(Pw_Display* dpy, Pw_uInt num) { return 0; } // -------------------------------------------------------------------------- extern Pw_Bool Pw_Init(Pw_Display* dpy); bool pw_dd_init(void) { int i; #define N_COLORS 2 vmwareColors colors[N_COLORS]; int indeces[N_COLORS]; if ((pVMWARE = vmwareInitialize()) == (pVMWareVGA)0) { diag_printf("VMWARE-VGA failed initialization\n"); return FALSE; } i = 0; indeces[i] = VMW_BLACK; colors[i].red = 0; colors[i].green = 0; colors[i].blue = 0; i++; indeces[i] = VMW_WHITE; colors[i].red = 255; colors[i].green = 255; colors[i].blue = 255; vmwareLoadPalette(pVMWARE, i+1, indeces, colors); vmwareClear(pVMWARE, VMW_WHITE); lld.draw_point = draw_point; lld.draw_points = draw_points; lld.draw_hor_line = draw_hor_line; lld.draw_ver_line = draw_ver_line; lld.fill_rect = fill_rect; dd.lld = &lld; dd.display_refresh = display_refresh; dd.get_xinput_value = display_get_xinput_value; dd.init_components = Pw_Init; IPw_InitInternals(); IPw_DisplayOpen((Pw_Coord)pVMWARE->FBWidth-1, (Pw_Coord)pVMWARE->FBHeight-1, &dd, &dpy); if (!IPw_InitComponents(&dpy)) { IPw_DisplayClose(&dpy); return false; } IPw_DisplayRefresh(&dpy); return true; } //----------------------------------------------------------------------------- // Keyboard definitions #define KBDATAPORT 0x0060 // data I/O port #define KBCMDPORT 0x0064 // command port (write) #define KBSTATPORT 0x0064 // status port (read) // Scan codes #define LSHIFT 0x2a #define RSHIFT 0x36 #define CTRL 0x1d #define ALT 0x38 #define CAPS 0x3a #define NUMS 0x45 #define BREAK 0x80 // Bits for KBFlags #define KBNormal 0x0000 #define KBShift 0x0001 #define KBCtrl 0x0002 #define KBAlt 0x0004 #define KBIndex 0x0007 // mask for the above #define KBExtend 0x0010 #define KBAck 0x0020 #define KBResend 0x0040 #define KBShiftL (0x0080 | KBShift) #define KBShiftR (0x0100 | KBShift) #define KBCtrlL (0x0200 | KBCtrl) #define KBCtrlR (0x0400 | KBCtrl) #define KBAltL (0x0800 | KBAlt) #define KBAltR (0x1000 | KBAlt) #define KBCapsLock 0x2000 #define KBNumLock 0x4000 static CYG_BYTE KBScanTable[128][4] = { // Normal Shift Control Alt // 0x00 { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0x1b, 0x1b, 0x1b, 0xFF, }, { '1', '!', 0xFF, 0xFF, }, { '2', '"', 0xFF, 0xFF, }, { '3', '#', 0xFF, 0xFF, }, { '4', '$', 0xFF, 0xFF, }, { '5', '%', 0xFF, 0xFF, }, { '6', '^', 0xFF, 0xFF, }, { '7', '&', 0xFF, 0xFF, }, { '8', '*', 0xFF, 0xFF, }, { '9', '(', 0xFF, 0xFF, }, { '0', ')', 0xFF, 0xFF, }, { '-', '_', 0xFF, 0xFF, }, { '=', '+', 0xFF, 0xFF, }, { '\b', '\b', 0xFF, 0xFF, }, { '\t', '\t', 0xFF, 0xFF, }, // 0x10 { 'q', 'Q', 0x11, 0xFF, }, { 'w', 'W', 0x17, 0xFF, }, { 'e', 'E', 0x05, 0xFF, }, { 'r', 'R', 0x12, 0xFF, }, { 't', 'T', 0x14, 0xFF, }, { 'y', 'Y', 0x19, 0xFF, }, { 'u', 'U', 0x15, 0xFF, }, { 'i', 'I', 0x09, 0xFF, }, { 'o', 'O', 0x0F, 0xFF, }, { 'p', 'P', 0x10, 0xFF, }, { '[', '{', 0x1b, 0xFF, }, { ']', '}', 0x1d, 0xFF, }, { '\r', '\r', '\n', 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 'a', 'A', 0x01, 0xFF, }, { 's', 'S', 0x13, 0xFF, }, // 0x20 { 'd', 'D', 0x04, 0xFF, }, { 'f', 'F', 0x06, 0xFF, }, { 'g', 'G', 0x07, 0xFF, }, { 'h', 'H', 0x08, 0xFF, }, { 'j', 'J', 0x0a, 0xFF, }, { 'k', 'K', 0x0b, 0xFF, }, { 'l', 'L', 0x0c, 0xFF, }, { ';', ':', 0xFF, 0xFF, }, { 0x27, '@', 0xFF, 0xFF, }, { '#', '~', 0xFF, 0xFF, }, { '`', '~', 0xFF, 0xFF, }, { '\\', '|', 0x1C, 0xFF, }, { 'z', 'Z', 0x1A, 0xFF, }, { 'x', 'X', 0x18, 0xFF, }, { 'c', 'C', 0x03, 0xFF, }, { 'v', 'V', 0x16, 0xFF, }, // 0x30 { 'b', 'B', 0x02, 0xFF, }, { 'n', 'N', 0x0E, 0xFF, }, { 'm', 'M', 0x0D, 0xFF, }, { ',', '<', 0xFF, 0xFF, }, { '.', '>', 0xFF, 0xFF, }, { '/', '?', 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { '*', 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { ' ', ' ', ' ', ' ', }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xF1, 0xE1, 0xFF, 0xFF, }, { 0xF2, 0xE2, 0xFF, 0xFF, }, { 0xF3, 0xE3, 0xFF, 0xFF, }, { 0xF4, 0xE4, 0xFF, 0xFF, }, { 0xF5, 0xE5, 0xFF, 0xFF, }, // 0x40 { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { '7', 0xFF, 0xFF, 0xFF, }, { '8', 0x15, 0x15, 0x15, }, { '9', 0x10, 0x10, 0x10, }, { '-', 0xFF, 0xFF, 0xFF, }, { '4', 0xFF, 0xFF, 0xFF, }, { '5', 0xFF, 0xFF, 0xFF, }, { '6', 0xFF, 0xFF, 0xFF, }, { '+', 0xFF, 0xFF, 0xFF, }, { '1', 0xFF, 0xFF, 0xFF, }, // 0x50 { '2', 0x04, 0x04, 0x04, }, { '3', 0x0e, 0x0e, 0x0e, }, { '0', 0xFF, 0xFF, 0xFF, }, { '.', 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, // 0x60 { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, // 0x70 { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, { 0xFF, 0xFF, 0xFF, 0xFF, }, }; static int KBIndexTab[8] = { 0, 1, 2, 2, 3, 3, 3, 3 }; static int KBFlags = 0; //----------------------------------------------------------------------------- static CYG_BYTE KeyboardAscii(CYG_BYTE scancode) { CYG_BYTE ascii = 0xFF; // Start by handling all shift/ctl keys: switch( scancode ) { case 0x53: // delete if (KBFlags & KBCtrl && KBFlags & KBAlt) { ; // CYGACC_CALL_IF_RESET(); } break; case 0xe0: KBFlags |= KBExtend; return 0xFF; case 0xfa: KBFlags |= KBAck; return 0xFF; case 0xfe: KBFlags |= KBResend; return 0xFF; case LSHIFT: KBFlags |= KBShiftL; return 0xFF; case LSHIFT | BREAK: KBFlags &= ~KBShiftL; return 0xFF; case RSHIFT: KBFlags |= KBShiftR; return 0xFF; case RSHIFT | BREAK: KBFlags &= ~KBShiftR; return 0xFF; case CTRL: if( KBFlags & KBExtend ) { KBFlags |= KBCtrlR; KBFlags &= ~KBExtend; } else KBFlags |= KBCtrlL; return 0xFF; case CTRL | BREAK: if( KBFlags & KBExtend ) { KBFlags &= ~KBCtrlR; KBFlags &= ~KBExtend; } else KBFlags &= ~KBCtrlL; return 0xFF; case ALT: if( KBFlags & KBExtend ) { KBFlags |= KBAltR; KBFlags &= ~KBExtend; } else KBFlags |= KBAltL; return 0xFF; case ALT | BREAK: if( KBFlags & KBExtend ) { KBFlags &= ~KBAltR; KBFlags &= ~KBExtend; } else KBFlags &= ~KBAltL; return 0xFF; case CAPS: KBFlags ^= KBCapsLock; case CAPS | BREAK: return 0xFF; case NUMS: KBFlags ^= KBNumLock; case NUMS | BREAK: return 0xFF; } // Clear Extend flag if set KBFlags &= ~KBExtend; // Ignore all other BREAK codes if( scancode & 0x80 ) return 0xFF; // Here the scancode is for something we can turn // into an ASCII value ascii = KBScanTable[scancode & 0x7F][KBIndexTab[KBFlags & KBIndex]]; return ascii; } /* KeyboardAscii */ //----------------------------------------------------------------------------- static Pw_Bool ReadKeySym (Pw_uInt *keysym) { CYG_BYTE stat, code; CYG_BYTE c; HAL_READ_UINT8(KBSTATPORT, stat); if ((stat & 0x01) == 0) return FALSE; HAL_READ_UINT8(KBDATAPORT, code); // Translate to ASCII c = KeyboardAscii(code); if (c != 0xFF) { *keysym = c; return TRUE; } return FALSE; } static Pw_Bool TranslateKeyCode(Pw_uInt keysym, Pw_uInt* keycode) { switch (keysym) { case '1': // 0xFF52: *keycode = PW_UP_KEY_CODE; return TRUE; case '2': // 0xFF54: *keycode = PW_DOWN_KEY_CODE; return TRUE; case '3': // 0xFF51: *keycode = PW_LEFT_KEY_CODE; return TRUE; case '4': // 0xFF53: *keycode = PW_RIGHT_KEY_CODE; return TRUE; case '5': // 0xFF56: *keycode = PW_NEXT_KEY_CODE; return TRUE; case '6': // 0xFF55: *keycode = PW_PREV_KEY_CODE; return TRUE; case '7': // 0xFF0D: *keycode = PW_YES_KEY_CODE; return TRUE; default: return FALSE; } } void pw_dd_main_loop(void) { struct timeval selTimeout; int key_sym; int key_pressed = -1; selTimeout.tv_sec = 0; selTimeout.tv_usec = 100000; while(1) { if (select(0, NULL, NULL, NULL, &selTimeout) == 0) { if (ReadKeySym(&key_sym)) if (TranslateKeyCode(key_sym, &key_pressed)) IPw_EventKeyPressed(&dpy, key_pressed); IPw_TimeoutProcess(&dpy, 100); selTimeout.tv_sec = 0; selTimeout.tv_usec = 100000; } } }