/* AbiSource Program Utilities * Copyright (C) 1998-2000 AbiSource, Inc. * * This program 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 * of the License, or (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ #include #include #include "ut_types.h" #include "ut_assert.h" #include "ut_debugmsg.h" #include "ev_EditBinding.h" #include "ev_EditEventMapper.h" #include "ev_EditMethod.h" #include "xav_View.h" #include "ev_NamedVirtualKey.h" #include "ev_UnixKeyboard.h" #include"ut_mbtowc.h" ////////////////////////////////////////////////////////////////// static EV_EditBits s_mapVirtualKeyCodeToNVK(gint keyval); static UT_Bool s_isVirtualKeyCode(gint keyval); static GdkModifierType s_getAltMask(void); ////////////////////////////////////////////////////////////////// // This is used to remember the modifier mask (GDK_MODx_MASK) that // is bound to the Alt keys. We load this once per session. // // TODO Figure out if GTK/GDK can send us a MappingNotify event. // TODO If so, recompute this value. // static GdkModifierType s_alt_mask = GDK_MODIFIER_MASK; // bogus value GdkModifierType ev_UnixKeyboard::getAltModifierMask(void) { return s_alt_mask; } ////////////////////////////////////////////////////////////////// ev_UnixKeyboard::ev_UnixKeyboard(EV_EditEventMapper* pEEM) : EV_Keyboard(pEEM) { if (s_alt_mask == GDK_MODIFIER_MASK) s_alt_mask = s_getAltMask(); } ev_UnixKeyboard::~ev_UnixKeyboard(void) { } UT_Bool ev_UnixKeyboard::keyPressEvent(AV_View* pView, GdkEventKey* e) { EV_EditBits state = 0; EV_EditEventMapperResult result; EV_EditMethod * pEM; if (e->state & GDK_SHIFT_MASK) state |= EV_EMS_SHIFT; if (e->state & GDK_CONTROL_MASK) state |= EV_EMS_CONTROL; if (e->state & (s_alt_mask)) state |= EV_EMS_ALT; //UT_DEBUGMSG(("KeyPressEvent: keyval=%04lx state=%04lx\n",e->keyval,state)); if (s_isVirtualKeyCode(e->keyval)) { EV_EditBits nvk = s_mapVirtualKeyCodeToNVK(e->keyval); switch (nvk) { case EV_NVK__IGNORE__: return UT_FALSE; default: result = m_pEEM->Keystroke((UT_uint32)EV_EKP_PRESS|state|nvk,&pEM); switch (result) { case EV_EEMR_BOGUS_START: // If it is a bogus key and we don't have a sequence in // progress, we should let the system handle it // (this lets things like ALT-F4 work). return UT_FALSE; case EV_EEMR_BOGUS_CONT: // If it is a bogus key but in the middle of a sequence, // we should silently eat it (this is to prevent things // like Control-X ALT-F4 from killing us -- if they want // to kill us, fine, but they shouldn't be in the middle // of a sequence). return UT_TRUE; case EV_EEMR_COMPLETE: UT_ASSERT(pEM); invokeKeyboardMethod(pView,pEM,0,0); // no char data to offer return UT_TRUE; case EV_EEMR_INCOMPLETE: return UT_TRUE; default: UT_ASSERT(0); return UT_TRUE; } } } else { UT_uint16 charData = e->keyval; UT_Mbtowc m; wchar_t wc; UT_UCSChar *ucs; char *mbs=e->string; int mLength=strlen(mbs); int uLength; if(charData>0xff) result = m_pEEM->Keystroke(EV_EKP_PRESS|state|'a',&pEM); else result = m_pEEM->Keystroke(EV_EKP_PRESS|state|charData,&pEM); switch (result) { case EV_EEMR_BOGUS_START: // If it is a bogus key and we don't have a sequence in // progress, we should let the system handle it // (this lets things like ALT-F4 work). return UT_FALSE; case EV_EEMR_BOGUS_CONT: // If it is a bogus key but in the middle of a sequence, // we should silently eat it (this is to prevent things // like Control-X ALT-F4 from killing us -- if they want // to kill us, fine, but they shouldn't be in the middle // of a sequence). return UT_TRUE; case EV_EEMR_COMPLETE: UT_ASSERT(pEM); uLength=0; ucs=new UT_UCSChar[mLength]; for(int i=0;i 0x0000FFFF) return UT_FALSE;//was UT_TRUE before CJK patch if (keyval > 0xFF00) // see the above table return UT_TRUE; if (keyval > 0xFE00) return UT_TRUE; UT_ASSERT(keyval <= 0xFD00); // we don't what to do with 3270 keys if (keyval == 0x0020) // special handling for ASCII-Space return UT_TRUE; return UT_FALSE; } static EV_EditBits s_mapVirtualKeyCodeToNVK(gint keyval) { // map the given virtual key into a "named virtual key". // these are referenced by NVK_ symbol so that the cross // platform code can properly refer to them. // there is also a set of Hardware Vendor ranges defined. // these appear to have stuff in the high word. (see {ap_,DEC,HP,Sun}keysym.h) // for now, we will ignore these. if (keyval >0x0000FFFF) return EV_NVK__IGNORE__; if (keyval > 0xFF00) return s_Table_NVK_0xff[keyval - 0xFF00]; if (keyval > 0xFE00) return s_Table_NVK_0xfe[keyval - 0xFE00]; if (keyval == 0x0020) return EV_NVK_SPACE; UT_ASSERT(0); return EV_NVK__IGNORE__; } ////////////////////////////////////////////////////////////////// // deal with keyboard mapping oddities ////////////////////////////////////////////////////////////////// #include #include #include #include static GdkModifierType s_getAltMask(void) { ////////////////////////////////////////////////////////////////// // find out what modifier mask XL_Alt_{L,R} are bound to. ////////////////////////////////////////////////////////////////// int alt_mask = 0; Display * display = GDK_DISPLAY(); KeyCode kcAltL = XKeysymToKeycode(display,XK_Alt_L); KeyCode kcAltR = XKeysymToKeycode(display,XK_Alt_R); XModifierKeymap * pModMap = XGetModifierMapping(display); int mkpm = pModMap->max_keypermod; int k,m; int mAltL=-1; int mAltR=-1; for (m=0; m<8; m++) { for (k=0; kmodifiermap[m*mkpm + k]; if (kcAltL && (code == kcAltL)) mAltL = m; if (kcAltR && (code == kcAltR)) mAltR = m; } } switch (mAltL) { default: // Should not happen... case -1: // Alt_L is not a modifier key ?? case 0: // Alt_L is mapped to SHIFT ?? case 1: // Alt_L is mapped to (Caps)LOCK ?? case 2: // Alt_L is mapped to CONTROL ?? break; // ... ignore this key. case 3: alt_mask |= GDK_MOD1_MASK; break; case 4: alt_mask |= GDK_MOD2_MASK; break; case 5: alt_mask |= GDK_MOD3_MASK; break; case 6: alt_mask |= GDK_MOD4_MASK; break; case 7: alt_mask |= GDK_MOD5_MASK; break; } switch (mAltR) { default: // Should not happen... case -1: // Alt_R is not a modifier key ?? case 0: // Alt_R is mapped to SHIFT ?? case 1: // Alt_R is mapped to (Caps)LOCK ?? case 2: // Alt_R is mapped to CONTROL ?? break; // ... ignore this key. case 3: alt_mask |= GDK_MOD1_MASK; break; case 4: alt_mask |= GDK_MOD2_MASK; break; case 5: alt_mask |= GDK_MOD3_MASK; break; case 6: alt_mask |= GDK_MOD4_MASK; break; case 7: alt_mask |= GDK_MOD5_MASK; break; } XFreeModifiermap(pModMap); if (!alt_mask) // if nothing set, fall back to MOD1 alt_mask = GDK_MOD1_MASK; //UT_DEBUGMSG(("Keycodes for alt [l 0x%x][r 0x%x] using modifiers [%d %d] yields [0x%x]\n",kcAltL,kcAltR,mAltL-2,mAltR-2,alt_mask)); return (GdkModifierType)alt_mask; }