📄 gdkkeyboard-fb.c
字号:
/* GDK - The GIMP Drawing Kit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * 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. */#include <config.h>#include <gdk/gdk.h>#include <gdk/gdkinternals.h>#include "gdkkeysyms.h"#include "gdkprivate-fb.h"#include <errno.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <ctype.h>#include <termios.h>#include <sys/ioctl.h>#include <sys/kd.h>#include <sys/vt.h>typedef struct _GdkFBKeyboard GdkFBKeyboard;typedef struct _GdkFBKeyboardDevice GdkFBKeyboardDevice;struct _GdkFBKeyboard { gint fd; GIOChannel *io; gint io_tag; guint modifier_state; guint caps_lock : 1; gint group; gint level; GdkFBKeyboardDevice *dev;};struct _GdkFBKeyboardDevice { char *name; gboolean (*open)(GdkFBKeyboard *kb); void (*close)(GdkFBKeyboard *kb); guint (*lookup_key) (GdkFBKeyboard *kb, const GdkKeymapKey *key); gboolean (*translate_keyboard_state) (GdkFBKeyboard *kb, guint hardware_keycode, GdkModifierType state, gint group, guint *keyval, gint *effective_group, gint *level, GdkModifierType *consumed_modifiers); gboolean (*get_entries_for_keyval) (GdkFBKeyboard *kb, guint keyval, GdkKeymapKey **keys, gint *n_keys); gboolean (*get_entries_for_keycode) (GdkFBKeyboard *kb, guint hardware_keycode, GdkKeymapKey **keys, guint **keyvals, gint *n_entries); gpointer driver_data;};static GdkFBKeyboard *gdk_fb_keyboard = NULL;static GdkKeymap *default_keymap = NULL;static gboolean xlate_open (GdkFBKeyboard *kb);static void xlate_close (GdkFBKeyboard *kb);static guint xlate_lookup (GdkFBKeyboard *kb, const GdkKeymapKey *key);static gboolean xlate_translate (GdkFBKeyboard *kb, guint hardware_keycode, GdkModifierType state, gint group, guint *keyval, gint *effective_group, gint *level, GdkModifierType *consumed_modifiers);static gboolean xlate_get_for_keyval (GdkFBKeyboard *kb, guint keyval, GdkKeymapKey **keys, gint *n_keys);static gboolean xlate_get_for_keycode (GdkFBKeyboard *kb, guint hardware_keycode, GdkKeymapKey **keys, guint **keyvals, gint *n_entries);static gboolean raw_open (GdkFBKeyboard *kb);static void raw_close (GdkFBKeyboard *kb);static guint raw_lookup (GdkFBKeyboard *kb, const GdkKeymapKey *key);static gboolean raw_translate (GdkFBKeyboard *kb, guint hardware_keycode, GdkModifierType state, gint group, guint *keyval, gint *effective_group, gint *level, GdkModifierType *consumed_modifiers);static gboolean raw_get_for_keyval (GdkFBKeyboard *kb, guint keyval, GdkKeymapKey **keys, gint *n_keys);static gboolean raw_get_for_keycode (GdkFBKeyboard *kb, guint hardware_keycode, GdkKeymapKey **keys, guint **keyvals, gint *n_entries);static GdkFBKeyboardDevice keyb_devs[] ={ { "xlate", xlate_open, xlate_close, xlate_lookup, xlate_translate, xlate_get_for_keyval, xlate_get_for_keycode }, { "raw", raw_open, raw_close, raw_lookup, raw_translate, raw_get_for_keyval, raw_get_for_keycode },};GdkKeymap*gdk_keymap_get_default_for_display (GdkDisplay *display){ if (default_keymap == NULL) default_keymap = g_object_new (gdk_keymap_get_type (), NULL); return default_keymap;}GdkKeymap*gdk_keymap_get_for_display (GdkDisplay *display){ return gdk_keymap_get_default_for_display (display);}PangoDirectiongdk_keymap_get_direction (GdkKeymap *keymap){ /* FIXME: Only supports LTR keymaps at the moment */ return PANGO_DIRECTION_LTR;}guintgdk_fb_keyboard_modifiers (void){ return gdk_fb_keyboard->modifier_state;}gbooleangdk_fb_keyboard_init (gboolean open_dev){ GdkFBKeyboard *keyb; char *keyb_type; int i; gdk_fb_keyboard = g_new0 (GdkFBKeyboard, 1); keyb = gdk_fb_keyboard; keyb->fd = -1; keyb_type = getenv ("GDK_KEYBOARD_TYPE"); if (!keyb_type) keyb_type = "xlate"; for (i = 0; i < G_N_ELEMENTS(keyb_devs); i++) { if (g_ascii_strcasecmp(keyb_type, keyb_devs[i].name)==0) break; } if (i == G_N_ELEMENTS(keyb_devs)) { g_warning ("No keyboard driver of type %s found", keyb_type); return FALSE; } keyb->dev = &keyb_devs[i]; if (open_dev) return gdk_fb_keyboard_open (); else return TRUE;}gbooleangdk_fb_keyboard_open (void){ GdkFBKeyboard *keyb; GdkFBKeyboardDevice *device; keyb = gdk_fb_keyboard; device = keyb->dev; if (!device->open(keyb)) { g_warning ("Keyboard driver open failed"); return FALSE; } return TRUE;}void gdk_fb_keyboard_close (void){ gdk_fb_keyboard->dev->close(gdk_fb_keyboard);}gbooleangdk_keymap_get_entries_for_keyval (GdkKeymap *keymap, guint keyval, GdkKeymapKey **keys, gint *n_keys){ g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE); g_return_val_if_fail (keys != NULL, FALSE); g_return_val_if_fail (n_keys != NULL, FALSE); g_return_val_if_fail (keyval != 0, FALSE); return gdk_fb_keyboard->dev->get_entries_for_keyval (gdk_fb_keyboard, keyval, keys, n_keys);}gbooleangdk_keymap_get_entries_for_keycode (GdkKeymap *keymap, guint hardware_keycode, GdkKeymapKey **keys, guint **keyvals, gint *n_entries){ g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE); g_return_val_if_fail (n_entries != NULL, FALSE); return gdk_fb_keyboard->dev->get_entries_for_keycode (gdk_fb_keyboard, hardware_keycode, keys, keyvals, n_entries);}guintgdk_keymap_lookup_key (GdkKeymap *keymap, const GdkKeymapKey *key){ g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), 0); g_return_val_if_fail (key != NULL, 0); g_return_val_if_fail (key->group < 4, 0); return gdk_fb_keyboard->dev->lookup_key (gdk_fb_keyboard, key);}gbooleangdk_keymap_translate_keyboard_state (GdkKeymap *keymap, guint hardware_keycode, GdkModifierType state, gint group, guint *keyval, gint *effective_group, gint *level, GdkModifierType *consumed_modifiers){ g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE); g_return_val_if_fail (group < 4, FALSE); return gdk_fb_keyboard->dev->translate_keyboard_state (gdk_fb_keyboard, hardware_keycode, state, group, keyval, effective_group, level, consumed_modifiers);}static voidgdk_fb_handle_key (guint hw_keycode, guint keyval, guint modifier_state, guint8 group, gchar *string, gint string_length, gboolean key_up){ GdkWindow *win; GdkEvent *event; /* handle some magic keys */ if (key_up && (modifier_state & GDK_CONTROL_MASK) && (modifier_state & GDK_MOD1_MASK)) { if (keyval == GDK_BackSpace) { ioctl (gdk_display->tty_fd, KDSKBMODE, K_XLATE); exit (1); } if (keyval == GDK_Return) gdk_fb_redraw_all (); } win = gdk_fb_keyboard_event_window (gdk_fb_window_find_focus (), key_up ? GDK_KEY_RELEASE : GDK_KEY_PRESS); if (win) { event = gdk_event_make (win, key_up ? GDK_KEY_RELEASE : GDK_KEY_PRESS, TRUE); event->key.state = modifier_state; event->key.keyval = keyval; event->key.string = string; event->key.length = string_length; event->key.hardware_keycode = hw_keycode; event->key.group = group; } else g_free (string);}/****************************************************** ********* Device specific keyboard code ************** ******************************************************//* XLATE keyboard driver */struct { char *str; guint code; guint modifier;} xlate_codes[] ={ {"\x5b\x41", GDK_F1}, {"\x5b\x42", GDK_F2}, {"\x5b\x43", GDK_F3}, {"\x5b\x44", GDK_F4}, {"\x5b\x45", GDK_F5}, {"\x31\x37\x7e", GDK_F6}, {"\x31\x38\x7e", GDK_F7}, {"\x31\x39\x7e", GDK_F8}, {"\x32\x30\x7e", GDK_F9}, {"\x32\x31\x7e", GDK_F10}, {"\x32\x33\x7e", GDK_F11}, {"\x32\x34\x7e", GDK_F12}, {"\x32\x35\x7e", GDK_F1, GDK_SHIFT_MASK}, {"\x32\x36\x7e", GDK_F2, GDK_SHIFT_MASK}, {"\x32\x38\x7e", GDK_F3, GDK_SHIFT_MASK}, {"\x32\x39\x7e", GDK_F4, GDK_SHIFT_MASK}, {"\x33\x31\x7e", GDK_F5, GDK_SHIFT_MASK}, {"\x33\x32\x7e", GDK_F6, GDK_SHIFT_MASK}, {"\x33\x33\x7e", GDK_F7, GDK_SHIFT_MASK}, {"\x33\x34\x7e", GDK_F8, GDK_SHIFT_MASK}, {"\x31\x7e", GDK_Home}, {"\x35\x7e", GDK_Page_Up}, {"\x34\x7e", GDK_End}, {"\x36\x7e", GDK_Page_Down}, {"\x32\x7e", GDK_Insert}, {"\x33\x7e", GDK_Delete}, {"\x41", GDK_Up}, {"\x44", GDK_Left}, {"\x42", GDK_Down}, {"\x43", GDK_Right}, {"\x50", GDK_Break},};struct { guint code; guint modifier;} xlate_chars[] ={ /* 0x00 */ {'@', GDK_CONTROL_MASK}, {'a', GDK_CONTROL_MASK}, {'b', GDK_CONTROL_MASK}, {'c', GDK_CONTROL_MASK}, {'d', GDK_CONTROL_MASK}, {'e', GDK_CONTROL_MASK}, {'f', GDK_CONTROL_MASK}, {'g', GDK_CONTROL_MASK}, {'h', GDK_CONTROL_MASK}, {GDK_Tab, 0}, {'j', GDK_CONTROL_MASK}, {'k', GDK_CONTROL_MASK}, {'l', GDK_CONTROL_MASK}, {GDK_Return, 0}, {'n', GDK_CONTROL_MASK}, {'o', GDK_CONTROL_MASK}, /* 0x10 */ {'p', GDK_CONTROL_MASK}, {'q', GDK_CONTROL_MASK}, {'r', GDK_CONTROL_MASK}, {'s', GDK_CONTROL_MASK}, {'t', GDK_CONTROL_MASK}, {'u', GDK_CONTROL_MASK}, {'v', GDK_CONTROL_MASK}, {'w', GDK_CONTROL_MASK}, {'x', GDK_CONTROL_MASK}, {'y', GDK_CONTROL_MASK}, {'z', GDK_CONTROL_MASK}, {GDK_Escape, 0}, {'\\', GDK_CONTROL_MASK}, {']', GDK_CONTROL_MASK}, {'^', GDK_CONTROL_MASK}, {'_', GDK_CONTROL_MASK}, /* 0x20 */ {GDK_space, 0}, {'!', 0}, {'"', 0}, {'#', 0}, {'$', 0}, {'%', 0}, {'&', 0}, {'\'', 0}, {'(', 0}, {')', 0}, {'*', 0}, {'+', 0}, {',', 0}, {'-', 0}, {'.', 0}, {'/', 0}, /* 0x30 */ {'0', 0}, {'1', 0}, {'2', 0}, {'3', 0}, {'4', 0}, {'5', 0}, {'6', 0}, {'7', 0}, {'8', 0}, {'9', 0}, {':', 0}, {';', 0}, {'<', 0}, {'=', 0}, {'>', 0}, {'?', 0}, /* 0x40 */ {'@', 0}, {'A', 0}, {'B', 0}, {'C', 0}, {'D', 0}, {'E', 0}, {'F', 0}, {'G', 0}, {'H', 0}, {'I', 0}, {'J', 0}, {'K', 0}, {'L', 0}, {'M', 0}, {'N', 0}, {'O', 0}, /* 0x50 */ {'P', 0}, {'Q', 0}, {'R', 0}, {'S', 0}, {'T', 0}, {'U', 0}, {'V', 0}, {'W', 0}, {'X', 0}, {'Y', 0}, {'Z', 0}, {'[', 0}, {'\\', 0}, {']', 0}, {'^', 0}, {'_', 0}, /* 0x60 */ {'`', 0}, {'a', 0}, {'b', 0}, {'c', 0}, {'d', 0}, {'e', 0}, {'f', 0}, {'g', 0}, {'h', 0}, {'i', 0}, {'j', 0}, {'k', 0}, {'l', 0}, {'m', 0}, {'n', 0}, {'o', 0}, /* 0x70 */ {'p', 0}, {'q', 0}, {'r', 0}, {'s', 0}, {'t', 0}, {'u', 0}, {'v', 0},
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -