diff --git a/dlls/x11drv/event.c b/dlls/x11drv/event.c index 399ce347226..a570993a1ff 100644 --- a/dlls/x11drv/event.c +++ b/dlls/x11drv/event.c @@ -136,9 +136,12 @@ static int process_events( struct x11drv_thread_data *data ) wine_tsx11_lock(); while ( XPending( data->display ) ) { + Bool ignore; + XNextEvent( data->display, &event ); + ignore = XFilterEvent( &event, None ); wine_tsx11_unlock(); - EVENT_ProcessEvent( &event ); + if (!ignore) EVENT_ProcessEvent( &event ); count++; wine_tsx11_lock(); } @@ -478,13 +481,22 @@ static const char * const focus_details[] = */ static void EVENT_FocusIn( HWND hwnd, XFocusChangeEvent *event ) { + XIC xic; + if (!hwnd) return; TRACE( "win %p xwin %lx detail=%s\n", hwnd, event->window, focus_details[event->detail] ); - if (wmTakeFocus) return; /* ignore FocusIn if we are using take focus */ if (event->detail == NotifyPointer) return; + if ((xic = X11DRV_get_ic( hwnd ))) + { + wine_tsx11_lock(); + XSetICFocus( xic ); + wine_tsx11_unlock(); + } + if (wmTakeFocus) return; /* ignore FocusIn if we are using take focus */ + if (!can_activate_window(hwnd)) { HWND hwnd = GetFocus(); @@ -507,11 +519,18 @@ static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event ) HWND hwnd_tmp; Window focus_win; int revert; + XIC xic; TRACE( "win %p xwin %lx detail=%s\n", hwnd, event->window, focus_details[event->detail] ); if (event->detail == NotifyPointer) return; x11drv_thread_data()->last_focus = hwnd; + if ((xic = X11DRV_get_ic( hwnd ))) + { + wine_tsx11_lock(); + XUnsetICFocus( xic ); + wine_tsx11_unlock(); + } if (hwnd != GetForegroundWindow()) return; SendMessageA( hwnd, WM_CANCELMODE, 0, 0 ); diff --git a/dlls/x11drv/keyboard.c b/dlls/x11drv/keyboard.c index 13d3dfc907b..73c67cd62a1 100644 --- a/dlls/x11drv/keyboard.c +++ b/dlls/x11drv/keyboard.c @@ -840,11 +840,14 @@ static const WORD nonchar_key_scan[256] = /* Returns the Windows virtual key code associated with the X event */ /* x11 lock must be held */ -static WORD EVENT_event_to_vkey( XKeyEvent *e) +static WORD EVENT_event_to_vkey( XIC xic, XKeyEvent *e) { KeySym keysym; - XLookupString(e, NULL, 0, &keysym, NULL); + if (xic) + XmbLookupString(xic, e, NULL, 0, &keysym, NULL); + else + XLookupString(e, NULL, 0, &keysym, NULL); if ((keysym >= 0xFFAE) && (keysym <= 0xFFB9) && (keysym != 0xFFAF) && (e->state & NumLockMask)) @@ -988,7 +991,7 @@ void X11DRV_KeyEvent( HWND hwnd, XKeyEvent *event ) WORD vkey = 0, bScan; DWORD dwFlags; int ascii_chars; - + XIC xic = X11DRV_get_ic( hwnd ); DWORD event_time = event->time - X11DRV_server_startticks; /* this allows support for dead keys */ @@ -996,18 +999,12 @@ void X11DRV_KeyEvent( HWND hwnd, XKeyEvent *event ) event->keycode=(event->keycode & 0xff); wine_tsx11_lock(); - ascii_chars = XLookupString(event, Str, sizeof(Str), &keysym, NULL); + if (xic) + ascii_chars = XmbLookupString(xic, event, Str, sizeof(Str), &keysym, NULL); + else + ascii_chars = XLookupString(event, Str, sizeof(Str), &keysym, NULL); wine_tsx11_unlock(); - /* Ignore some unwanted events */ - if (keysym == XK_ISO_Prev_Group || - keysym == XK_ISO_Next_Group || - keysym == XK_Mode_switch) - { - TRACE("Ignoring %s keyboard event\n", TSXKeysymToString(keysym)); - return; - } - TRACE_(key)("state = %X\n", event->state); /* If XKB extensions are used, the state mask for AltGr will use the group @@ -1034,7 +1031,9 @@ void X11DRV_KeyEvent( HWND hwnd, XKeyEvent *event ) } wine_tsx11_lock(); - vkey = EVENT_event_to_vkey(event); + vkey = EVENT_event_to_vkey(xic,event); + /* X returns keycode 0 for composed characters */ + if (!vkey && ascii_chars) vkey = VK_NONAME; wine_tsx11_unlock(); TRACE_(key)("keycode 0x%x converted to vkey 0x%x\n", @@ -1123,7 +1122,19 @@ X11DRV_KEYBOARD_DetectLayout (void) keysym = XKeycodeToKeysym (display, keyc, i); /* Allow both one-byte and two-byte national keysyms */ if ((keysym < 0x8000) && (keysym != ' ')) - ckey[i] = keysym & 0xFF; + { +#ifdef HAVE_XKB + if (!is_xkb || !XkbTranslateKeySym(display, &keysym, 0, &ckey[i], 1, NULL)) +#endif + { + TRACE("XKB could not translate keysym %ld\n", keysym); + /* FIXME: query what keysym is used as Mode_switch, fill XKeyEvent + * with appropriate ShiftMask and Mode_switch, use XLookupString + * to get character in the local encoding. + */ + ckey[i] = keysym & 0xFF; + } + } else { ckey[i] = KEYBOARD_MapDeadKeysym(keysym); } @@ -1277,8 +1288,18 @@ void X11DRV_InitKeyboard( BYTE *key_state_table ) int maxlen=0,maxval=-1,ok; for (i=0; i=XK_KP_0) && (keysym<=XK_KP_9)) { - *(char*)lpChar = 0; + lpChar[0] = 0; ret = 0; } @@ -1863,7 +1898,7 @@ INT X11DRV_ToUnicode(UINT virtKey, UINT scanCode, LPBYTE lpKeyState, if (((keysym>=33) && (keysym < 'A')) || ((keysym > 'Z') && (keysym < 'a'))) { - *(char*)lpChar = 0; + lpChar[0] = 0; ret = 0; } } @@ -1872,13 +1907,13 @@ INT X11DRV_ToUnicode(UINT virtKey, UINT scanCode, LPBYTE lpKeyState, extended keyboard. X returns a char for it, but Windows doesn't */ if (keysym == XK_Delete) { - *(char*)lpChar = 0; + lpChar[0] = 0; ret = 0; } else if((lpKeyState[VK_SHIFT] & 0x80) /* Shift is pressed */ && (keysym == XK_KP_Decimal)) { - *(char*)lpChar = 0; + lpChar[0] = 0; ret = 0; } @@ -1887,7 +1922,7 @@ INT X11DRV_ToUnicode(UINT virtKey, UINT scanCode, LPBYTE lpKeyState, { TRACE_(key)("Translating char 0x%02x from code page %d to unicode\n", *(BYTE *)lpChar, main_key_tab[kbd_layout].layout_cp); - ret = MultiByteToWideChar(main_key_tab[kbd_layout].layout_cp, 0, (LPCSTR)lpChar, ret, bufW, bufW_size); + ret = MultiByteToWideChar(main_key_tab[kbd_layout].layout_cp, 0, lpChar, ret, bufW, bufW_size); } } diff --git a/windows/message.c b/windows/message.c index 8527cf95f48..4f7375c1a65 100644 --- a/windows/message.c +++ b/windows/message.c @@ -681,124 +681,6 @@ void WINAPI UserYield16(void) } -struct accent_char -{ - BYTE ac_accent; - BYTE ac_char; - BYTE ac_result; -}; - -static const struct accent_char accent_chars[] = -{ -/* A good idea should be to read /usr/X11/lib/X11/locale/iso8859-x/Compose */ - {'`', 'A', '\300'}, {'`', 'a', '\340'}, - {'\'', 'A', '\301'}, {'\'', 'a', '\341'}, - {'^', 'A', '\302'}, {'^', 'a', '\342'}, - {'~', 'A', '\303'}, {'~', 'a', '\343'}, - {'"', 'A', '\304'}, {'"', 'a', '\344'}, - {'O', 'A', '\305'}, {'o', 'a', '\345'}, - {'0', 'A', '\305'}, {'0', 'a', '\345'}, - {'A', 'A', '\305'}, {'a', 'a', '\345'}, - {'A', 'E', '\306'}, {'a', 'e', '\346'}, - {',', 'C', '\307'}, {',', 'c', '\347'}, - {'`', 'E', '\310'}, {'`', 'e', '\350'}, - {'\'', 'E', '\311'}, {'\'', 'e', '\351'}, - {'^', 'E', '\312'}, {'^', 'e', '\352'}, - {'"', 'E', '\313'}, {'"', 'e', '\353'}, - {'`', 'I', '\314'}, {'`', 'i', '\354'}, - {'\'', 'I', '\315'}, {'\'', 'i', '\355'}, - {'^', 'I', '\316'}, {'^', 'i', '\356'}, - {'"', 'I', '\317'}, {'"', 'i', '\357'}, - {'-', 'D', '\320'}, {'-', 'd', '\360'}, - {'~', 'N', '\321'}, {'~', 'n', '\361'}, - {'`', 'O', '\322'}, {'`', 'o', '\362'}, - {'\'', 'O', '\323'}, {'\'', 'o', '\363'}, - {'^', 'O', '\324'}, {'^', 'o', '\364'}, - {'~', 'O', '\325'}, {'~', 'o', '\365'}, - {'"', 'O', '\326'}, {'"', 'o', '\366'}, - {'/', 'O', '\330'}, {'/', 'o', '\370'}, - {'`', 'U', '\331'}, {'`', 'u', '\371'}, - {'\'', 'U', '\332'}, {'\'', 'u', '\372'}, - {'^', 'U', '\333'}, {'^', 'u', '\373'}, - {'"', 'U', '\334'}, {'"', 'u', '\374'}, - {'\'', 'Y', '\335'}, {'\'', 'y', '\375'}, - {'T', 'H', '\336'}, {'t', 'h', '\376'}, - {'s', 's', '\337'}, {'"', 'y', '\377'}, - {'s', 'z', '\337'}, {'i', 'j', '\377'}, - /* iso-8859-2 uses this */ - {'<', 'L', '\245'}, {'<', 'l', '\265'}, /* caron */ - {'<', 'S', '\251'}, {'<', 's', '\271'}, - {'<', 'T', '\253'}, {'<', 't', '\273'}, - {'<', 'Z', '\256'}, {'<', 'z', '\276'}, - {'<', 'C', '\310'}, {'<', 'c', '\350'}, - {'<', 'E', '\314'}, {'<', 'e', '\354'}, - {'<', 'D', '\317'}, {'<', 'd', '\357'}, - {'<', 'N', '\322'}, {'<', 'n', '\362'}, - {'<', 'R', '\330'}, {'<', 'r', '\370'}, - {';', 'A', '\241'}, {';', 'a', '\261'}, /* ogonek */ - {';', 'E', '\312'}, {';', 'e', '\332'}, - {'\'', 'Z', '\254'}, {'\'', 'z', '\274'}, /* acute */ - {'\'', 'R', '\300'}, {'\'', 'r', '\340'}, - {'\'', 'L', '\305'}, {'\'', 'l', '\345'}, - {'\'', 'C', '\306'}, {'\'', 'c', '\346'}, - {'\'', 'N', '\321'}, {'\'', 'n', '\361'}, -/* collision whith S, from iso-8859-9 !!! */ - {',', 'S', '\252'}, {',', 's', '\272'}, /* cedilla */ - {',', 'T', '\336'}, {',', 't', '\376'}, - {'.', 'Z', '\257'}, {'.', 'z', '\277'}, /* dot above */ - {'/', 'L', '\243'}, {'/', 'l', '\263'}, /* slash */ - {'/', 'D', '\320'}, {'/', 'd', '\360'}, - {'(', 'A', '\303'}, {'(', 'a', '\343'}, /* breve */ - {'\275', 'O', '\325'}, {'\275', 'o', '\365'}, /* double acute */ - {'\275', 'U', '\334'}, {'\275', 'u', '\374'}, - {'0', 'U', '\332'}, {'0', 'u', '\372'}, /* ring above */ - /* iso-8859-3 uses this */ - {'/', 'H', '\241'}, {'/', 'h', '\261'}, /* slash */ - {'>', 'H', '\246'}, {'>', 'h', '\266'}, /* circumflex */ - {'>', 'J', '\254'}, {'>', 'j', '\274'}, - {'>', 'C', '\306'}, {'>', 'c', '\346'}, - {'>', 'G', '\330'}, {'>', 'g', '\370'}, - {'>', 'S', '\336'}, {'>', 's', '\376'}, -/* collision whith G( from iso-8859-9 !!! */ - {'(', 'G', '\253'}, {'(', 'g', '\273'}, /* breve */ - {'(', 'U', '\335'}, {'(', 'u', '\375'}, -/* collision whith I. from iso-8859-3 !!! */ - {'.', 'I', '\251'}, {'.', 'i', '\271'}, /* dot above */ - {'.', 'C', '\305'}, {'.', 'c', '\345'}, - {'.', 'G', '\325'}, {'.', 'g', '\365'}, - /* iso-8859-4 uses this */ - {',', 'R', '\243'}, {',', 'r', '\263'}, /* cedilla */ - {',', 'L', '\246'}, {',', 'l', '\266'}, - {',', 'G', '\253'}, {',', 'g', '\273'}, - {',', 'N', '\321'}, {',', 'n', '\361'}, - {',', 'K', '\323'}, {',', 'k', '\363'}, - {'~', 'I', '\245'}, {'~', 'i', '\265'}, /* tilde */ - {'-', 'E', '\252'}, {'-', 'e', '\272'}, /* macron */ - {'-', 'A', '\300'}, {'-', 'a', '\340'}, - {'-', 'I', '\317'}, {'-', 'i', '\357'}, - {'-', 'O', '\322'}, {'-', 'o', '\362'}, - {'-', 'U', '\336'}, {'-', 'u', '\376'}, - {'/', 'T', '\254'}, {'/', 't', '\274'}, /* slash */ - {'.', 'E', '\314'}, {'.', 'e', '\344'}, /* dot above */ - {';', 'I', '\307'}, {';', 'i', '\347'}, /* ogonek */ - {';', 'U', '\331'}, {';', 'u', '\371'}, - /* iso-8859-9 uses this */ - /* iso-8859-9 has really bad choosen G( S, and I. as they collide - * whith the same letters on other iso-8859-x (that is they are on - * different places :-( ), if you use turkish uncomment these and - * comment out the lines in iso-8859-2 and iso-8859-3 sections - * FIXME: should be dynamic according to chosen language - * if/when Wine has turkish support. - */ -/* collision whith G( from iso-8859-3 !!! */ -/* {'(', 'G', '\320'}, {'(', 'g', '\360'}, */ /* breve */ -/* collision whith S, from iso-8859-2 !!! */ -/* {',', 'S', '\336'}, {',', 's', '\376'}, */ /* cedilla */ -/* collision whith I. from iso-8859-3 !!! */ -/* {'.', 'I', '\335'}, {'.', 'i', '\375'}, */ /* dot above */ -}; - - /*********************************************************************** * TranslateMessage (USER32.@) * @@ -817,7 +699,6 @@ static const struct accent_char accent_chars[] = */ BOOL WINAPI TranslateMessage( const MSG *msg ) { - static int dead_char; UINT message; WCHAR wp[2]; BOOL rc = FALSE; @@ -843,35 +724,12 @@ BOOL WINAPI TranslateMessage( const MSG *msg ) { case 1: message = (msg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR; - /* Should dead chars handling go in ToAscii ? */ - if (dead_char) - { - int i; - - if (wp[0] == ' ') wp[0] = dead_char; - if (dead_char == 0xa2) dead_char = '('; - else if (dead_char == 0xa8) dead_char = '"'; - else if (dead_char == 0xb2) dead_char = ';'; - else if (dead_char == 0xb4) dead_char = '\''; - else if (dead_char == 0xb7) dead_char = '<'; - else if (dead_char == 0xb8) dead_char = ','; - else if (dead_char == 0xff) dead_char = '.'; - for (i = 0; i < sizeof(accent_chars)/sizeof(accent_chars[0]); i++) - if ((accent_chars[i].ac_accent == dead_char) && - (accent_chars[i].ac_char == wp[0])) - { - wp[0] = accent_chars[i].ac_result; - break; - } - dead_char = 0; - } TRACE_(key)("1 -> PostMessage(%s)\n", SPY_GetMsgName(message, msg->hwnd)); PostMessageW( msg->hwnd, message, wp[0], msg->lParam ); break; case -1: message = (msg->message == WM_KEYDOWN) ? WM_DEADCHAR : WM_SYSDEADCHAR; - dead_char = wp[0]; TRACE_(key)("-1 -> PostMessage(%s)\n", SPY_GetMsgName(message, msg->hwnd)); PostMessageW( msg->hwnd, message, wp[0], msg->lParam ); return TRUE;