void kbd_setkeybits( int key) { /* * NumLock is handled differently here because it is a toggle * key. That is, one pair of DOWN-then-UP is really equal * to DOWN, and another pair is equal to UP. We don't have * to do this with CapsLock because the key itself sticks * down. */ switch (key & 0x7f) { /* set key up and key down */ case 0x47: /* num lock */ if (!(key & 0x80)) { if (ISKEYDOWN(key)) KEYISUP(key); else KEYISDOWN(key); } break; #ifdef LAME_OPTION case ADBK_OPTION: /* work around brokedness in old adb.c */ if (ISKEYDOWN(ADBK_OPTION)) { KEYISUP(ADBK_OPTION); } else { KEYISDOWN(ADBK_OPTION); } break; #endif /* LAME_OPTION */ default: if (key & 0x80) { KEYISUP((key & 0x7f)); /* if((key & 0x7f) == ADBK_CAPSLOCK) * kbd_setlight(0x02); */ } else { /* if((key & 0x7f) == ADBK_CAPSLOCK) * kbd_setlight(0x0); */ if ((key & 0x7f) == ADBK_OPTION && ISKEYDOWN(ADBK_OPTION)) KEYISUP(ADBK_OPTION); else KEYISDOWN(key); } break; } }
void ClsXPMenu::RenderItem( ClsDC *pDC, LPDRAWITEMSTRUCT pdis, ItemData *pData ) { // Determine the image, checkbox and text parts of the menu. ClsRect rcCaption( pdis->rcItem ), rcImage( pdis->rcItem ), rcCheck; rcImage.Right() = rcImage.Left() + m_cxBitmap + 8; rcCaption.Left() += m_cxBitmap + 8; rcCheck = rcImage; rcCheck.Deflate( 1, 1 ); rcCheck.Right()--; // A toplevel item? if ( pData->m_bToplevel ) { // Selected or hot? if ( pdis->itemState & ODS_SELECTED || pdis->itemState & ODS_HOTLIGHT ) { // Select appropiate colors. COLORREF crFg, crBg; if ( pdis->itemState & ODS_HOTLIGHT || ! IsDropped()) { crFg = XPColors.GetXPColor( ClsXPColors::XPC_OUTER_SELECTION); crBg = XPColors.GetXPColor( ClsXPColors::XPC_INNER_SELECTION ); } else { crFg = XPColors.GetXPColor( ClsXPColors::XPC_IMAGE_DISABLED ); crBg = XPColors.GetXPColor( ClsXPColors::XPC_IMAGE_BACKGROUND ); } // Render the background. pDC->OutlinedRectangle( &pdis->rcItem, crFg, crBg ); } else // Simply clear background. pDC->FillRect( &pdis->rcItem, ( HBRUSH )( COLOR_BTNFACE + 1 )); // Adjust the caption rectangle. rcCaption = pdis->rcItem; rcCaption.Offset( 6, 0 ); } else { // Is the item selected? if (( pdis->itemState & ODS_SELECTED ) && pData->m_bSeparator == FALSE ) { // Determine background color. COLORREF crBkgnd; // Is the item disabled or not? if ( ! ( pdis->itemState & ODS_DISABLED )) crBkgnd = XPColors.GetXPColor( ClsXPColors::XPC_INNER_SELECTION ); else { // See if either the up or the down arrow key is pressed. // If so the item is selected using one of these keys. In // That case we render the item differently. // // Sorry about the goto... if ( ! ISKEYDOWN( VK_UP ) && ! ISKEYDOWN( VK_DOWN ) && ! ISKEYDOWN( VK_LEFT ) && ! ISKEYDOWN( VK_RIGHT )) goto normal; crBkgnd = XPColors.GetXPColor( ClsXPColors::XPC_TEXT_BACKGROUND ); } // Render the selection rectangle. pDC->OutlinedRectangle( &pdis->rcItem, XPColors.GetXPColor( ClsXPColors::XPC_OUTER_SELECTION ), crBkgnd ); } else { normal: // Render the image background. ClsBrush brush( XPColors.GetXPColor( ClsXPColors::XPC_IMAGE_BACKGROUND )); pDC->FillRect( rcImage, &brush ); // render the text background. brush.Delete(); brush.CreateSolidBrush( XPColors.GetXPColor( ClsXPColors::XPC_TEXT_BACKGROUND )); pDC->FillRect( rcCaption, &brush ); } // Is the item checked? if ( pdis->itemState & ODS_CHECKED ) { // Disabled? COLORREF crBk, crFg; if ( ! ( pdis->itemState & ODS_DISABLED )) { // Select colors to use. crBk = XPColors.GetXPColor( pdis->itemState & ODS_SELECTED ? ClsXPColors::XPC_INNER_CHECKED_SELECTED : ClsXPColors::XPC_INNER_CHECKED ); crFg = XPColors.GetXPColor( ClsXPColors::XPC_OUTER_CHECKED ); } else { // Select colors to use. crBk = XPColors.GetXPColor( ClsXPColors::XPC_IMAGE_BACKGROUND ); crFg = XPColors.GetXPColor( ClsXPColors::XPC_IMAGE_DISABLED ); } // Render checkbox image. pDC->OutlinedRectangle( rcCheck, crFg, crBk ); // Does this item have a bitmap? if ( pData->m_iBitmap == -1 ) { // Get the item type and checkmark information. ClsMenuItemInfo mi; mi.fMask = MIIM_CHECKMARKS | MIIM_TYPE; if ( GetItemInfo( pdis->itemID, &mi )) { // Radiobutton? if ( mi.fType & MFT_RADIOCHECK ) // Render the radiobutton. RenderRadioBullet( pDC, rcCheck, XPColors.GetXPColor( pdis->itemState & ODS_DISABLED ? ClsXPColors::XPC_IMAGE_DISABLED : ClsXPColors::XPC_TEXT ), pdis->itemState ); else // Render the checkmark or checkmark bitmap. RenderCheckmark( pDC, rcCheck, XPColors.GetXPColor( pdis->itemState & ODS_DISABLED ? ClsXPColors::XPC_IMAGE_DISABLED : ClsXPColors::XPC_TEXT ), XPColors.GetXPColor( ClsXPColors::XPC_TEXT ), pdis->itemState & ~ODS_DISABLED, &mi ); } } } // If we do not have a bitmap and we are // not a seperator we check to see if we // are a Radio-check item. else if ( pData->m_iBitmap == -1 && pData->m_bSeparator == FALSE ) { // Radio item? ClsMenuItemInfo mi; mi.fMask = MIIM_CHECKMARKS | MIIM_TYPE; if ( GetItemInfo( pdis->itemID, &mi ) && mi.fType & MFT_RADIOCHECK ) { // Render the radiobutton. RenderRadioBullet( pDC, rcCheck, XPColors.GetXPColor( pdis->itemState & ODS_DISABLED ? ClsXPColors::XPC_IMAGE_DISABLED : ClsXPColors::XPC_TEXT ), pdis->itemState ); } } // Item data present? if ( pData ) { // Separator? if ( pData->m_bSeparator == TRUE ) { // Create and select pen to render the separator. ClsPen pen( PS_SOLID, 1, XPColors.GetXPColor( ClsXPColors::XPC_SEPARATOR )); ClsSelector s( pDC, pen ); // Render the separator. rcCaption.Top() += rcCaption.Height() / 2; rcCaption.Left() += 8; pDC->MoveTo( rcCaption.TopLeft()); pDC->LineTo( rcCaption.Right(), rcCaption.Top()); } else { // Does the item have a bitmap assigned to it? if ( pData->m_iBitmap >= 0 && reinterpret_cast<ClsXPMenu *>( pData->m_pOwner )->m_hImageList ) { // Adjust image position. rcImage.Offset( -1, 0 ); // Determine image rendering flags. The disabled flag is only used // when the item is disabled and we do not have a disabled imagelist. DWORD dwFlags = 0; if ( pdis->itemState & ODS_SELECTED && ( ! ( pdis->itemState & ODS_DISABLED )) && ( ! ( pdis->itemState & ODS_CHECKED ))) dwFlags |= ClsDrawTools::CDSF_HOT; if ( pdis->itemState & ODS_DISABLED && reinterpret_cast<ClsXPMenu *>( pData->m_pOwner )->m_hDisabledImageList == NULL ) dwFlags |= ClsDrawTools::CDSF_DISABLED; // Determine the image list to use, normal or disabled. HIMAGELIST himl = ( pdis->itemState & ODS_DISABLED && reinterpret_cast<ClsXPMenu *>( pData->m_pOwner )->m_hDisabledImageList ) ? reinterpret_cast<ClsXPMenu *>( pData->m_pOwner )->m_hDisabledImageList : reinterpret_cast<ClsXPMenu *>( pData->m_pOwner )->m_hImageList; // Render image... ClsDrawTools::RenderXPBitmap( *pDC, himl, pData->m_iBitmap, rcImage, dwFlags | ClsDrawTools::CDSF_TRANSPARENT ); // Restore image rectangle position. rcImage.Offset( 1, 0 ); } } } } if ( pData ) { // Any text? if ( pData->m_strItemName ) { // Setup text color and draw mode. pDC->SetTextColor( pdis->itemState & ODS_INACTIVE ? ::GetSysColor( COLOR_GRAYTEXT ) : ( XPColors.GetXPColor( pdis->itemState & ODS_DISABLED ? ClsXPColors::XPC_TEXT_DISABLED : ClsXPColors::XPC_TEXT ))); pDC->SetBkMode( TRANSPARENT ); // Adjust the rectangle. if ( ! pData->m_bToplevel ) { rcCaption.Left() += 8; rcCaption.Right() -= 6; } // Skip checkmark width. if ( ! pData->m_bToplevel ) rcCaption.Right() -= ::GetSystemMetrics( SM_CXMENUCHECK ); // Split caption in a left an right part. ClsString Left, Right; SplitCaption( pData->m_strItemName, Left, Right ); // Render the parts. if ( Left.GetStringLength()) ClsDrawTools::RenderText( *pDC, Left, rcCaption, ClsDrawTools::CDSF_LEFTALIGN | ( pdis->itemState & ODS_NOACCEL ? ClsDrawTools::CDSF_HIDEACCEL : 0 )); if ( Right.GetStringLength()) ClsDrawTools::RenderText( *pDC, Right, rcCaption, ClsDrawTools::CDSF_RIGHTALIGN ); } } }
/* * Turn a scan code to characters, based on the status of keyboard * * How to handle function keys? * Should I mess with NumLock here? */ int kbd_scantokey( int key, u_char * chars) { /* chars must be able to hold at least 3 */ /* but 255 might be safer, if Fkeys become */ /* macros */ int keyssofar = 0; key &= 0x7f; /* don't care about key ups */ /* First, check for arrow keys: */ switch (key) { case ADBK_LEFT: chars[0] = 27; /* Left */ chars[1] = VTCHAR; chars[2] = 'D'; return (3); case ADBK_RIGHT: /* Right C */ chars[0] = 27; chars[1] = VTCHAR; chars[2] = 'C'; return (3); case ADBK_DOWN: /* Down B */ chars[0] = 27; chars[1] = VTCHAR; chars[2] = 'B'; return (3); case ADBK_UP: /* Up A */ chars[0] = 27; chars[1] = VTCHAR; chars[2] = 'A'; return (3); case ADBK_PGUP: /* pgup */ chars[0] = 27; chars[1] = '['; chars[2] = '5'; chars[3] = '~'; return (4); case ADBK_PGDN: /* pgdn */ chars[0] = 27; chars[1] = '['; chars[2] = '6'; chars[3] = '~'; return (4); case ADBK_HOME: /* home */ chars[0] = 27; chars[1] = '['; chars[2] = '1'; chars[3] = '~'; return (4); case ADBK_END: /* end */ chars[0] = 27; chars[1] = '['; chars[2] = '4'; chars[3] = '~'; return (4); /* function keys */ case ADBK_F1: func_dokey(0); return 0; case ADBK_F2: func_dokey(1); return 0; case ADBK_F3: func_dokey(2); return 0; case ADBK_F4: func_dokey(3); return 0; case ADBK_F5: func_dokey(4); return 0; case ADBK_F6: func_dokey(5); return 0; case ADBK_F7: func_dokey(6); return 0; case ADBK_F8: func_dokey(7); return 0; case ADBK_F9: func_dokey(8); return 0; case ADBK_F10: func_dokey(9); return 0; case ADBK_F11: func_dokey(10); return 0; case ADBK_F12: func_dokey(11); return 0; case ADBK_F15: func_init(1); return 0; } if (keyboard[key][0] == 0) return (0); #ifndef OPTSET if (ISKEYDOWN(ADBK_OPTION)) { /* OPTION doubles for Meta */ /* Meta means "prefix with ESC" -- Emacs */ chars[keyssofar++] = 27; } #endif /* OPTSET */ if (ISKEYDOWN(ADBK_CONTROL)) { /* CTRL */ if (keyboard[key][MAP_CTRL] == 0 && key != ADBK_SPACE) return 0; chars[keyssofar++] = keyboard[key][MAP_CTRL]; #ifdef OPTSET } else if (ISKEYDOWN(ADBK_OPTION) && ISKEYDOWN(ADBK_SHIFT)) { /* OPTION + SHIFT */ if (keyboard[key][MAP_OPTSHFT] == 0) return 0; chars[keyssofar++] = keyboard[key][MAP_OPTSHFT]; #endif /* OPTSET */ } else if (ISKEYDOWN(ADBK_SHIFT)) { /* SHIFT */ if (keyboard[key][MAP_SHIFT] == 0) return 0; chars[keyssofar++] = keyboard[key][MAP_SHIFT]; #ifdef OPTSET } else if (ISKEYDOWN(ADBK_OPTION)) { /* OPTION */ if (keyboard[key][MAP_OPTION] == 0) return 0; chars[keyssofar++] = keyboard[key][MAP_OPTION]; #endif /* OPTSET */ } else if (ISKEYDOWN(ADBK_CAPSLOCK)) { /* CAPSLOCK */ if (isealpha(keyboard[key][MAP_SHIFT])) chars[keyssofar++] = keyboard[key][MAP_SHIFT]; else chars[keyssofar++] = keyboard[key][MAP_NORMAL]; } else { /* nothing */ chars[keyssofar++] = keyboard[key][MAP_NORMAL]; } return (keyssofar); }
/* * Take care of storing keydown and keyup, * take care of flower/command keys, which control VTs and GRFs * directly, and also take care of distinguishing RAW from COOKED * key strokes, if the keypress can be sent on to VT. */ void kbd_doevent( int key) { int numchars; u_char chars[256]; u_char ochar = 0; int i; kbd_setkeybits(key); if (!ADBK_PRESS(key)) { /* Key up... */ return; } numchars = kbd_scantokey(key, chars); if (ISKEYDOWN(ADBK_FLOWER)) { /* flower/command */ switch (key) { case ADBK_F: /* font change */ mux_changefont(); break; case ADBK_P: /* pointer */ mouse_on = !mouse_on; mux_mouseon(mouse_on); #ifdef HIDE_MOUSE mouse_vis = 1; /* make sure we show the pointer when * it's turned on */ #endif /* HIDE_MOUSE */ break; case ADBK_O: /* open new vt */ main_newvt(); break; case ADBK_X: /* old paste */ mux_paste(); break; case ADBK_C: /* copy, mac-style */ mux_copy(); break; case ADBK_V: /* paste, mac-style */ mux_realpaste(); break; /* Digits: */ case ADBK_1: case ADBK_2: case ADBK_3: case ADBK_4: case ADBK_5: case ADBK_6: case ADBK_7: case ADBK_8: case ADBK_9: i = keyboard[key][0] - '1'; if (ISKEYDOWN(ADBK_SHIFT)) { mux_vttogrf(i); } else { mux_switchtovt(i); } break; case ADBK_UP: /* up */ mux_vtscroll(1); break; case ADBK_DOWN:/* dn */ mux_vtscroll(-1); break; case ADBK_PGUP:/* pgup */ mux_vtpage(1); break; case ADBK_PGDN:/* pgdn */ mux_vtpage(-1); break; case ADBK_END: /* end */ mux_vtbottom(); break; case ADBK_HOME:/* home */ mux_vttop(); break; } return; } #ifdef HIDE_MOUSE if (mouse_on && mouse_vis && numchars) { /* we have actual * typing, hide the * mouse */ mux_mouseon(!mouse_on); mouse_vis = 0; } #endif /* HIDE_MOUSE */ for (i = 0; i < numchars; i++) { if (indig) { if (chars[i] != ' ') ochar = chars[i]; else ochar = 0; chars[i] = dodig(chars[i], &ochar); goto hoppari; } /* process a digraph */ if ((indig = isdig(chars[i]))) continue; /* if we got a digraph key, don't say * it yet */ hoppari: /* I'm becoming a serious goto-user */ main_keyhit(mux_curvt, chars[i]); if (ochar) { main_keyhit(mux_curvt, ochar); ochar = 0; } } }