⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gdkkeys-x11.c

📁 linux下电话本所依赖的一些图形库
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 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 <config.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <limits.h>#include <errno.h>#include "gdk.h"#include "gdkx.h"#include "gdkprivate-x11.h"#include "gdkinternals.h"#include "gdkdisplay-x11.h"#include "gdkkeysyms.h"#include "gdkalias.h"#ifdef HAVE_XKB#include <X11/XKBlib.h>/* OSF-4.0 is apparently missing this macro */#  ifndef XkbKeySymEntry#    define XkbKeySymEntry(d,k,sl,g) \ 	(XkbKeySym(d,k,((XkbKeyGroupsWidth(d,k)*(g))+(sl))))#  endif#endif /* HAVE_XKB */typedef struct _GdkKeymapX11 GdkKeymapX11;#define GDK_TYPE_KEYMAP_X11          (gdk_keymap_x11_get_type ())#define GDK_KEYMAP_X11(object)       (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_KEYMAP_X11, GdkKeymapX11))#define GDK_IS_KEYMAP_X11(object)    (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_KEYMAP_X11))typedef struct _DirectionCacheEntry DirectionCacheEntry;struct _DirectionCacheEntry{  guint serial;  Atom group_atom;  PangoDirection direction;};struct _GdkKeymapX11{  GdkKeymap     parent_instance;  gint min_keycode;  gint max_keycode;  KeySym* keymap;  gint keysyms_per_keycode;  XModifierKeymap* mod_keymap;  guint lock_keysym;  GdkModifierType group_switch_mask;  GdkModifierType num_lock_mask;  gboolean sun_keypad;  PangoDirection current_direction;  gboolean have_direction;  guint current_serial;#ifdef HAVE_XKB  XkbDescPtr xkb_desc;  /* We cache the directions */  Atom current_group_atom;  guint current_cache_serial;  /* A cache of size four should be more than enough, people usually   * have two groups around, and the xkb limit is four.  It still   * works correct for more than four groups.  It's just the   * cache.   */  DirectionCacheEntry group_direction_cache[4];#endif};#define KEYMAP_USE_XKB(keymap) GDK_DISPLAY_X11 ((keymap)->display)->use_xkb#define KEYMAP_XDISPLAY(keymap) GDK_DISPLAY_XDISPLAY ((keymap)->display)static GType gdk_keymap_x11_get_type (void);static void  gdk_keymap_x11_init     (GdkKeymapX11 *keymap);static GTypegdk_keymap_x11_get_type (void){  static GType object_type = 0;  if (!object_type)    {      static const GTypeInfo object_info =	{	  sizeof (GdkKeymapClass),	  (GBaseInitFunc) NULL,	  (GBaseFinalizeFunc) NULL,	  (GClassInitFunc) NULL,	  NULL,           /* class_finalize */	  NULL,           /* class_data */	  sizeof (GdkKeymapX11),	  0,              /* n_preallocs */	  (GInstanceInitFunc) gdk_keymap_x11_init,	};            object_type = g_type_register_static (GDK_TYPE_KEYMAP,                                            "GdkKeymapX11",                                            &object_info, 0);    }    return object_type;}static voidgdk_keymap_x11_init (GdkKeymapX11 *keymap){  keymap->min_keycode = 0;  keymap->max_keycode = 0;  keymap->keymap = NULL;  keymap->keysyms_per_keycode = 0;  keymap->mod_keymap = NULL;    keymap->num_lock_mask = 0;  keymap->sun_keypad = FALSE;  keymap->group_switch_mask = 0;  keymap->lock_keysym = GDK_Caps_Lock;  keymap->have_direction = FALSE;  keymap->current_serial = 0;#ifdef HAVE_XKB  keymap->xkb_desc = NULL;  keymap->current_group_atom = 0;  keymap->current_cache_serial = 0;#endif}static inline voidupdate_keyrange (GdkKeymapX11 *keymap_x11){  if (keymap_x11->max_keycode == 0)    XDisplayKeycodes (KEYMAP_XDISPLAY (GDK_KEYMAP (keymap_x11)),		      &keymap_x11->min_keycode, &keymap_x11->max_keycode);}#ifdef HAVE_XKBstatic XkbDescPtrget_xkb (GdkKeymapX11 *keymap_x11){  GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_KEYMAP (keymap_x11)->display);  Display *xdisplay = display_x11->xdisplay;    update_keyrange (keymap_x11);    if (keymap_x11->xkb_desc == NULL)    {      keymap_x11->xkb_desc = XkbGetMap (xdisplay, XkbKeySymsMask | XkbKeyTypesMask, XkbUseCoreKbd);      if (keymap_x11->xkb_desc == NULL)	g_error ("Failed to get keymap");      XkbGetNames (xdisplay, XkbGroupNamesMask, keymap_x11->xkb_desc);    }  else if (keymap_x11->current_serial != display_x11->keymap_serial)    {      XkbGetUpdatedMap (xdisplay, XkbKeySymsMask | XkbKeyTypesMask,			keymap_x11->xkb_desc);      XkbGetNames (xdisplay, XkbGroupNamesMask, keymap_x11->xkb_desc);    }  keymap_x11->current_serial = display_x11->keymap_serial;  return keymap_x11->xkb_desc;}#endif /* HAVE_XKB *//* Whether we were able to turn on detectable-autorepeat using * XkbSetDetectableAutorepeat. If FALSE, we'll fall back * to checking the next event with XPending(). *//**  * gdk_keymap_get_for_display: * @display: the #GdkDisplay. * @returns: the #GdkKeymap attached to @display. * * Returns the #GdkKeymap attached to @display. * * Since: 2.2 **/GdkKeymap*gdk_keymap_get_for_display (GdkDisplay *display){  GdkDisplayX11 *display_x11;  g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);  display_x11 = GDK_DISPLAY_X11 (display);    if (!display_x11->keymap)    display_x11->keymap = g_object_new (gdk_keymap_x11_get_type (), NULL);  display_x11->keymap->display = display;  return display_x11->keymap;}/* Find the index of the group/level pair within the keysyms for a key. * We round up the number of keysyms per keycode to the next even number, * otherwise we lose a whole group of keys */#define KEYSYM_INDEX(keymap_impl, group, level) \  (2 * ((group) % (gint)((keymap_impl->keysyms_per_keycode + 1) / 2)) + (level))#define KEYSYM_IS_KEYPAD(s) (((s) >= 0xff80 && (s) <= 0xffbd) || \                             ((s) >= 0x11000000 && (s) <= 0x1100ffff))static gintget_symbol (const KeySym *syms,	    GdkKeymapX11 *keymap_x11,	    gint group,	    gint level){  gint index;  index = KEYSYM_INDEX(keymap_x11, group, level);  if (index > keymap_x11->keysyms_per_keycode)      return NoSymbol;  return syms[index];}static voidupdate_keymaps (GdkKeymapX11 *keymap_x11){  GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_KEYMAP (keymap_x11)->display);  Display *xdisplay = display_x11->xdisplay;  #ifdef HAVE_XKB  g_assert (!KEYMAP_USE_XKB (GDK_KEYMAP (keymap_x11)));#endif    if (keymap_x11->keymap == NULL ||      keymap_x11->current_serial != display_x11->keymap_serial)    {      gint i;      gint map_size;      gint keycode;      keymap_x11->current_serial = display_x11->keymap_serial;            update_keyrange (keymap_x11);            if (keymap_x11->keymap)        XFree (keymap_x11->keymap);      if (keymap_x11->mod_keymap)        XFreeModifiermap (keymap_x11->mod_keymap);            keymap_x11->keymap = XGetKeyboardMapping (xdisplay, keymap_x11->min_keycode,						keymap_x11->max_keycode - keymap_x11->min_keycode + 1,						&keymap_x11->keysyms_per_keycode);      /* GDK_ISO_Left_Tab, as usually configured through XKB, really messes       * up the whole idea of "consumed modifiers" because shift is consumed.       * However, <shift>Tab is not usually GDK_ISO_Left_Tab without XKB,       * we we fudge the map here.       */      keycode = keymap_x11->min_keycode;      while (keycode <= keymap_x11->max_keycode)        {          KeySym *syms = keymap_x11->keymap + (keycode - keymap_x11->min_keycode) * keymap_x11->keysyms_per_keycode;	  /* Check both groups */	  for (i = 0 ; i < 2 ; i++)	    {	      if (get_symbol (syms, keymap_x11, i, 0) == GDK_Tab)		syms[KEYSYM_INDEX (keymap_x11, i, 1)] = GDK_ISO_Left_Tab;	    }          /*           * If there is one keysym and the key symbol has upper and lower           * case variants fudge the keymap           */          if (get_symbol (syms, keymap_x11, 0, 1) == 0)            {              guint lower;              guint upper;              gdk_keyval_convert_case (get_symbol (syms, keymap_x11, 0, 0), &lower, &upper);              if (lower != upper)                {                  syms[KEYSYM_INDEX (keymap_x11, 0, 0)] = lower;                  syms[KEYSYM_INDEX (keymap_x11, 0, 1)] = upper;                }            }                          ++keycode;        }      keymap_x11->mod_keymap = XGetModifierMapping (xdisplay);      keymap_x11->lock_keysym = GDK_VoidSymbol;      keymap_x11->group_switch_mask = 0;      keymap_x11->num_lock_mask = 0;      /* There are 8 sets of modifiers, with each set containing       * max_keypermod keycodes.       */      map_size = 8 * keymap_x11->mod_keymap->max_keypermod;      for (i = 0; i < map_size; i++)        {          /* Get the key code at this point in the map. */          gint keycode = keymap_x11->mod_keymap->modifiermap[i];          gint j;          KeySym *syms;	  guint mask;          /* Ignore invalid keycodes. */          if (keycode < keymap_x11->min_keycode ||              keycode > keymap_x11->max_keycode)            continue;          syms = keymap_x11->keymap + (keycode - keymap_x11->min_keycode) * keymap_x11->keysyms_per_keycode;          /* The fourth modifier, GDK_MOD1_MASK is 1 << 3.	   * Each group of max_keypermod entries refers to the same modifier.           */          mask = 1 << (i / keymap_x11->mod_keymap->max_keypermod);          switch (mask)            {            case GDK_LOCK_MASK:              /* Get the Lock keysym.  If any keysym bound to the Lock modifier               * is Caps_Lock, we will interpret the modifier as Caps_Lock;               * otherwise, if any is bound to Shift_Lock, we will interpret               * the modifier as Shift_Lock. Otherwise, the lock modifier	       * has no effect.               */	      for (j = 0; j < keymap_x11->keysyms_per_keycode; j++)		{		  if (syms[j] == GDK_Caps_Lock)		    keymap_x11->lock_keysym = GDK_Caps_Lock;		  else if (syms[j] == GDK_Shift_Lock &&			   keymap_x11->lock_keysym == GDK_VoidSymbol)		    keymap_x11->lock_keysym = GDK_Shift_Lock;		}              break;            case GDK_CONTROL_MASK:            case GDK_SHIFT_MASK:            case GDK_MOD1_MASK:              /* Some keyboard maps are known to map Mode_Switch as an               * extra Mod1 key. In circumstances like that, it won't be               * used to switch groups.               */              break;            default:              /* Find the Mode_Switch and Num_Lock modifiers. */              for (j = 0; j < keymap_x11->keysyms_per_keycode; j++)                {                  if (syms[j] == GDK_Mode_switch)                    {                      /* This modifier swaps groups */                      keymap_x11->group_switch_mask |= mask;                    }                  else if (syms[j] == GDK_Num_Lock)                    {                      /* This modifier is used for Num_Lock */                      keymap_x11->num_lock_mask |= mask;                    }                }              break;            }        }      /* Hack: The Sun X server puts the keysym to use when the Num Lock       * modifier is on in the third element of the keysym array, instead       * of the second.       */      if ((strcmp (ServerVendor (xdisplay), "Sun Microsystems, Inc.") == 0) &&          (keymap_x11->keysyms_per_keycode > 2))        keymap_x11->sun_keypad = TRUE;      else        keymap_x11->sun_keypad = FALSE;    }}static const KeySym*get_keymap (GdkKeymapX11 *keymap_x11){  update_keymaps (keymap_x11);    return keymap_x11->keymap;}#define GET_EFFECTIVE_KEYMAP(keymap) get_effective_keymap ((keymap), G_STRFUNC)static GdkKeymap *get_effective_keymap (GdkKeymap  *keymap,		      const char *function){  if (!keymap)    {      GDK_NOTE (MULTIHEAD,		g_message ("reverting to default display keymap in %s",			   function));      return gdk_keymap_get_default ();    }  return keymap;}#if HAVE_XKBstatic PangoDirectionget_direction (XkbDescRec *xkb, 	       gint group){  gint code;  gint rtl_minus_ltr = 0; /* total number of RTL keysyms minus LTR ones */  for (code = xkb->min_key_code; code <= xkb->max_key_code; code++)    {      gint width = XkbKeyGroupWidth (xkb, code, group);      gint level;      for (level = 0; level < width; level++)	{	  KeySym sym = XkbKeySymEntry (xkb, code, level, group);	  PangoDirection dir = pango_unichar_direction (gdk_keyval_to_unicode (sym));	  switch (dir)	    {	    case PANGO_DIRECTION_RTL:	      rtl_minus_ltr++;	      break;	    case PANGO_DIRECTION_LTR:	      rtl_minus_ltr--;	      break;	    default:	      break;	    }	}    }      if (rtl_minus_ltr > 0)    return PANGO_DIRECTION_RTL;  else    return PANGO_DIRECTION_LTR;}static voidupdate_direction (GdkKeymapX11 *keymap_x11){  XkbDescRec *xkb = get_xkb (keymap_x11);  XkbStateRec state_rec;  GdkDisplay *display = GDK_KEYMAP (keymap_x11)->display;  gint group;  Atom group_atom;  XkbGetState (GDK_DISPLAY_XDISPLAY (display), XkbUseCoreKbd, &state_rec);  group = XkbGroupLock (&state_rec);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -