예제 #1
0
void CLowLevelKeyboard::Initialize(HWND hWnd)
{
  SDL_EnableUNICODE(1);
  // set repeat to 10ms to ensure repeat time < frame time
  // so that hold times can be reliably detected
  SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, 10);
#if defined(_LINUX) && !defined(__APPLE__)
  Display* dpy = XOpenDisplay(NULL);
  if (!dpy)
    return;

  XkbDescPtr desc;
  char* symbols;

  desc = XkbGetKeyboard(dpy, XkbAllComponentsMask, XkbUseCoreKbd);
  if(!desc)
  {
    XCloseDisplay(dpy);
    return;
  }

  symbols = XGetAtomName(dpy, desc->names->symbols);
  if(symbols)
  {
    CLog::Log(LOGDEBUG, "CLowLevelKeyboard::Initialize - XKb symbols %s", symbols);
    if(strstr(symbols, "(evdev)"))
      m_bEvdev = true;
  }

  XFree(symbols);
  XkbFreeKeyboard(desc, XkbAllComponentsMask, True);
  XCloseDisplay(dpy);
#endif
}
예제 #2
0
VkBool32 VKTS_APIENTRY _visualInitKey(Display* display)
{
    memset(g_keys, VKTS_KEY_UNKNOWN, sizeof(g_keys));

    XkbDescPtr desc = XkbGetKeyboard(display, XkbAllComponentsMask, XkbUseCoreKbd);

    if (!desc)
    {
        return VK_FALSE;
    }

    char name[XkbKeyNameLength + 1];
    name[XkbKeyNameLength] = '\0';

    for (int32_t keyCode = desc->min_key_code; keyCode <= desc->max_key_code; keyCode++)
    {
        if (keyCode < 0 || keyCode >= 512)
        {
            continue;
        }

        memcpy(name, desc->names->keys[keyCode].name, XkbKeyNameLength);

        g_keys[keyCode] = _visualMapKey(name);
    }

    XkbFreeKeyboard(desc, 0, True);

    return VK_TRUE;
}
예제 #3
0
void KeyboardLayoutWidget::setKeyboard(XkbComponentNamesPtr names)
{
    release();
    if (xkb)
        XkbFreeKeyboard(xkb, 0, TRUE);
    if (names) {
        xkb = XkbGetKeyboardByName (QX11Info::display(), XkbUseCoreKbd,
                      names, 0,
                      XkbGBN_GeometryMask |
                      XkbGBN_KeyNamesMask |
                      XkbGBN_OtherNamesMask |
                      XkbGBN_ClientSymbolsMask |
                      XkbGBN_IndicatorMapMask, FALSE);
        xkbOnDisplay = FALSE;
    } else {
        xkb = XkbGetKeyboard (QX11Info::display(),
                           XkbGBN_GeometryMask |
                           XkbGBN_KeyNamesMask |
                           XkbGBN_OtherNamesMask |
                           XkbGBN_SymbolsMask |
                           XkbGBN_IndicatorMapMask,
                           XkbUseCoreKbd);
        XkbGetNames (QX11Info::display(), XkbAllNamesMask, xkb);
        xkbOnDisplay = TRUE;
    }

    if (xkb == NULL)
        return;

    alloc ();
    init();
    initColors();
    generatePixmap(true);
    repaint();
}
예제 #4
0
static int check_for_evdev(void)
{
    SDL_SysWMinfo info;
    XkbDescPtr desc;
    int has_evdev = 0;
    const char *keycodes;

    SDL_VERSION(&info.version);
    if (!SDL_GetWMInfo(&info))
        return 0;

    desc = XkbGetKeyboard(info.info.x11.display,
                          XkbGBN_AllComponentsMask,
                          XkbUseCoreKbd);
    if (desc == NULL || desc->names == NULL)
        return 0;

    keycodes = XGetAtomName(info.info.x11.display, desc->names->keycodes);
    if (keycodes == NULL)
        fprintf(stderr, "could not lookup keycode name\n");
    else if (strstart(keycodes, "evdev", NULL))
        has_evdev = 1;
    else if (!strstart(keycodes, "xfree86", NULL))
        fprintf(stderr,
                "unknown keycodes `%s', please report to [email protected]\n",
                keycodes);

    XkbFreeClientMap(desc, XkbGBN_AllComponentsMask, True);

    return has_evdev;
}
예제 #5
0
static int check_for_evdev(void)
{
    SDL_SysWMinfo info;
    XkbDescPtr desc = NULL;
    int has_evdev = 0;
    char *keycodes = NULL;

    SDL_VERSION(&info.version);
    if (!SDL_GetWMInfo(&info)) {
        return 0;
    }
    desc = XkbGetKeyboard(info.info.x11.display,
                          XkbGBN_AllComponentsMask,
                          XkbUseCoreKbd);
    if (desc && desc->names) {
        keycodes = XGetAtomName(info.info.x11.display, desc->names->keycodes);
        if (keycodes == NULL) {
            fprintf(stderr, "could not lookup keycode name\n");
        } else if (strstart(keycodes, "evdev", NULL)) {
            has_evdev = 1;
        } else if (!strstart(keycodes, "xfree86", NULL)) {
            fprintf(stderr, "unknown keycodes `%s', please report to "
                    "[email protected]\n", keycodes);
        }
    }

    if (desc) {
        XkbFreeKeyboard(desc, XkbGBN_AllComponentsMask, True);
    }
    if (keycodes) {
        XFree(keycodes);
    }
    return has_evdev;
}
예제 #6
0
/*
 * Loads the XKB keymap from the X11 server and feeds it to xkbcommon.
 * Necessary so that we can properly let xkbcommon track the keyboard state and
 * translate keypresses to utf-8.
 *
 * Ideally, xkbcommon would ship something like this itself, but as of now
 * (version 0.2.0), it doesn’t.
 *
 */
static bool load_keymap(void) {
    bool ret = false;
    XkbFileInfo result;
    memset(&result, '\0', sizeof(result));
    result.xkb = XkbGetKeyboard(display, XkbAllMapComponentsMask, XkbUseCoreKbd);
    if (result.xkb == NULL) {
        fprintf(stderr, "[i3lock] XKB: XkbGetKeyboard failed\n");
        return false;
    }

    FILE *temp = tmpfile();
    if (temp == NULL) {
        fprintf(stderr, "[i3lock] could not create tempfile\n");
        return false;
    }

    bool ok = XkbWriteXKBKeymap(temp, &result, false, false, NULL, NULL);
    if (!ok) {
        fprintf(stderr, "[i3lock] XkbWriteXKBKeymap failed\n");
        goto out;
    }

    rewind(temp);

    if (xkb_context == NULL) {
        if ((xkb_context = xkb_context_new(0)) == NULL) {
            fprintf(stderr, "[i3lock] could not create xkbcommon context\n");
            goto out;
        }
    }

    if (xkb_keymap != NULL)
        xkb_keymap_unref(xkb_keymap);

    if ((xkb_keymap = xkb_keymap_new_from_file(xkb_context, temp, XKB_KEYMAP_FORMAT_TEXT_V1, 0)) == NULL) {
        fprintf(stderr, "[i3lock] xkb_keymap_new_from_file failed\n");
        goto out;
    }

    struct xkb_state *new_state = xkb_state_new(xkb_keymap);
    if (new_state == NULL) {
        fprintf(stderr, "[i3lock] xkb_state_new failed\n");
        goto out;
    }

    if (xkb_state != NULL)
        xkb_state_unref(xkb_state);
    xkb_state = new_state;

    ret = true;
out:
    XkbFreeKeyboard(result.xkb, XkbAllComponentsMask, true);
    fclose(temp);
    return ret;
}
예제 #7
0
unsigned int xkb_numlock_mask()
    {
    XkbDescPtr xkb;
    if(( xkb = XkbGetKeyboard( qt_xdisplay(), XkbAllComponentsMask, XkbUseCoreKbd )) != NULL )
	{
        unsigned int mask = xkb_mask_modifier( xkb, "NumLock" );
        XkbFreeKeyboard( xkb, 0, True );
        return mask;
        }
    return 0;
    }
예제 #8
0
KeyboardLayoutWidget::KeyboardLayoutWidget(QWidget* parent): QWidget(parent),
    ratio(1.0),
    trackModifiers(false )
{
    uint i = 0;
    for (i = 0; i < sizeof(deadMapData) / sizeof(deadMapData[0]); i ++)
        deadMap[deadMapData[i].dead] = deadMapData[i].nondead;

    xkb = XkbGetKeyboard (QX11Info::display(),
                          XkbGBN_GeometryMask |
                          XkbGBN_KeyNamesMask |
                          XkbGBN_OtherNamesMask |
                          XkbGBN_SymbolsMask |
                          XkbGBN_IndicatorMapMask,
                          XkbUseCoreKbd);

    if (!xkb)
        return;

    groupLevels = pGroupsLevels;

    XkbGetNames (QX11Info::display(), XkbAllNamesMask, xkb);

    l3mod = XkbKeysymToModifiers (QX11Info::display(),
                                  XK_ISO_Level3_Shift);

    XkbSelectEventDetails (QX11Info::display(), XkbUseCoreKbd,
                   XkbIndicatorStateNotify,
                   xkb->indicators->phys_indicators,
                   xkb->indicators->phys_indicators);

    xkbOnDisplay = true;

    int mask = (XkbStateNotifyMask | XkbNamesNotifyMask |
    XkbControlsNotifyMask | XkbIndicatorMapNotifyMask |
    XkbNewKeyboardNotifyMask);
    XkbSelectEvents (QX11Info::display(), XkbUseCoreKbd, mask, mask);


    mask = XkbGroupStateMask | XkbModifierStateMask;
    XkbSelectEventDetails (QX11Info::display(), XkbUseCoreKbd,
                   XkbStateNotify, mask, mask);

    mask = (XkbGroupNamesMask | XkbIndicatorNamesMask);
    XkbSelectEventDetails (QX11Info::display(), XkbUseCoreKbd,
                   XkbNamesNotify, mask, mask);


    alloc ();
    init();
    initColors();

    setFocusPolicy(Qt::StrongFocus);
}
XkbUI_ViewPtr
XkbUI_SimpleInit(Display *dpy,Window win,int width,int height)
{
XkbDescPtr	xkb;

    if ((!dpy)||(win==None)||(width<1)||(height<1))
	return NULL;
    xkb= XkbGetKeyboard(dpy,XkbGBN_AllComponentsMask,XkbUseCoreKbd);
    if (!xkb)
	return NULL;
    return XkbUI_Init(dpy,win,width,height,xkb,NULL);
}
예제 #10
0
파일: numlock.cpp 프로젝트: chtisgit/slim
static unsigned int xkb_numlock_mask(Display* dpy)
{
	XkbDescPtr xkb;

	xkb = XkbGetKeyboard( dpy, XkbAllComponentsMask, XkbUseCoreKbd );
	if( xkb != nullptr ) {
		unsigned int mask = xkb_mask_modifier( xkb, "NumLock" );
		XkbFreeKeyboard( xkb, 0, True );
		return mask;
	}
	return 0;
}
예제 #11
0
//Need to handle errors here properly.
void getKbd(virtkey * cvirt){
    if (cvirt->kbd)
        XkbFreeKeyboard (cvirt->kbd, XkbAllComponentsMask, True);

    cvirt->kbd = XkbGetKeyboard (cvirt->display,
                                    XkbCompatMapMask |
                                    XkbNamesMask |
                                    XkbGeometryMask,
                                    XkbUseCoreKbd);
    #if 0
    /* test missing keyboard (LP: 526791)
       keyboard on/off every 10 seconds */
    if (getenv ("VIRTKEY_DEBUG"))
    {
        if (cvirt->kbd && time(NULL) % 20 < 10)
        {
            XkbFreeKeyboard (cvirt->kbd, XkbAllComponentsMask, True);
            cvirt->kbd = NULL;
        }
    }
    #endif

    if (cvirt->kbd == NULL){
        PyErr_SetString(virtkey_error,
                        "XkbGetKeyboard failed to get keyboard from x server");
        return;
    }

    /*
    Status stat = XkbGetGeometry (cvirt->display, cvirt->kbd);

    if (stat == BadValue)
        PyErr_SetString(virtkey_error,
            "Error getting keyboard geometry info, Bad Value.\n");
    if (stat == BadImplementation)
        PyErr_SetString(virtkey_error,
            "Error getting keyboard geometry info, Bad Implementation.\n");
    if (stat == BadName)
        PyErr_SetString(virtkey_error,
            "Error getting keyboard geometry info, Bad Name.\n");
    if (stat == BadAlloc)
        PyErr_SetString(virtkey_error,
            "Error getting keyboard geometry info, Bad Alloc.\n");
    */

    if (XkbGetNames (cvirt->display, XkbAllNamesMask, cvirt->kbd) != Success)
        PyErr_SetString(virtkey_error, "Error getting key name info.\n");

    return;
}
예제 #12
0
// Called once. Checks whether evdev is loaded and sets m_bEvdev accordingly.
static void InitEvdev(void)
{
/*
	歌方:
		1、
		
	卦指:
		1、
		
	傍苧:
		1、
*/
	// Set m_bEvdevInit to indicate we have been initialised
	m_bEvdevInit = true;

	Display* dpy = XOpenDisplay(NULL);
	if (!dpy)
	{
		CLog::Log(LOGERROR, "CWinEventsSDL::CWinEventsSDL - XOpenDisplay failed");
		return;
	}

	XkbDescPtr desc;
	char* symbols;

	desc = XkbGetKeyboard(dpy, XkbAllComponentsMask, XkbUseCoreKbd);
	if(!desc)
	{
		XCloseDisplay(dpy);
		CLog::Log(LOGERROR, "CWinEventsSDL::CWinEventsSDL - XkbGetKeyboard failed");
		return;
	}

	symbols = XGetAtomName(dpy, desc->names->symbols);
	if(symbols)
	{
		CLog::Log(LOGDEBUG, "CWinEventsSDL::CWinEventsSDL - XKb symbols %s", symbols);
		if(strstr(symbols, "(evdev)"))
			m_bEvdev = true;
		else
			m_bEvdev = false;
	}

	XFree(symbols);
	XkbFreeKeyboard(desc, XkbAllComponentsMask, True);
	XCloseDisplay(dpy);

	CLog::Log(LOGDEBUG, "CWinEventsSDL::CWinEventsSDL - m_bEvdev = %d", m_bEvdev);
}
예제 #13
0
파일: bstxkb.c 프로젝트: whitelynx/beast
/* --- functions --- */
gboolean
bst_xkb_open (const gchar *const_display,
	      gboolean     sync)
{
  gchar *display = (gchar*) const_display;
  int ext_base_event, ext_base_error, ext_status;
  int ext_major = XkbMajorVersion;
  int ext_minor = XkbMinorVersion;

  g_return_val_if_fail (display != NULL, FALSE);
  g_return_val_if_fail (bst_xkb_display == NULL, FALSE);

  bst_xkb_display = XkbOpenDisplay (display,
				    &ext_base_event,
				    &ext_base_error,
				    &ext_major,
				    &ext_minor,
				    &ext_status);
  /* possible values for ext_status:
   *   XkbOD_BadLibraryVersion library version mismatch
   *   XkbOD_ConnectionRefused unable to open display
   *   XkbOD_BadServerVersion  server version mismatch
   *   XkbOD_NonXkbServer      XKB extension not present
   *   XkbOD_Success           guess what
   */
  if (bst_xkb_display && sync)
    XSynchronize (bst_xkb_display, True);
  if (bst_xkb_display && ext_status == XkbOD_Success)
    {
      bst_xkb_desc = XkbGetKeyboard (bst_xkb_display,
				     XkbAllComponentsMask,
				     XkbUseCoreKbd);
      if (bst_xkb_desc && (!bst_xkb_desc->names || !bst_xkb_desc->geom))
	{
	  XkbFreeKeyboard (bst_xkb_desc,
			   XkbAllComponentsMask,
			   True);
	  bst_xkb_desc = NULL;
	}
    }
  if (bst_xkb_display && !bst_xkb_desc)
    {
      XCloseDisplay (bst_xkb_display);
      bst_xkb_display = NULL;
    }

  return bst_xkb_desc != NULL;
}
예제 #14
0
//========================================
// XAccess...
//----------------------------------------
void XAccess(Display *dpy,char *displayname) {
 #ifndef __powerpc__
 XkbDescPtr xkb;
 int major, minor,op, event, error;
 int timeout = 5;

 // Query XKB Extension...
 // -----------------------
 major = XkbMajorVersion;
 minor = XkbMinorVersion;
 if (XkbQueryExtension(dpy, &op, &event, &error, &major, &minor) == 0) {
  printf("xaccess: Unable to initialize XKEYBOARD extension");
  exit(1);
 }
 while (timeout > 0) {
  xkb = XkbGetKeyboard(dpy, XkbGBN_AllComponentsMask, XkbUseCoreKbd);
  if (xkb == NULL || xkb->geom == NULL) {
   timeout -= 1; sleep(1);
  } else {
   break;
  }
 }
 if (timeout <= 0) {
  printf("xaccess: Couldn't get keyboard\n");
  exit(1);
 }
 
 // Everything is fine, now set the access block...
 // ------------------------------------------------ 
 XkbGetControls(dpy, XkbAllControlsMask, xkb);
 if (xkb->ctrls == NULL) {
  xkb->ctrls = (XkbControlsPtr)malloc(sizeof(XkbControlsRec));
 }

 xkb->ctrls->enabled_ctrls |= XkbMouseKeysMask | XkbMouseKeysAccelMask;
 xkb->ctrls->mk_delay       = 40;
 xkb->ctrls->mk_interval    = 10;
 xkb->ctrls->mk_time_to_max = 1000;
 xkb->ctrls->mk_max_speed   = 500;
 xkb->ctrls->mk_curve       = 0;

 // Set keyboard control...
 // ------------------------
 XkbSetControls(dpy, XkbAllControlsMask, xkb);
 XSync(dpy, False);
 #endif
}
예제 #15
0
Bool NestedClientGetKeyboardMappings(NestedClientPrivatePtr pPriv, KeySymsPtr keySyms, CARD8 *modmap, XkbControlsPtr ctrls) {
    XModifierKeymap *modifier_keymap;
    KeySym *keymap;
    int mapWidth;
    int min_keycode, max_keycode;
    int i, j;
    XkbDescPtr xkb;

    XDisplayKeycodes(pPriv->display, &min_keycode, &max_keycode);
    keymap = XGetKeyboardMapping(pPriv->display,
                                 min_keycode,
                                 max_keycode - min_keycode + 1,
                                 &mapWidth);

    memset(modmap, 0, sizeof(CARD8) * MAP_LENGTH);
    modifier_keymap = XGetModifierMapping(pPriv->display);
    for (j = 0; j < 8; j++)
        for(i = 0; i < modifier_keymap->max_keypermod; i++) {
            CARD8 keycode;
            if ((keycode = modifier_keymap->modifiermap[j * modifier_keymap->max_keypermod + i]))
                modmap[keycode] |= 1<<j;
    }
    XFreeModifiermap(modifier_keymap);

    keySyms->minKeyCode = min_keycode;
    keySyms->maxKeyCode = max_keycode;
    keySyms->mapWidth = mapWidth;
    keySyms->map = keymap;

    xkb = XkbGetKeyboard(pPriv->display, XkbGBN_AllComponentsMask, XkbUseCoreKbd);
    if (xkb == NULL || xkb->geom == NULL) {
        xf86DrvMsg(pPriv->scrnIndex, X_ERROR, "Couldn't get XKB keyboard.\n");
        free(keymap);
        return FALSE;
    }

    if(XkbGetControls(pPriv->display, XkbAllControlsMask, xkb) != Success) {
        xf86DrvMsg(pPriv->scrnIndex, X_ERROR, "Couldn't get XKB keyboard controls.\n");
        free(keymap);
        return FALSE;
    }

    memcpy(ctrls, xkb->ctrls, sizeof(XkbControlsRec));
    XkbFreeKeyboard(xkb, 0, False);
    return TRUE;
}
예제 #16
0
파일: NumLock.cpp 프로젝트: edeproject/svn
static unsigned int numlock_mask(Display* dpy) {
	XkbDescPtr xkb = XkbGetKeyboard(dpy, XkbAllComponentsMask, XkbUseCoreKbd);
	if(xkb == NULL)
		return 0;

	char* modstr;
	unsigned int mask = 0;

	for(int i = 0; i < XkbNumVirtualMods; i++) {
		modstr = XGetAtomName(xkb->dpy, xkb->names->vmods[i]);
		if(modstr != NULL && strcmp(modstr, "NumLock") == 0) {
			XkbVirtualModsToReal(xkb, 1 << i, &mask);
			break;
		}
	}

	XkbFreeKeyboard(xkb, 0, True);
	return mask;
}
예제 #17
0
//=====================================
// XKeyboard auto repeat set
//-------------------------------------
void XKeyboard::autoRepeat ( void ) {
	// log(L_INFO,"XKeyboard::autoRepeat() called\n");
	// ...
	// This function is called if either the repeat or
	// delay rate has changed. We will use xset to apply
	// the new rate/delay values to the X-Server. The
	// function is called after the slider has been 
	// released
	// ---
	XkbDescPtr xkb;
	int major = XkbMajorVersion;
	int minor = XkbMinorVersion;
	int op, event, error;
	int timeout = 500;
	Display* dpy = QApplication::desktop()->x11Display();
	if (XkbQueryExtension(dpy, &op, &event, &error, &major, &minor) == 0) {
		log (L_INFO,"XKeyboard::Unable to initialize XKB extension");
		return;
	}
	while (timeout > 0) {
		xkb = XkbGetKeyboard (
			dpy, XkbGBN_AllComponentsMask, XkbUseCoreKbd
		);
		if (xkb == NULL || xkb->geom == NULL) {
			timeout -= 1; usleep(100);
		} else {
			break;
		}
	}
	if (timeout <= 0) {
		log (L_INFO,"XKeyboard::Couldn't get keyboard\n");
		return;
	}
	XkbGetControls (dpy, XkbRepeatKeysMask, xkb);
	xkb->ctrls->repeat_delay = mDelay->value();
	xkb->ctrls->repeat_interval = 1000/mRepeat->value();
	XkbSetControls (
		dpy, XkbRepeatKeysMask, xkb
	);
	XSync (dpy, False);
}
예제 #18
0
//=====================================
// XAccessX init page with data infos 
//-------------------------------------
void XAccessX::initPage (void) {
	// log (L_INFO,"XAccessX::initPage() called\n");
	// ...
	// this function is called after the page was created.
	// It must only be used to init the widgets contents
	// with the data available for selections and other stuff
	// like that
    // ---	
	// Query XKB Extension...
	// -----------------------
	int timeout = 5;
	major = XkbMajorVersion;
	minor = XkbMinorVersion;
	if (XkbQueryExtension(
		x11Display(), &op, &event, &error, &major, &minor) == 0
	) {
	log(L_WARN,
		"XKB: Unable to initialize XKEYBOARD extension\n"
	);
	}
	while (timeout > 0) {
		xkb = XkbGetKeyboard(
			x11Display(), XkbGBN_AllComponentsMask, XkbUseCoreKbd
		);
		if (xkb == NULL || xkb->geom == NULL) {
		timeout -= 1; sleep(1);
		} else {
		break;
		}
	}
	if (timeout <= 0) {
	log (L_WARN,
		"XKB: Couldn't get keyboard\n"
	);
	} 
}
예제 #19
0
void CKeyboardStat::Initialize()
{
/* this stuff probably doesn't belong here  *
 * but in some x11 specific WinEvents file  *
 * but for some reason the code to map keys *
 * to specific xbmc vkeys is here           */
#if defined(_LINUX) && !defined(__APPLE__)
  Display* dpy = XOpenDisplay(NULL);
  if (!dpy)
    return;

  XkbDescPtr desc;
  char* symbols;

  desc = XkbGetKeyboard(dpy, XkbAllComponentsMask, XkbUseCoreKbd);
  if(!desc)
  {
    XCloseDisplay(dpy);
    return;
  }

  symbols = XGetAtomName(dpy, desc->names->symbols);
  if(symbols)
  {
    CLog::Log(LOGDEBUG, "CKeyboardStat::Initialize - XKb symbols %s", symbols);
    if(strstr(symbols, "(evdev)"))
      m_bEvdev = true;
    else
      m_bEvdev = false;
  }

  XFree(symbols);
  XkbFreeKeyboard(desc, XkbAllComponentsMask, True);
  XCloseDisplay(dpy);
#endif
}
예제 #20
0
파일: xinput.c 프로젝트: 4eremuxa/xserver
int main(int argc, char **argv)
{
    Display              *display = NULL;
    int                  device   = -1;
    int                  newmouse = -1;
    int                  newkbd   = -1;
    int                  count;
    int                  i, j;
    XDeviceInfo          *devInfo;
    XExtensionVersion    *ext;

    if (argc == 2 || argc == 3 || argc == 4 || argc == 5) {
        if (!(display = XOpenDisplay(argv[1]))) {
            printf("Cannot open display %s\n", argv[1]);
            return -1;
        }
        if (argc >= 3) device   = strtol(argv[2], NULL, 0);
        if (argc >= 4) newmouse = strtol(argv[3], NULL, 0);
        if (argc >= 5) newkbd   = strtol(argv[4], NULL, 0);
    } else {
        printf("Usage: %s display [device] [newmouse] [newkbd]\n", argv[0]);
        return -1;
    }

    if (!display && !(display = XOpenDisplay(NULL))) {
        printf("Cannot open default display\n");
        return -1;
    }

    ext = XGetExtensionVersion(display, INAME);
    if (!ext || ext == (XExtensionVersion *)NoSuchExtension) {
        printf("No XInputExtension\n");
        return -1;
    }
    printf("%s version %d.%d\n",
           INAME, ext->major_version, ext->minor_version);

    if (!(devInfo = XListInputDevices(display, &count)) || !count) {
        printf("Cannot list devices\n");
        return -1;
    }

    for (i = 0; i < count; i++) {
        XAnyClassPtr any;
        const char   *kind   = "Unknown";
        int          has_key = 0;
        
        switch (devInfo[i].use) {
        case IsXPointer:         kind = "XPointer";         break;
        case IsXKeyboard:        kind = "XKeyboard";        break;
        case IsXExtensionDevice: kind = "XExtensionDevice"; break;
        }
        printf("%2lu %-20.20s %-16.16s",
               (long unsigned)devInfo[i].id,
               devInfo[i].name ? devInfo[i].name : "", kind);

        for (j = 0, any = devInfo[i].inputclassinfo;
             j < devInfo[i].num_classes;
             any = (XAnyClassPtr)((char *)any + any->length), j++) {
            const char   *class = "unk";
            switch (any->class) {
            case KeyClass:       class = "key"; ++has_key; break;
            case ButtonClass:    class = "btn"; break;
            case ValuatorClass:  class = "val"; break;
            case FeedbackClass:  class = "fdb"; break;
            case ProximityClass: class = "prx"; break;
            case FocusClass:     class = "foc"; break;
            case OtherClass:     class = "oth"; break;
            }
            printf(" %s", class);
        }
        printf("\n");
        printdmxinfo(display, i);

        if (has_key) {
            XkbDescPtr           xkb;
            if ((xkb = XkbGetKeyboard(display,
                                      XkbAllComponentsMask,
                                      devInfo[i].id))) {
                printf("   Xkb Information:\n");
                printf("      Device id = %d\n", xkb->device_spec);
                printf("      Min keycode = 0x%02x\n", xkb->min_key_code);
                printf("      Max keycode = 0x%02x\n", xkb->max_key_code);
#define PRINTNAME(x)                                                     \
    printf("      %s = %s\n",                                            \
           #x, xkb->names->x ? XGetAtomName(display, xkb->names->x) : "")
                PRINTNAME(keycodes);
                PRINTNAME(geometry);
                PRINTNAME(symbols);
                PRINTNAME(types);
                PRINTNAME(compat);
            }
        }
    }

    if (newmouse >= 0) {
        XDevice     *dev;

        printf("Trying to make device %d core mouse\n", newmouse);
        dev = XOpenDevice(display, devInfo[newmouse].id);
        printf("Status = %d\n",
               XChangePointerDevice(display, dev, 0, 1));
        return 0;
    }

    if (newkbd >= 0) {
        XDevice     *dev;

        printf("Trying to make device %d core keyboard\n", newkbd);
        dev = XOpenDevice(display, devInfo[newkbd].id);
        printf("Status = %d\n",
               XChangeKeyboardDevice(display, dev));
        return 0;
    }
            

    if (device >=0){
#define MAX_EVENTS 100
        int         cnt = 0;
        XDevice     *dev;
        XEventClass event_list[MAX_EVENTS];
        int         event_type[MAX_EVENTS];
        const char  *names[MAX_EVENTS];
        int         total = 0;

#define ADD(type)                                     \
        if (cnt >= MAX_EVENTS) abort();             \
        names[cnt] = #type;                           \
        type(dev, event_type[cnt], event_list[cnt]);  \
        if (event_type[cnt]) ++cnt
        

        dev = XOpenDevice(display, devInfo[device].id);
        ADD(DeviceKeyPress);
        ADD(DeviceKeyRelease);
        ADD(DeviceButtonPress);
        ADD(DeviceButtonRelease);
        ADD(DeviceMotionNotify);
        ADD(DeviceFocusIn);
        ADD(DeviceFocusOut);
        ADD(ProximityIn);
        ADD(ProximityOut);
        ADD(DeviceStateNotify);
        ADD(DeviceMappingNotify);
        ADD(ChangeDeviceNotify);
        
        for (i = 0; i < cnt; i++) {
            printf("Waiting for %s events of type %d (%lu) on 0x%08lx\n",
                   names[i],
                   event_type[i], (unsigned long)event_list[i],
                   (long unsigned)DefaultRootWindow(display));
        }
        XSelectExtensionEvent(display, DefaultRootWindow(display),
                              event_list, cnt);
        
        for (;;) {
            XEvent event;
            XNextEvent(display, &event);
            for (i = 0; i < cnt; i++) {
                XDeviceMotionEvent *e = (XDeviceMotionEvent *)&event;
                XDeviceButtonEvent *b = (XDeviceButtonEvent *)&event;
                if (event.type == event_type[i]) {
                    printf("%s id=%lu (%d @ %d,%d; s=0x%04x, d=%d, t=%lu)"
                           " axes_count=%d first=%d %d %d %d %d %d %d\n",
                           names[i],
                           (long unsigned)e->deviceid,
                           e->type,
                           e->x, e->y,
                           e->device_state,
                           b->button,
                           (long unsigned)b->time,
                           e->axes_count,
                           e->first_axis,
                           e->axis_data[0],
                           e->axis_data[1],
                           e->axis_data[2],
                           e->axis_data[3],
                           e->axis_data[4],
                           e->axis_data[5]);
                }
            }
            ++total;
#if 0
                                /* Used to check motion history for
                                 * extension devices. */
            if (!(total % 10)) {
                XDeviceTimeCoord *tc;
                int              n, m, a;
                struct timeval   tv;
                unsigned long    ms;
                gettimeofday(&tv, NULL);
                ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
                tc = XGetDeviceMotionEvents(display, dev, ms-1000, ms,
                                            &n, &m, &a);
                printf("Got %d events of mode %s with %d axes\n",
                       n, m == Absolute ? "Absolute" : "Relative", a);
                for (i = 0; i < n && i < 10; i++) {
                    printf("  %d: %lu %d %d\n",
                           i, tc[i].time, tc[i].data[0], tc[i].data[1]);
                }
                XFreeDeviceMotionEvents(tc);
            }
#endif                
        }
    }

    XCloseDisplay(display);
    return 0;
}
예제 #21
0
int
xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
{
    XModifierKeymap *modifier_keymap;
    KeySym *keymap;
    int mapWidth;
    int min_keycode, max_keycode;
    KeySymsRec keySyms;
    CARD8 modmap[MAP_LENGTH];
    int i, j;
    XKeyboardState values;
    XkbDescPtr xkb;
    int op, event, error, major, minor;

    switch (onoff) {
    case DEVICE_INIT:
        XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode);
#ifdef _XSERVER64
        {
            KeySym64 *keymap64;
            int len;

            keymap64 = XGetKeyboardMapping(xnestDisplay,
                                           min_keycode,
                                           max_keycode - min_keycode + 1,
                                           &mapWidth);
            len = (max_keycode - min_keycode + 1) * mapWidth;
            keymap = xallocarray(len, sizeof(KeySym));
            for (i = 0; i < len; ++i)
                keymap[i] = keymap64[i];
            XFree(keymap64);
        }
#else
        keymap = XGetKeyboardMapping(xnestDisplay,
                                     min_keycode,
                                     max_keycode - min_keycode + 1, &mapWidth);
#endif

        memset(modmap, 0, sizeof(modmap));
        modifier_keymap = XGetModifierMapping(xnestDisplay);
        for (j = 0; j < 8; j++)
            for (i = 0; i < modifier_keymap->max_keypermod; i++) {
                CARD8 keycode;

                if ((keycode =
                     modifier_keymap->modifiermap[j *
                                                  modifier_keymap->
                                                  max_keypermod + i]))
                    modmap[keycode] |= 1 << j;
            }
        XFreeModifiermap(modifier_keymap);

        keySyms.minKeyCode = min_keycode;
        keySyms.maxKeyCode = max_keycode;
        keySyms.mapWidth = mapWidth;
        keySyms.map = keymap;

        if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor)
            == 0) {
            ErrorF("Unable to initialize XKEYBOARD extension.\n");
            goto XkbError;
        }
        xkb =
            XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask,
                           XkbUseCoreKbd);
        if (xkb == NULL || xkb->geom == NULL) {
            ErrorF("Couldn't get keyboard.\n");
            goto XkbError;
        }
        XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb);

        InitKeyboardDeviceStruct(pDev, NULL,
                                 xnestBell, xnestChangeKeyboardControl);

        XkbApplyMappingChange(pDev, &keySyms, keySyms.minKeyCode,
                              keySyms.maxKeyCode - keySyms.minKeyCode + 1,
                              modmap, serverClient);

        XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls);
        XkbFreeKeyboard(xkb, 0, False);
        free(keymap);
        break;
    case DEVICE_ON:
        xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK;
        for (i = 0; i < xnestNumScreens; i++)
            XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
        break;
    case DEVICE_OFF:
        xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK;
        for (i = 0; i < xnestNumScreens; i++)
            XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
        break;
    case DEVICE_CLOSE:
        break;
    }
    return Success;

 XkbError:
    XGetKeyboardControl(xnestDisplay, &values);
    memmove((char *) defaultKeyboardControl.autoRepeats,
            (char *) values.auto_repeats, sizeof(values.auto_repeats));

    InitKeyboardDeviceStruct(pDev, NULL, xnestBell, xnestChangeKeyboardControl);
    free(keymap);
    return Success;
}
예제 #22
0
// Update the key code LUT
//
static void updateKeyCodeLUT(void)
{
    int i, keyCode, keyCodeGLFW;
    char name[XkbKeyNameLength + 1];
    XkbDescPtr descr;

    // Clear the LUT
    for (keyCode = 0;  keyCode < 256;  keyCode++)
        _glfw.x11.keyCodeLUT[keyCode] = GLFW_KEY_UNKNOWN;

    // Use XKB to determine physical key locations independently of the current
    // keyboard layout

    // Get keyboard description
    descr = XkbGetKeyboard(_glfw.x11.display,
                            XkbAllComponentsMask,
                            XkbUseCoreKbd);

    // Find the X11 key code -> GLFW key code mapping
    for (keyCode = descr->min_key_code; keyCode <= descr->max_key_code; ++keyCode)
    {
        // Get the key name
        for (i = 0;  i < XkbKeyNameLength;  i++)
            name[i] = descr->names->keys[keyCode].name[i];

        name[XkbKeyNameLength] = 0;

        // Map the key name to a GLFW key code. Note: We only map printable
        // keys here, and we use the US keyboard layout. The rest of the
        // keys (function keys) are mapped using traditional KeySym
        // translations.
        if (strcmp(name, "TLDE") == 0) keyCodeGLFW = GLFW_KEY_GRAVE_ACCENT;
        else if (strcmp(name, "AE01") == 0) keyCodeGLFW = GLFW_KEY_1;
        else if (strcmp(name, "AE02") == 0) keyCodeGLFW = GLFW_KEY_2;
        else if (strcmp(name, "AE03") == 0) keyCodeGLFW = GLFW_KEY_3;
        else if (strcmp(name, "AE04") == 0) keyCodeGLFW = GLFW_KEY_4;
        else if (strcmp(name, "AE05") == 0) keyCodeGLFW = GLFW_KEY_5;
        else if (strcmp(name, "AE06") == 0) keyCodeGLFW = GLFW_KEY_6;
        else if (strcmp(name, "AE07") == 0) keyCodeGLFW = GLFW_KEY_7;
        else if (strcmp(name, "AE08") == 0) keyCodeGLFW = GLFW_KEY_8;
        else if (strcmp(name, "AE09") == 0) keyCodeGLFW = GLFW_KEY_9;
        else if (strcmp(name, "AE10") == 0) keyCodeGLFW = GLFW_KEY_0;
        else if (strcmp(name, "AE11") == 0) keyCodeGLFW = GLFW_KEY_MINUS;
        else if (strcmp(name, "AE12") == 0) keyCodeGLFW = GLFW_KEY_EQUAL;
        else if (strcmp(name, "AD01") == 0) keyCodeGLFW = GLFW_KEY_Q;
        else if (strcmp(name, "AD02") == 0) keyCodeGLFW = GLFW_KEY_W;
        else if (strcmp(name, "AD03") == 0) keyCodeGLFW = GLFW_KEY_E;
        else if (strcmp(name, "AD04") == 0) keyCodeGLFW = GLFW_KEY_R;
        else if (strcmp(name, "AD05") == 0) keyCodeGLFW = GLFW_KEY_T;
        else if (strcmp(name, "AD06") == 0) keyCodeGLFW = GLFW_KEY_Y;
        else if (strcmp(name, "AD07") == 0) keyCodeGLFW = GLFW_KEY_U;
        else if (strcmp(name, "AD08") == 0) keyCodeGLFW = GLFW_KEY_I;
        else if (strcmp(name, "AD09") == 0) keyCodeGLFW = GLFW_KEY_O;
        else if (strcmp(name, "AD10") == 0) keyCodeGLFW = GLFW_KEY_P;
        else if (strcmp(name, "AD11") == 0) keyCodeGLFW = GLFW_KEY_LEFT_BRACKET;
        else if (strcmp(name, "AD12") == 0) keyCodeGLFW = GLFW_KEY_RIGHT_BRACKET;
        else if (strcmp(name, "AC01") == 0) keyCodeGLFW = GLFW_KEY_A;
        else if (strcmp(name, "AC02") == 0) keyCodeGLFW = GLFW_KEY_S;
        else if (strcmp(name, "AC03") == 0) keyCodeGLFW = GLFW_KEY_D;
        else if (strcmp(name, "AC04") == 0) keyCodeGLFW = GLFW_KEY_F;
        else if (strcmp(name, "AC05") == 0) keyCodeGLFW = GLFW_KEY_G;
        else if (strcmp(name, "AC06") == 0) keyCodeGLFW = GLFW_KEY_H;
        else if (strcmp(name, "AC07") == 0) keyCodeGLFW = GLFW_KEY_J;
        else if (strcmp(name, "AC08") == 0) keyCodeGLFW = GLFW_KEY_K;
        else if (strcmp(name, "AC09") == 0) keyCodeGLFW = GLFW_KEY_L;
        else if (strcmp(name, "AC10") == 0) keyCodeGLFW = GLFW_KEY_SEMICOLON;
        else if (strcmp(name, "AC11") == 0) keyCodeGLFW = GLFW_KEY_APOSTROPHE;
        else if (strcmp(name, "AB01") == 0) keyCodeGLFW = GLFW_KEY_Z;
        else if (strcmp(name, "AB02") == 0) keyCodeGLFW = GLFW_KEY_X;
        else if (strcmp(name, "AB03") == 0) keyCodeGLFW = GLFW_KEY_C;
        else if (strcmp(name, "AB04") == 0) keyCodeGLFW = GLFW_KEY_V;
        else if (strcmp(name, "AB05") == 0) keyCodeGLFW = GLFW_KEY_B;
        else if (strcmp(name, "AB06") == 0) keyCodeGLFW = GLFW_KEY_N;
        else if (strcmp(name, "AB07") == 0) keyCodeGLFW = GLFW_KEY_M;
        else if (strcmp(name, "AB08") == 0) keyCodeGLFW = GLFW_KEY_COMMA;
        else if (strcmp(name, "AB09") == 0) keyCodeGLFW = GLFW_KEY_PERIOD;
        else if (strcmp(name, "AB10") == 0) keyCodeGLFW = GLFW_KEY_SLASH;
        else if (strcmp(name, "BKSL") == 0) keyCodeGLFW = GLFW_KEY_BACKSLASH;
        else if (strcmp(name, "LSGT") == 0) keyCodeGLFW = GLFW_KEY_WORLD_1;
        else keyCodeGLFW = GLFW_KEY_UNKNOWN;

        // Update the key code LUT
        if ((keyCode >= 0) && (keyCode < 256))
            _glfw.x11.keyCodeLUT[keyCode] = keyCodeGLFW;
    }

    // Free the keyboard description
    XkbFreeKeyboard(descr, 0, True);

    // Translate the un-translated key codes using traditional X11 KeySym
    // lookups
    for (keyCode = 0;  keyCode < 256;  keyCode++)
    {
        if (_glfw.x11.keyCodeLUT[keyCode] < 0)
            _glfw.x11.keyCodeLUT[keyCode] = translateKey(keyCode);
    }
}
예제 #23
0
const guint16 const *vnc_display_keymap_gdk2xtkbd_table(GdkWindow *window,
                                                        size_t *maplen)
{
#ifdef GDK_WINDOWING_X11
	if (GDK_IS_X11_WINDOW(window)) {
		XkbDescPtr desc;
		const gchar *keycodes = NULL;
                GdkDisplay *dpy = gdk_window_get_display(window);

		/* There is no easy way to determine what X11 server
		 * and platform & keyboard driver is in use. Thus we
		 * do best guess heuristics.
		 *
		 * This will need more work for people with other
		 * X servers..... patches welcomed.
		 */

		desc = XkbGetKeyboard(gdk_x11_display_get_xdisplay(dpy),
				      XkbGBN_AllComponentsMask,
				      XkbUseCoreKbd);
		if (desc) {
			if (desc->names) {
				keycodes = gdk_x11_get_xatom_name(desc->names->keycodes);
				if (!keycodes)
					g_warning("could not lookup keycode name");
			}
			XkbFreeKeyboard(desc, XkbGBN_AllComponentsMask, True);
		}

		if (check_for_xwin(dpy)) {
			VNC_DEBUG("Using xwin keycode mapping");
			*maplen = G_N_ELEMENTS(keymap_xorgxwin2xtkbd);
			return keymap_xorgxwin2xtkbd;
		} else if (check_for_xquartz(dpy)) {
			VNC_DEBUG("Using xquartz keycode mapping");
			*maplen = G_N_ELEMENTS(keymap_xorgxquartz2xtkbd);
			return keymap_xorgxquartz2xtkbd;
		} else if (keycodes && STRPREFIX(keycodes, "evdev_")) {
			VNC_DEBUG("Using evdev keycode mapping");
			*maplen = G_N_ELEMENTS(keymap_xorgevdev2xtkbd);
			return keymap_xorgevdev2xtkbd;
		} else if (keycodes && STRPREFIX(keycodes, "xfree86_")) {
			VNC_DEBUG("Using xfree86 keycode mapping");
			*maplen = G_N_ELEMENTS(keymap_xorgkbd2xtkbd);
			return keymap_xorgkbd2xtkbd;
		} else {
			g_warning("Unknown keycode mapping '%s'.\n"
				  "Please report to [email protected]\n"
				  "including the following information:\n"
				  "\n"
				  "  - Operating system\n"
				  "  - GDK build\n"
				  "  - X11 Server\n"
				  "  - xprop -root\n"
				  "  - xdpyinfo\n",
				  keycodes);
			return NULL;
		}
	}
#endif

#ifdef GDK_WINDOWING_WIN32
	if (GDK_IS_WIN32_WINDOW(window)) {
		VNC_DEBUG("Using Win32 virtual keycode mapping");
		*maplen = G_N_ELEMENTS(keymap_win322xtkbd);
		return keymap_win322xtkbd;
	}
#endif

#ifdef GDK_WINDOWING_QUARTZ
	if (GDK_IS_QUARTZ_WINDOW(window)) {
		VNC_DEBUG("Using OS-X virtual keycode mapping");
		*maplen = G_N_ELEMENTS(keymap_osx2xtkbd);
		return keymap_osx2xtkbd;
	}
#endif

#ifdef GDK_WINDOWING_WAYLAND
	if (GDK_IS_WAYLAND_WINDOW(window)) {
		VNC_DEBUG("Using Wayland Xorg/evdev virtual keycode mapping");
		*maplen = G_N_ELEMENTS(keymap_xorgevdev2xtkbd);
		return keymap_xorgevdev2xtkbd;
        }
#endif

#ifdef GDK_WINDOWING_BROADWAY
	if (GDK_IS_BROADWAY_WINDOW(window)) {
                g_warning("experimental: using broadway, x11 virtual keysym mapping - with very limited support. See also https://bugzilla.gnome.org/show_bug.cgi?id=700105");

			*maplen = G_N_ELEMENTS(keymap_x112xtkbd);
			return keymap_x112xtkbd;
        }
#endif

	g_warning("Unsupported GDK Windowing platform.\n"
		  "Disabling extended keycode tables.\n"
		  "Please report to [email protected]\n"
		  "including the following information:\n"
		  "\n"
		  "  - Operating system\n"
		  "  - GDK Windowing system build\n");
	return NULL;
}
예제 #24
0
int
xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
{
  XModifierKeymap *modifier_keymap;
  KeySym *keymap;
  int mapWidth;
  int min_keycode, max_keycode;
  KeySymsRec keySyms;
  CARD8 modmap[MAP_LENGTH];
  int i, j;
  XKeyboardState values;

  switch (onoff)
    {
    case DEVICE_INIT: 
      modifier_keymap = XGetModifierMapping(xnestDisplay);
      XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode);
#ifdef _XSERVER64
      {
	KeySym64 *keymap64;
	int i, len;
	keymap64 = XGetKeyboardMapping(xnestDisplay,
				     min_keycode,
				     max_keycode - min_keycode + 1,
				     &mapWidth);
	len = (max_keycode - min_keycode + 1) * mapWidth;
	keymap = (KeySym *)xalloc(len * sizeof(KeySym));
	for(i = 0; i < len; ++i)
	  keymap[i] = keymap64[i];
	XFree(keymap64);
      }
#else
      keymap = XGetKeyboardMapping(xnestDisplay, 
				   min_keycode,
				   max_keycode - min_keycode + 1,
				   &mapWidth);
#endif
      
      for (i = 0; i < MAP_LENGTH; i++)
	modmap[i] = 0;
      for (j = 0; j < 8; j++)
	for(i = 0; i < modifier_keymap->max_keypermod; i++) {
	  CARD8 keycode;
	  if ((keycode = 
	      modifier_keymap->
	        modifiermap[j * modifier_keymap->max_keypermod + i]))
	    modmap[keycode] |= 1<<j;
	}
      XFreeModifiermap(modifier_keymap);
      
      keySyms.minKeyCode = min_keycode;
      keySyms.maxKeyCode = max_keycode;
      keySyms.mapWidth = mapWidth;
      keySyms.map = keymap;

#ifdef XKB
      if (noXkbExtension) {
XkbError:
#endif
      XGetKeyboardControl(xnestDisplay, &values);

      memmove((char *) defaultKeyboardControl.autoRepeats,
             (char *) values.auto_repeats, sizeof(values.auto_repeats));

      InitKeyboardDeviceStruct(&pDev->public, &keySyms, modmap,
			       xnestBell, xnestChangeKeyboardControl);
#ifdef XKB
      } else {
	FILE *file;
	XkbConfigRtrnRec config;

	XkbComponentNamesRec names;
	char *rules, *model, *layout, *variants, *options;

	XkbDescPtr xkb;
	int op, event, error, major, minor;

	if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor) == 0) {
	  ErrorF("Unable to initialize XKEYBOARD extension.\n");
	  goto XkbError;
        }
	xkb = XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd);
	if (xkb == NULL || xkb->geom == NULL) {
	  ErrorF("Couldn't get keyboard.\n");
	  goto XkbError;
	}
	XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb);

	memset(&names, 0, sizeof(XkbComponentNamesRec));
	rules = XKB_DFLT_RULES_FILE;
	model = XKB_DFLT_KB_MODEL;
	layout = XKB_DFLT_KB_LAYOUT;
	variants = XKB_DFLT_KB_VARIANT;
	options = XKB_DFLT_KB_OPTIONS;
	if (XkbInitialMap) {
	  if ((names.keymap = strchr(XkbInitialMap, '/')) != NULL)
	    ++names.keymap;
	  else
	    names.keymap = XkbInitialMap;
	}

	XkbSetRulesDflts(rules, model, layout, variants, options);
	XkbInitKeyboardDeviceStruct(pDev, &names, &keySyms, modmap,
				    xnestBell, xnestChangeKeyboardControl);
	XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls);
	XkbFreeKeyboard(xkb, 0, False);
      }
#endif
#ifdef _XSERVER64
      xfree(keymap);
#else
      XFree(keymap);
#endif
      break;
    case DEVICE_ON: 
      xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK;
      for (i = 0; i < xnestNumScreens; i++)
	XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
      break;
    case DEVICE_OFF: 
      xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK;
      for (i = 0; i < xnestNumScreens; i++)
	XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
      break;
    case DEVICE_CLOSE: 
      break;
    }
예제 #25
0
static guint
compute_above_tab_keycode (Display *xdisplay)
{
  XkbDescPtr keyboard;
  XkbGeometryPtr geometry;
  int i, j, k;
  int tab_keycode;
  char *tab_name;
  XkbSectionPtr tab_section;
  XkbBoundsRec tab_bounds;
  XkbKeyPtr best_key = NULL;
  guint best_keycode = (guint)-1;
  int best_x_dist = G_MAXINT;
  int best_y_dist = G_MAXINT;

  /* We need only the Names and the Geometry, but asking for these results
   * in the Keyboard information retrieval failing for unknown reasons.
   * (Testing with xorg-1.9.1.) So we ask for a part that we don't need
   * as well.
   */
  keyboard = XkbGetKeyboard (xdisplay,
                             XkbGBN_ClientSymbolsMask | XkbGBN_KeyNamesMask | XkbGBN_GeometryMask,
                             XkbUseCoreKbd);
  if (!keyboard)
    return best_keycode;

  geometry = keyboard->geom;

  /* There could potentially be multiple keys with the Tab keysym on the keyboard;
   * but XKeysymToKeycode() returns us the one that the alt-Tab binding will
   * use which is good enough
   */
  tab_keycode = XKeysymToKeycode (xdisplay, XK_Tab);
  if (tab_keycode == 0 || tab_keycode < keyboard->min_key_code || tab_keycode > keyboard->max_key_code)
    goto out;

  /* The keyboard geometry is stored by key "name" rather than keycode.
   * (Key names are 4-character strings like like TAB or AE01.) We use the
   * 'names' part of the keyboard description to map keycode to key name.
   *
   * XKB has a "key aliases" feature where a single keyboard key can have
   * multiple names (with separate sets of aliases in the 'names' part and
   * in the 'geometry' part), but I don't really understand it or how it is used,
   * so I'm ignoring it here.
   */

  tab_name = keyboard->names->keys[tab_keycode].name; /* Not NULL terminated! */

  /* First, iterate through the keyboard geometry to find the tab key; the keyboard
   * geometry has a three-level heirarchy of section > row > key
   */
  for (i = 0; i < geometry->num_sections; i++)
    {
      XkbSectionPtr section = &geometry->sections[i];
      for (j = 0; j < section->num_rows; j++)
        {
          int x = 0;
          int y = 0;

          XkbRowPtr row = &section->rows[j];
          for (k = 0; k < row->num_keys; k++)
            {
              XkbKeyPtr key = &row->keys[k];
              XkbShapePtr shape = XkbKeyShape (geometry, key);

              if (row->vertical)
                y += key->gap;
              else
                x += key->gap;

              if (strncmp (key->name.name, tab_name, XkbKeyNameLength) == 0)
                {
                  tab_section = section;
                  tab_bounds = shape->bounds;
                  tab_bounds.x1 += row->left + x;
                  tab_bounds.x2 += row->left + x;
                  tab_bounds.y1 += row->top + y;
                  tab_bounds.y2 += row->top + y;

                  goto found_tab;
                }

              if (row->vertical)
                y += (shape->bounds.y2 - shape->bounds.y1);
              else
                x += (shape->bounds.x2 - shape->bounds.x1);
            }
        }
    }

  /* No tab key found */
  goto out;

 found_tab:

  /* Now find the key that:
   *  - Is in the same section as the Tab key
   *  - Has a horizontal center in the Tab key's horizonal bounds
   *  - Is above the Tab key at a distance closer than any other key
   *  - In case of ties, has its horizontal center as close as possible
   *    to the Tab key's horizontal center
   */
  for (j = 0; j < tab_section->num_rows; j++)
    {
      int x = 0;
      int y = 0;

      XkbRowPtr row = &tab_section->rows[j];
      for (k = 0; k < row->num_keys; k++)
        {
          XkbKeyPtr key = &row->keys[k];
          XkbShapePtr shape = XkbKeyShape(geometry, key);
          XkbBoundsRec bounds = shape->bounds;
          int x_center;
          int x_dist, y_dist;

          if (row->vertical)
            y += key->gap;
          else
            x += key->gap;

          bounds.x1 += row->left + x;
          bounds.x2 += row->left + x;
          bounds.y1 += row->top + y;
          bounds.y2 += row->top + y;

          y_dist = tab_bounds.y1 - bounds.y2;
          if (y_dist < 0)
            continue;

          x_center = (bounds.x1 + bounds.x2) / 2;
          if (x_center < tab_bounds.x1 || x_center > tab_bounds.x2)
            continue;

          x_dist = ABS (x_center - (tab_bounds.x1 + tab_bounds.x2) / 2);

          if (y_dist < best_y_dist ||
              (y_dist == best_y_dist && x_dist < best_x_dist))
            {
              best_key = key;
              best_x_dist = x_dist;
              best_y_dist = y_dist;
             }

          if (row->vertical)
            y += (shape->bounds.y2 - shape->bounds.y1);
          else
            x += (shape->bounds.x2 - shape->bounds.x1);
        }
    }

  if (best_key == NULL)
    goto out;

  /* Now we need to resolve the name of the best key back to a keycode */
  for (i = keyboard->min_key_code; i < keyboard->max_key_code; i++)
    {
      if (strncmp (best_key->name.name, keyboard->names->keys[i].name, XkbKeyNameLength) == 0)
        {
          best_keycode = i;
          break;
        }
    }

 out:
  XkbFreeKeyboard (keyboard, 0, True);

  return best_keycode;
}