?? gdkkeys-win32.c
字號:
/* GDK - The GIMP Drawing Kit * Copyright (C) 2000 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//* * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS * file for a list of people on the GTK+ Team. See the ChangeLog * files for a list of changes. These files are distributed with * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */#include <ctype.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <limits.h>#include <errno.h>#include "gdk.h"#include "gdkprivate-win32.h"#include "gdkinternals.h"#include "gdkkeysyms.h"#include <config.h>guint _gdk_keymap_serial = 0;gboolean _gdk_keyboard_has_altgr = FALSE;guint _scancode_rshift = 0;static GdkModifierType gdk_shift_modifiers = GDK_SHIFT_MASK;static GdkKeymap *default_keymap = NULL;static guint *keysym_tab = NULL;typedef int (WINAPI *t_ToUnicodeEx) (UINT,UINT,PBYTE,LPWSTR,int,UINT,HKL);static t_ToUnicodeEx p_ToUnicodeEx = NULL;#ifdef G_ENABLE_DEBUGstatic voidprint_keysym_tab (void){ gint vk; g_print ("keymap:%s%s\n", _gdk_keyboard_has_altgr ? " (uses AltGr)" : "", (gdk_shift_modifiers & GDK_LOCK_MASK) ? " (has ShiftLock)" : ""); for (vk = 0; vk < 256; vk++) { gint state; g_print ("%#.02x: ", vk); for (state = 0; state < 4; state++) { gchar *name = gdk_keyval_name (keysym_tab[vk*4 + state]); if (name == NULL) name = "(none)"; g_print ("%s ", name); } g_print ("\n"); }}#endifstatic voidhandle_special (guint vk, guint *ksymp, gint shift){ switch (vk) { case VK_CANCEL: *ksymp = GDK_Cancel; break; case VK_BACK: *ksymp = GDK_BackSpace; break; case VK_TAB: if (shift & 0x1) *ksymp = GDK_ISO_Left_Tab; else *ksymp = GDK_Tab; break; case VK_CLEAR: *ksymp = GDK_Clear; break; case VK_RETURN: *ksymp = GDK_Return; break; case VK_SHIFT: case VK_LSHIFT: *ksymp = GDK_Shift_L; break; case VK_CONTROL: case VK_LCONTROL: *ksymp = GDK_Control_L; break; case VK_MENU: case VK_LMENU: *ksymp = GDK_Alt_L; break; case VK_PAUSE: *ksymp = GDK_Pause; break; case VK_ESCAPE: *ksymp = GDK_Escape; break; case VK_PRIOR: *ksymp = GDK_Prior; break; case VK_NEXT: *ksymp = GDK_Next; break; case VK_END: *ksymp = GDK_End; break; case VK_HOME: *ksymp = GDK_Home; break; case VK_LEFT: *ksymp = GDK_Left; break; case VK_UP: *ksymp = GDK_Up; break; case VK_RIGHT: *ksymp = GDK_Right; break; case VK_DOWN: *ksymp = GDK_Down; break; case VK_SELECT: *ksymp = GDK_Select; break; case VK_PRINT: *ksymp = GDK_Print; break; case VK_EXECUTE: *ksymp = GDK_Execute; break; case VK_INSERT: *ksymp = GDK_Insert; break; case VK_DELETE: *ksymp = GDK_Delete; break; case VK_HELP: *ksymp = GDK_Help; break; case VK_LWIN: *ksymp = GDK_Meta_L; break; case VK_RWIN: *ksymp = GDK_Meta_R; break; case VK_APPS: *ksymp = GDK_Menu; break; case VK_MULTIPLY: *ksymp = GDK_KP_Multiply; break; case VK_ADD: *ksymp = GDK_KP_Add; break; case VK_SEPARATOR: *ksymp = GDK_KP_Separator; break; case VK_SUBTRACT: *ksymp = GDK_KP_Subtract; break; case VK_DIVIDE: *ksymp = GDK_KP_Divide; break; case VK_F1: *ksymp = GDK_F1; break; case VK_F2: *ksymp = GDK_F2; break; case VK_F3: *ksymp = GDK_F3; break; case VK_F4: *ksymp = GDK_F4; break; case VK_F5: *ksymp = GDK_F5; break; case VK_F6: *ksymp = GDK_F6; break; case VK_F7: *ksymp = GDK_F7; break; case VK_F8: *ksymp = GDK_F8; break; case VK_F9: *ksymp = GDK_F9; break; case VK_F10: *ksymp = GDK_F10; break; case VK_F11: *ksymp = GDK_F11; break; case VK_F12: *ksymp = GDK_F12; break; case VK_F13: *ksymp = GDK_F13; break; case VK_F14: *ksymp = GDK_F14; break; case VK_F15: *ksymp = GDK_F15; break; case VK_F16: *ksymp = GDK_F16; break; case VK_F17: *ksymp = GDK_F17; break; case VK_F18: *ksymp = GDK_F18; break; case VK_F19: *ksymp = GDK_F19; break; case VK_F20: *ksymp = GDK_F20; break; case VK_F21: *ksymp = GDK_F21; break; case VK_F22: *ksymp = GDK_F22; break; case VK_F23: *ksymp = GDK_F23; break; case VK_F24: *ksymp = GDK_F24; break; case VK_NUMLOCK: *ksymp = GDK_Num_Lock; break; case VK_SCROLL: *ksymp = GDK_Scroll_Lock; break; case VK_RSHIFT: *ksymp = GDK_Shift_R; break; case VK_RCONTROL: *ksymp = GDK_Control_R; break; case VK_RMENU: *ksymp = GDK_Alt_R; break; }}static voidset_shift_vks (guchar *key_state, gint shift){ switch (shift) { case 0: key_state[VK_SHIFT] = 0; key_state[VK_CONTROL] = key_state[VK_MENU] = 0; break; case 1: key_state[VK_SHIFT] = 0x80; key_state[VK_CONTROL] = key_state[VK_MENU] = 0; break; case 2: key_state[VK_SHIFT] = 0; key_state[VK_CONTROL] = key_state[VK_MENU] = 0x80; break; case 3: key_state[VK_SHIFT] = 0x80; key_state[VK_CONTROL] = key_state[VK_MENU] = 0x80; break; }}static voidreset_after_dead (guchar key_state[256]){ guchar temp_key_state[256]; memmove (temp_key_state, key_state, sizeof (key_state)); temp_key_state[VK_SHIFT] = temp_key_state[VK_CONTROL] = temp_key_state[VK_MENU] = 0; if (G_WIN32_HAVE_WIDECHAR_API ()) { wchar_t wcs[2]; (*p_ToUnicodeEx) (VK_SPACE, MapVirtualKey (VK_SPACE, 0), temp_key_state, wcs, G_N_ELEMENTS (wcs), 0, _gdk_input_locale); } else { char chars[2]; ToAsciiEx (VK_SPACE, MapVirtualKey (VK_SPACE, 0), temp_key_state, (LPWORD) chars, 0, _gdk_input_locale); }}static voidhandle_dead (guint keysym, guint *ksymp){ switch (keysym) { case '"': /* 0x022 */ *ksymp = GDK_dead_diaeresis; break; case '\'': /* 0x027 */ *ksymp = GDK_dead_acute; break; case GDK_asciicircum: /* 0x05e */ *ksymp = GDK_dead_circumflex; break; case GDK_grave: /* 0x060 */ *ksymp = GDK_dead_grave; break; case GDK_asciitilde: /* 0x07e */ *ksymp = GDK_dead_tilde; break; case GDK_diaeresis: /* 0x0a8 */ *ksymp = GDK_dead_diaeresis; break; case GDK_degree: /* 0x0b0 */ *ksymp = GDK_dead_abovering; break; case GDK_acute: /* 0x0b4 */ *ksymp = GDK_dead_acute; break; case GDK_periodcentered: /* 0x0b7 */ *ksymp = GDK_dead_abovedot; break; case GDK_cedilla: /* 0x0b8 */ *ksymp = GDK_dead_cedilla; break; case GDK_breve: /* 0x1a2 */ *ksymp = GDK_dead_breve; break; case GDK_ogonek: /* 0x1b2 */ *ksymp = GDK_dead_ogonek; break; case GDK_caron: /* 0x1b7 */ *ksymp = GDK_dead_caron; break; case GDK_doubleacute: /* 0x1bd */ *ksymp = GDK_dead_doubleacute; break; case GDK_abovedot: /* 0x1ff */ *ksymp = GDK_dead_abovedot; break; case 0x1000384: /* Greek tonos */ *ksymp = GDK_dead_acute; break; case GDK_Greek_accentdieresis: /* 0x7ae */ *ksymp = GDK_Greek_accentdieresis; break; default: /* By default use the keysym as such. This takes care of for * instance the dead U+09CD (BENGALI VIRAMA) on the ekushey * Bengali layout. */ *ksymp = keysym; break; }}static voidupdate_keymap (void){ static guint current_serial = 0; guchar key_state[256]; guint scancode; guint vk; gboolean capslock_tested = FALSE; static HMODULE user32 = NULL; if (keysym_tab != NULL && current_serial == _gdk_keymap_serial) return; g_assert (G_WIN32_HAVE_WIDECHAR_API () || _gdk_input_codepage != 0); if (G_WIN32_HAVE_WIDECHAR_API () && user32 == NULL) { user32 = GetModuleHandle ("user32.dll"); g_assert (user32 != NULL); p_ToUnicodeEx = (t_ToUnicodeEx) GetProcAddress (user32, "ToUnicodeEx"); } current_serial = _gdk_keymap_serial; if (keysym_tab == NULL) keysym_tab = g_new (guint, 4*256); memset (key_state, 0, sizeof (key_state)); _gdk_keyboard_has_altgr = FALSE; gdk_shift_modifiers = GDK_SHIFT_MASK; for (vk = 0; vk < 256; vk++) { if ((scancode = MapVirtualKey (vk, 0)) == 0 && vk != VK_DIVIDE) keysym_tab[vk*4+0] = keysym_tab[vk*4+1] = keysym_tab[vk*4+2] = keysym_tab[vk*4+3] = GDK_VoidSymbol; else { gint shift; if (vk == VK_RSHIFT) _scancode_rshift = scancode; key_state[vk] = 0x80; for (shift = 0; shift < 4; shift++) { guint *ksymp = keysym_tab + vk*4 + shift; guchar chars[2]; set_shift_vks (key_state, shift); *ksymp = 0; /* First, handle those virtual keys that we always want * as special GDK_* keysyms, even if ToAsciiEx might * turn some them into a ASCII character (like TAB and * ESC). */ handle_special (vk, ksymp, shift); if (*ksymp == 0) { wchar_t wcs[10]; gint k; if (G_WIN32_HAVE_WIDECHAR_API ()) { k = (*p_ToUnicodeEx) (vk, scancode, key_state, wcs, G_N_ELEMENTS (wcs), 0, _gdk_input_locale);#if 0 g_print ("ToUnicodeEx(%02x, %d: %d): %d, %04x %04x\n", vk, scancode, shift, k, (k != 0 ? wcs[0] : 0), (k >= 2 ? wcs[1] : 0));#endif if (k == 1) *ksymp = gdk_unicode_to_keyval (wcs[0]); } else { k = ToAsciiEx (vk, scancode, key_state, (LPWORD) chars, 0, _gdk_input_locale);#if 0 g_print ("ToAsciiEx(%02x, %d: %d): %d, %02x %02x\n", vk, scancode, shift, k, (k != 0 ? chars[0] : 0), (k == 2 ? chars[1] : 0));#endif if (k == 1) { if (_gdk_input_codepage >= 1250 && _gdk_input_codepage <= 1258 && chars[0] >= GDK_space && chars[0] <= GDK_asciitilde) *ksymp = chars[0]; else { if (MultiByteToWideChar (_gdk_input_codepage, 0, chars, 1, wcs, 1) > 0) *ksymp = gdk_unicode_to_keyval (wcs[0]); } } else if (k == -1) { MultiByteToWideChar (_gdk_input_codepage, 0, chars, 1, wcs, 1); } } if (k == 1) { /* Keysym already stored above */ } else if (k == -1) { guint keysym = gdk_unicode_to_keyval (wcs[0]); /* It is a dead key, and it's has been stored in * the keyboard layout's state by * ToAsciiEx()/ToUnicodeEx(). Yes, this is an * incredibly silly API! Make the keyboard * layout forget it by calling * ToAsciiEx()/ToUnicodeEx() once more, with the * virtual key code and scancode for the * spacebar, without shift or AltGr. Otherwise
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -