Exemple #1
0
int
read_key (KeySym *keysym, unsigned int *modifiers, char *keysym_name, int len)
{
  XEvent ev;
  int nbytes;

  /* Read a key from the keyboard. */
  do
    {
      XMaskEvent (dpy, KeyPressMask|KeyRelease, &ev);
      *modifiers = ev.xkey.state;
      nbytes = cook_keycode (&ev.xkey, keysym, modifiers, keysym_name, len, 0);
    } while (IsModifierKey (*keysym) || ev.xkey.type == KeyRelease);

  return nbytes;
}
Exemple #2
0
bool wxGetKeyState(wxKeyCode key)
{
    wxASSERT_MSG(key != WXK_LBUTTON && key != WXK_RBUTTON && key !=
        WXK_MBUTTON, wxT("can't use wxGetKeyState() for mouse buttons"));

    Display *pDisplay = (Display*) wxGetDisplay();

    int iKey = wxCharCodeWXToX(key);
    int          iKeyMask = 0;
    Window       wDummy1, wDummy2;
    int          iDummy3, iDummy4, iDummy5, iDummy6;
    unsigned int iMask;
    KeyCode keyCode = XKeysymToKeycode(pDisplay,iKey);
    if (keyCode == NoSymbol)
        return false;

    if ( IsModifierKey(iKey) )  // If iKey is a modifier key, use a different method
    {
        XModifierKeymap *map = XGetModifierMapping(pDisplay);
        wxCHECK_MSG( map, false, wxT("failed to get X11 modifiers map") );

        for (int i = 0; i < 8; ++i)
        {
            if ( map->modifiermap[map->max_keypermod * i] == keyCode)
            {
                iKeyMask = 1 << i;
            }
        }

        XQueryPointer(pDisplay, DefaultRootWindow(pDisplay), &wDummy1, &wDummy2,
                        &iDummy3, &iDummy4, &iDummy5, &iDummy6, &iMask );
        XFreeModifiermap(map);
        return (iMask & iKeyMask) != 0;
    }

    // From the XLib manual:
    // The XQueryKeymap() function returns a bit vector for the logical state of the keyboard,
    // where each bit set to 1 indicates that the corresponding key is currently pressed down.
    // The vector is represented as 32 bytes. Byte N (from 0) contains the bits for keys 8N to 8N + 7
    // with the least-significant bit in the byte representing key 8N.
    char key_vector[32];
    XQueryKeymap(pDisplay, key_vector);
    return key_vector[keyCode >> 3] & (1 << (keyCode & 7));
}
bool UINativeHotKey::isValidKey(int iKeyCode)
{
#ifdef Q_WS_WIN
    return ((iKeyCode >= VK_SHIFT && iKeyCode <= VK_CAPITAL) ||
            (iKeyCode >= VK_LSHIFT && iKeyCode <= VK_RMENU) ||
            (iKeyCode >= VK_F1 && iKeyCode <= VK_F24) ||
            iKeyCode == VK_NUMLOCK || iKeyCode == VK_SCROLL ||
            iKeyCode == VK_LWIN || iKeyCode == VK_RWIN ||
            iKeyCode == VK_APPS ||
            iKeyCode == VK_PRINT);
#endif /* Q_WS_WIN */

#ifdef Q_WS_X11
    return (IsModifierKey(iKeyCode) /* allow modifiers */ ||
            IsFunctionKey(iKeyCode) /* allow function keys */ ||
            IsMiscFunctionKey(iKeyCode) /* allow miscellaneous function keys */ ||
            iKeyCode == XK_Scroll_Lock /* allow 'Scroll Lock' missed in IsModifierKey() */) &&
           (iKeyCode != NoSymbol /* ignore some special symbol */ &&
            iKeyCode != XK_Insert /* ignore 'insert' included into IsMiscFunctionKey */);
#endif /* Q_WS_X11 */

#ifdef Q_WS_MAC
    UInt32 modMask = ::DarwinKeyCodeToDarwinModifierMask(iKeyCode);
    switch (modMask)
    {
        case shiftKey:
        case optionKey:
        case controlKey:
        case rightShiftKey:
        case rightOptionKey:
        case rightControlKey:
        case cmdKey:
        case kEventKeyModifierRightCmdKeyMask:
            return true;
        default:
            return false;
    }
#endif /* Q_WS_MAC */

    return false;
}
Exemple #4
0
static int
handleKey(unsigned int xkeysym, unsigned int xkeystate, int is_push,
		     IMUIMContext *uic)
{
    DefTree *p;
    DefTree *m_top = uic->compose->m_top;
    DefTree *m_context = uic->compose->m_context;

    if ((is_push == 0)  || m_top == NULL)
	return 0;

    if (IsModifierKey(xkeysym))
	return 0;

    for (p = m_context; p ; p = p->next) {
	if (((xkeystate & p->modifier_mask) == p->modifier) &&
		(xkeysym == p->keysym)) {
	    break;
	}
    }

    if (p) { /* Matched */
	if (p->succession) { /* Intermediate */
	    uic->compose->m_context = p->succession;
	    return 1;
	} else { /* Terminate (reached to leaf) */
	    uic->compose->m_composed = p;
	    /* commit string here */
	    im_uim_commit_string(uic, uic->compose->m_composed->utf8);
	    /* initialize internal state for next key sequence */
	    uic->compose->m_context = m_top;
	    return 1;
	}
    } else { /* Unmatched */
	if (m_context == m_top)
	    return 0;
	/* Error (Sequence Unmatch occurred) */
	uic->compose->m_context = m_top;
	return 1;
    }
}
Exemple #5
0
bool Compose::handleKey(KeySym xkeysym, int xkeystate, bool is_push)
{
    DefTree *p;

    if ((is_push == false)  || m_top == NULL)
	return false;

    if (IsModifierKey(xkeysym))
	return false;

    for (p = m_context; p ; p = p->next) {
	if (((xkeystate & p->modifier_mask) == p->modifier) &&
		(xkeysym == p->keysym)) {
	    break;
	}
    }

    if (p) { // Matched
	if (p->succession) { // Intermediate
	    m_context = p->succession;
	    return true;
	} else { // Terminate (reached to leaf)
	    m_composed = p;
	    // commit string here
	    m_xic->commit_string(m_composed->utf8);
	    // initialize internal state for next key sequence
	    m_context = m_top;
	    return true;
	}
    } else { // Unmatched
	if (m_context == m_top)
	    return false;
	// Error (Sequence Unmatch occurred)
	m_context = m_top;
	return true;
    }
}
static gboolean accel_button_key_cb(GtkWidget *widget, GdkEventKey *event, gpointer userdata)
{
        char *accelerator;

        if(!accel_button_is_recording(GTK_BUTTON(widget))) {
                return FALSE;
        }
        if(event->type==GDK_KEY_RELEASE) {
                if(event->keyval==GDK_BackSpace || event->keyval==GDK_Escape || event->keyval==GDK_Delete) {
                        accel_button_set_label(GTK_BUTTON(widget));
                } else {
                        if(!IsModifierKey(event->keyval)) {
                                accelerator= gtk_accelerator_name(event->keyval, event->state);

                                gconf_client_set_string(ocha_gconf_get_client(),
                                                        OCHA_GCONF_ACCELERATOR_KEY,
                                                        accelerator,
                                                        NULL/*err*/);
                                g_free(accelerator);
                        }
                }
        }
        return TRUE;
 }
Exemple #7
0
/*
 * Process a keypress event
 *
 * Also appears in "main-x11.c".
 */
static void react_keypress(XKeyEvent *xev)
{
	int i, n, mc, ms, mo, mx;

	uint ks1;

	XKeyEvent *ev = (XKeyEvent*)(xev);

	KeySym ks;

	char buf[128];
	char msg[128];


	/* Check for "normal" keypresses */
	n = XLookupString(ev, buf, 125, &ks, NULL);

	/* Terminate */
	buf[n] = '\0';


	/* Hack -- Ignore "modifier keys" */
	if (IsModifierKey(ks)) return;


	/* Hack -- convert into an unsigned int */
	ks1 = (uint)(ks);

	/* Extract four "modifier flags" */
	mc = (ev->state & ControlMask) ? TRUE : FALSE;
	ms = (ev->state & ShiftMask) ? TRUE : FALSE;
	mo = (ev->state & Mod1Mask) ? TRUE : FALSE;
	mx = (ev->state & Mod2Mask) ? TRUE : FALSE;


	/* Normal keys with no modifiers */
	if (n && !mo && !mx && !IsSpecialKey(ks))
	{
		/* Enqueue the normal key(s) */
		for (i = 0; buf[i]; i++) Term_keypress(buf[i]);

		/* All done */
		return;
	}


	/* Handle a few standard keys (bypass modifiers) XXX XXX XXX */
	switch (ks1)
	{
		case XK_Escape:
		{
			Term_keypress(ESCAPE);
			return;
		}

		case XK_Return:
		{
			Term_keypress('\r');
			return;
		}

		case XK_Tab:
		{
			Term_keypress('\t');
			return;
		}

		case XK_Delete:
		case XK_BackSpace:
		{
			Term_keypress('\010');
			return;
		}
	}


	/* Hack -- Use the KeySym */
	if (ks)
	{
		sprintf(msg, "%c%s%s%s%s_%lX%c", 31,
		        mc ? "N" : "", ms ? "S" : "",
		        mo ? "O" : "", mx ? "M" : "",
		        (unsigned long)(ks), 13);
	}

	/* Hack -- Use the Keycode */
	else
	{
		sprintf(msg, "%c%s%s%s%sK_%X%c", 31,
		        mc ? "N" : "", ms ? "S" : "",
		        mo ? "O" : "", mx ? "M" : "",
		        ev->keycode, 13);
	}

	/* Enqueue the "macro trigger" string */
	for (i = 0; msg[i]; i++) Term_keypress(msg[i]);


	/* Hack -- auto-define macros as needed */
	if (n && (macro_find_exact(msg) < 0))
	{
		/* Create a macro */
		macro_add(msg, buf);
	}
}
Exemple #8
0
uni_t dpy_getchar(int timeout)
{
	while (numqueued == 0)
	{
		/* If a timeout was asked for, wait that long for an event. */

		if ((timeout != -1) && !XPending(display))
		{
			struct pollfd pfd =
			{
				.fd = ConnectionNumber(display),
				.events = POLLIN,
				.revents = 0
			};

			poll(&pfd, 1, timeout*1000);
			if (!pfd.revents)
				return -VK_TIMEOUT;
		}

		XEvent e;
		XNextEvent(display, &e);

		if (XFilterEvent(&e, window))
			continue;

		switch (e.type)
		{
			case MapNotify:
				break;

			case Expose:
			{
				/* Mark some of the screen as needing redrawing. */

				if (frontbuffer)
				{
					for (int y=0; y<screenheight; y++)
					{
						unsigned int* p = &frontbuffer[y * screenwidth];
						for (int x=0; x<screenwidth; x++)
							p[x] = 0;
					}
				}
				redraw();
				break;
			}

			case ConfigureNotify:
			{
				XConfigureEvent* xce = &e.xconfigure;
				int w = xce->width / fontwidth;
				int h = xce->height / fontheight;

				if ((w != screenwidth) || (h != screenheight))
				{
					screenwidth = w;
					screenheight = h;

					if (frontbuffer)
						free(frontbuffer);
					frontbuffer = NULL;
					if (backbuffer)
						free(backbuffer);
					backbuffer = calloc(screenwidth * screenheight, sizeof(unsigned int));
					push_key(-VK_RESIZE);
				}

				break;
			}

			case MappingNotify:
			case KeymapNotify:
				XRefreshKeyboardMapping(&e.xmapping);
				break;

			case KeyPress:
			{
				XKeyPressedEvent* xke = &e.xkey;
				KeySym keysym;
				char buffer[32];
				Status status = 0;
                int charcount = Xutf8LookupString(xic, xke,
					buffer, sizeof(buffer)-1, &keysym, &status);

				int mods = 0;
				if (xke->state & ShiftMask)
					mods |= VKM_SHIFT;
				if (xke->state & ControlMask)
					mods |= VKM_CTRL;

				if ((keysym & 0xffffff00) == 0xff00)
				{
					/* Special function key. */
					if (!IsModifierKey(keysym))
						push_key(-(keysym | mods));
				}
				else
				{
					const char* p = buffer;

					while ((p-buffer) < charcount)
					{
						uni_t c = readu8(&p);

						if (c < 32)
						{
							/* Ctrl + letter key */
							push_key(-(VKM_CTRLASCII | c | mods));
						}
						else
						{
							if (xke->state & Mod1Mask)
								push_key(-XK_Escape);
							push_key(c);
						}
					}
				}
				break;
			}
		}
	}

	return dequeue();
}

const char* dpy_getkeyname(uni_t k)
{
	static char buffer[32];

	switch (-k)
	{
		case VK_RESIZE:      return "KEY_RESIZE";
		case VK_TIMEOUT:     return "KEY_TIMEOUT";
		case VK_REDRAW:      return "KEY_REDRAW";
	}

	int key = -k & ~VKM__MASK;
	int mods = -k & VKM__MASK;

	if (mods & VKM_CTRLASCII)
	{
		sprintf(buffer, "KEY_%s^%c",
				(mods & VKM_SHIFT) ? "S" : "",
				key + 64);
		return buffer;
	}

	const char* template = NULL;
BOOLEAN CSoftHIDInputKbdMapper::GenInputReport(
                USHORT usUsageID, USHORT usFlag)
/*++
Routine Description:
    Generates new input report based on new keyboard event

Synchronization: 
    None
 
Arguments:
    usUsageID - HID Usage ID of key pressed/released.
    usFlag - Flag that specifies whether key was pressed or released.
    
Return Value:
    TRUE
        Success
    FALSE
        Could not generate new input report
--*/
{
    BOOLEAN fRet = TRUE;

    // Treat modifier keys separately
    if (IsModifierKey(usUsageID))
    {
        if (KEY_MAKE == (usFlag & KEY_MAKE)) {
            // Set modifier key
            m_InputReport.bModifier |= XlateModifierKey(usUsageID);
        }
        else {
            // Clear modifier key
            m_InputReport.bModifier &= ~XlateModifierKey(usUsageID);
        }
    }
    // Regular keys write to the array
    else
    {
        // New key was pressed: add it to the array
        if (KEY_MAKE == (usFlag & KEY_MAKE))
        {
            if (m_bKeySeqLen < MAX_KEYSEQ) {
                // This keyboard supports only one-byte Usage IDs
                m_InputReport.bUsageID[m_bKeySeqLen++] = (BYTE)usUsageID;
            }
            else
                fRet = FALSE;
        }
        // Old key was released: delete it from the array
        else
        {
            // Find key in the array
            for(BYTE i = 0; i < m_bKeySeqLen; i++)
            {
                if (m_InputReport.bUsageID[i] == usUsageID)
                {
                    // Delete key from the array
                    for(BYTE j = i; j < m_bKeySeqLen-1; j++) {
                        m_InputReport.bUsageID[j] = m_InputReport.bUsageID[j+1];
                    }
                    m_InputReport.bUsageID[--m_bKeySeqLen] = 0;
                    break;
                }
            }
        }
    }

    return fRet;

} // CSoftHIDInputKbdMapper::GenInputReport
Exemple #10
0
static void
Keyaction(Widget w, XEvent *e, String *p, Cardinal *np)
{
    static unsigned char compose[5];
    static int composing = -2;
    int kind = Kraw;

    int c, len, minmod;
    KeySym k, mk;
    Charfunc f;
    Modifiers md;
    char buf[100] = {0};

    c = 0;
    len = 0;

    /* Translate the keycode into a key symbol. */
    if(e->xany.type != KeyPress)
        return;
    XkbTranslateKeyCode(xkb, (KeyCode)e->xkey.keycode, e->xkey.state, &md, &k);
    XkbTranslateKeySym(e->xany.display, &k, e->xkey.state, buf, sizeof(buf) - 1, &len);

    /* Check to see if it's a specially-handled key first. */
    for (Keymapping *m = keymappings; m; m = m->next){
        KeySym u = NoSymbol;
        KeySym l = NoSymbol;
        XConvertCase(k, &l, &u);

        /* Note that magic bit manipulation here - we want to check that the
         * modifiers that are specified for the binding are all pressed, but
         * we allow other modifiers to be as well. This is because when NumLock
         * is on, it's always added to the modifier mask.
         */
        if (l == m->s || m->s == XK_VoidSymbol){
            if (m->m == 0 || (m->m & ~e->xkey.state) == 0){
                switch (m->c){
                    case Cnone:
                        return;

                    case Cdefault:
                        continue;

                    default:
                        f = ((GwinWidget)w)->gwin.gotchar;
                        if (f)
                            (*f)(m->c, m->k, Tcurrent, 0, 0, m->a);
                        return;
                }
            }
        }
    }

    /*
     * The following song and dance is so we can have our chosen
     * modifier key behave like a compose key, i.e, press and release
     * and then type the compose sequence, like Plan 9.  We have
     * to find out which key is the compose key first though.
     */
    if (IsModifierKey(k) && ((GwinWidget)w)->gwin.compose
            && composing == -2 && modmap) {
        minmod = (((GwinWidget)w)->gwin.compose+2)*keypermod;
        for (c = minmod; c < minmod+keypermod; c++) {
            XtTranslateKeycode(e->xany.display,
                    modmap->modifiermap[c],
                        e->xkey.state, &md, &mk);
            if (k == mk) {
                composing = -1;
                break;
            }
        }
        return;
    }

    /* Handle Multi_key separately, since it isn't a modifier */
    if(k == XK_Multi_key) {
        composing = -1;
        return;
    }

    if(k == NoSymbol || k > 0xff00)
        return;

    /* Check to see if we are in a composition sequence */
    if (!((GwinWidget)w)->gwin.compose && (e->xkey.state & Mod1Mask)
            && composing == -2)
        composing = -1;
    if (composing > -2) {
        compose[++composing] = k;
        if ((*compose == 'X') && (composing > 0)) {
            if ((k < '0') || (k > 'f') ||
                    ((k > '9') && (k < 'a'))) {
                STUFFCOMPOSE();
                c = (uint16_t)k;
                composing = -2;
            } else if (composing == 4) {
                c = unicode(compose);
                if (c == -1) {
                    STUFFCOMPOSE();
                    c = (uint16_t)compose[4];
                }
                composing = -2;
            }
        } else if (composing == 1) {
            c = (int)latin1(compose);
            if (c == -1) {
                STUFFCOMPOSE();
                c = (uint16_t)compose[1];
            }
            composing = -2;
        }
    } else {
        if (composing >= 0) {
            composing++;
            STUFFCOMPOSE();
        }
        c = keysymtoshort(k);
        composing = -2;
    }

    if (composing >= -1)
        return;

    f = ((GwinWidget)w)->gwin.gotchar;
    if(f)
        (*f)(c, kind, Tcurrent, 0, 0, NULL);
}
Exemple #11
0
/* ARGSUSED */
static void
InsertChar (
    Widget	ctxw,
    XEvent	*event,
    String	*params,
    Cardinal	*num_params)
{
    LoginWidget ctx = (LoginWidget)ctxw;

    char strbuf[128];
#ifndef XPM
    int  len;
#else
    int  len,pixels;
#endif /* XPM */
    KeySym  keysym = 0;

    if (ctx->login.xic) {
	static Status status;
	len = XmbLookupString(ctx->login.xic, &event->xkey, strbuf,
			      sizeof (strbuf), &keysym, &status);
    } else {
	static XComposeStatus compose_status = {NULL, 0};
	len = XLookupString (&event->xkey, strbuf, sizeof (strbuf),
			     &keysym, &compose_status);
    }
    strbuf[len] = '\0';

#ifdef XPM
    pixels = 3 + ctx->login.font->max_bounds.width * len +
    	     XTextWidth(ctx->login.font,
    	     		ctx->login.data.name,
    	     		strlen(ctx->login.data.name));
    	     	/* pixels to be added */
#endif /* XPM */

    /*
     * Note: You can override this default key handling
     * by the settings in the translation table
     * loginActionsTable at the end of this file.
     */
    switch (keysym) {
    case XK_Return:
    case XK_KP_Enter:
    case XK_Linefeed:
    case XK_Execute:
	FinishField(ctxw, event, params, num_params);
	return;
    case XK_BackSpace:
	DeleteBackwardChar(ctxw, event, params, num_params);
	return;
    case XK_Delete:
    case XK_KP_Delete:
    case DXK_Remove:
	/* Sorry, it's not a telex machine, it's a terminal */
	DeleteForwardChar(ctxw, event, params, num_params);
	return;
    case XK_Left:
    case XK_KP_Left:
	MoveBackwardChar(ctxw, event, params, num_params);
	return;
    case XK_Right:
    case XK_KP_Right:
	MoveForwardChar(ctxw, event, params, num_params);
	return;
    case XK_End:
    case XK_KP_End:
	MoveToEnd(ctxw, event, params, num_params);
	return;
    case XK_Home:
    case XK_KP_Home:
	MoveToBegining(ctxw, event, params, num_params);
	return;
    default:
	if (len == 0) {
	    if (!IsModifierKey(keysym))  /* it's not a modifier */
		XBell(XtDisplay(ctxw), 60);
	    return;
	} else
	    break;
    }

    switch (ctx->login.state) {
    case GET_NAME:
#ifndef XPM
	if (len + (int)strlen(ctx->login.data.name) >= NAME_LEN - 1)
#else
	if (
	        (len + (int)strlen(ctx->login.data.name) >= NAME_LEN - 1)/* &&
		(pixels <= LOGIN_W(ctx) - PROMPT_W(ctx))*/
	   )
#endif /* XPM */
	    len = NAME_LEN - strlen(ctx->login.data.name) - 2;
    case GET_PASSWD:
	if (len + (int)strlen(ctx->login.data.passwd) >= PASSWORD_LEN - 1)
	    len = PASSWORD_LEN - strlen(ctx->login.data.passwd) - 2;
    }
#ifndef XPM
    if (len == 0)
#else
    if (len == 0 || pixels >= LOGIN_W(ctx) - PROMPT_W(ctx))
#endif /* XPM */
	return;
    XorCursor (ctx);
    RemoveFail (ctx);
    switch (ctx->login.state) {
    case GET_NAME:
	EraseName (ctx, ctx->login.cursor);
	memmove( ctx->login.data.name + ctx->login.cursor + len,
	       ctx->login.data.name + ctx->login.cursor,
	       strlen (ctx->login.data.name + ctx->login.cursor) + 1);
	memmove( ctx->login.data.name + ctx->login.cursor, strbuf, len);
	DrawName (ctx, ctx->login.cursor);
	ctx->login.cursor += len;
	break;
    case GET_PASSWD:
	memmove( ctx->login.data.passwd + ctx->login.cursor + len,
	       ctx->login.data.passwd + ctx->login.cursor,
	       strlen (ctx->login.data.passwd + ctx->login.cursor) + 1);
	memmove( ctx->login.data.passwd + ctx->login.cursor, strbuf, len);
	ctx->login.cursor += len;

#ifdef XPM
	/*as good a place as any Caolan begin*/
	ctx->login.lastEventTime = time(NULL);
	/*as good a place as any Caolan end*/
#endif /* XPM */
	break;
    }
    XorCursor (ctx);
}
Exemple #12
0
static eventFilterStatus
clientCycleEventFilter (XfwmEvent *event, gpointer data)
{
    ScreenInfo *screen_info;
    DisplayInfo *display_info;
    ClientCycleData *passdata;
    Client *c, *removed;
    Client *c2 = NULL;
    eventFilterStatus status;
    KeyCode cancel, left, right, up, down;
    int key, modifiers;
    gboolean cycling;
    GList *li;

    TRACE ("entering");

    passdata = (ClientCycleData *) data;
    c = tabwinGetSelected(passdata->tabwin);
    if (c == NULL)
    {
        return EVENT_FILTER_CONTINUE;
    }

    screen_info = c->screen_info;
    display_info = screen_info->display_info;
    cancel = screen_info->params->keys[KEY_CANCEL].keycode;
    left = screen_info->params->keys[KEY_LEFT].keycode;
    right = screen_info->params->keys[KEY_RIGHT].keycode;
    up = screen_info->params->keys[KEY_UP].keycode;
    down = screen_info->params->keys[KEY_DOWN].keycode;
    modifiers = (screen_info->params->keys[KEY_CYCLE_WINDOWS].modifier |
                 screen_info->params->keys[KEY_CYCLE_REVERSE_WINDOWS].modifier);
    status = EVENT_FILTER_CONTINUE;
    removed = NULL;
    cycling = TRUE;

    /* Update the display time */
    myDisplayUpdateCurrentTime (display_info, event);

    switch (event->meta.type)
    {
        case XFWM_EVENT_KEY:
            if (event->key.pressed)
            {
                key = myScreenGetKeyPressed (screen_info, &event->key);
                /*
                 * We cannot simply check for key == KEY_CANCEL here because of the
                 * modidier being pressed, so we need to look at the keycode directly.
                 */
                if (event->key.keycode == cancel)
                {
                    c2 = tabwinSelectHead (passdata->tabwin);
                    cycling = FALSE;
                }
                else if (event->key.keycode == up)
                {
                    c2 = tabwinSelectDelta(passdata->tabwin, -1, 0);
                }
                else if (event->key.keycode == down)
                {
                    c2 = tabwinSelectDelta(passdata->tabwin, 1, 0);
                }
                else if (event->key.keycode == left)
                {
                    c2 = tabwinSelectDelta(passdata->tabwin, 0, -1);
                }
                else if (event->key.keycode == right)
                {
                    c2 = tabwinSelectDelta(passdata->tabwin, -0, 1);
                }
                else if (key == KEY_CYCLE_REVERSE_WINDOWS)
                {
                    TRACE ("cycle: previous");
                    c2 = tabwinSelectPrev(passdata->tabwin);
                }
                else if (key == KEY_CYCLE_WINDOWS)
                {
                    TRACE ("cycle: next");
                    c2 = tabwinSelectNext(passdata->tabwin);
                }
                if (c2)
                {
                    clientCycleUpdateWireframe (c2, passdata);
                }

                /* If last key press event had not our modifiers pressed, finish cycling */
                if (!(event->key.state & modifiers))
                {
                    cycling = FALSE;
                }
                status = EVENT_FILTER_STOP;
            }
            else
            {
                int keysym = XkbKeycodeToKeysym (event->meta.xevent->xany.display, event->key.keycode, 0, 0);

                if (IsModifierKey(keysym))
                {
                    if (!(myScreenGetModifierPressed (screen_info) & modifiers))
                    {
                        cycling = FALSE;
                    }
                }
            }
            status = EVENT_FILTER_STOP;
            break;
        case XFWM_EVENT_BUTTON:
            if (event->button.pressed)
            {
                /* only accept events for the tab windows */
                for (li = passdata->tabwin->tabwin_list; li != NULL; li = li->next)
                {
                    if (GDK_WINDOW_XID (gtk_widget_get_window (li->data)) == event->meta.window)
                    {
                        if  (event->button.button == Button1)
                        {
                            c2 = tabwinSelectHovered (passdata->tabwin);
                            cycling = FALSE;
                            break;
                        }
                        else if (event->button.button == Button4)
                        {
                            /* Mouse wheel scroll up */
                            TRACE ("cycle: previous");
                            c2 = tabwinSelectPrev(passdata->tabwin);
                        }
                        else if (event->button.button == Button5)
                        {
                            /* Mouse wheel scroll down */
                            TRACE ("cycle: next");
                            c2 = tabwinSelectNext(passdata->tabwin);
                        }
                    }
                    if (c2)
                    {
                        clientCycleUpdateWireframe (c2, passdata);
                    }
                }
            }
            status = EVENT_FILTER_STOP;
            break;
        case XFWM_EVENT_MOTION:
            break;
        case XFWM_EVENT_CROSSING:
            /* Track whether the pointer is inside one of the tab-windows */
            for (li = passdata->tabwin->tabwin_list; li != NULL; li = li->next)
            {
                if (GDK_WINDOW_XID (gtk_widget_get_window (li->data)) == event->meta.window)
                {
                    passdata->inside = event->crossing.enter;
                }
            }
            status = EVENT_FILTER_STOP;
            break;
        case XFWM_EVENT_XEVENT:
            switch (event->meta.xevent->type)
            {
                case DestroyNotify:
                    status = EVENT_FILTER_CONTINUE;
                    removed = myScreenGetClientFromWindow (screen_info,
                                                           ((XDestroyWindowEvent *) event->meta.xevent)->window,
                                                           SEARCH_WINDOW);
                    if (removed == NULL)
                    {
                        break; /* No need to go any further */
                    }
                    FALLTHROUGH;
                case UnmapNotify:
                    status = EVENT_FILTER_CONTINUE;
                    if (!removed)
                    {
                        removed = myScreenGetClientFromWindow (screen_info,
                                                               ((XUnmapEvent *) event->meta.xevent)->window,
                                                               SEARCH_WINDOW);
                        if (removed == NULL)
                        {
                            break; /* No need to go any further */
                        }
                    }
                    c = tabwinRemoveClient(passdata->tabwin, removed);
                    cycling = clientCycleUpdateWireframe (c, passdata);
                    break;
            }
            break;
    }

    if (!cycling)
    {
        TRACE ("event loop now finished");
        gtk_main_quit ();
    }

    return status;
}
Exemple #13
0
static eventFilterStatus
clientCycleEventFilter (XEvent * xevent, gpointer data)
{
    ScreenInfo *screen_info;
    DisplayInfo *display_info;
    ClientCycleData *passdata;
    Client *c, *removed;
    Client *c2 = NULL;
    eventFilterStatus status;
    KeyCode cancel, left, right, up, down;
    int key, modifiers;
    gboolean key_pressed, cycling, gone;
    GList *li;
    Window mouse_window = 0;
    XButtonEvent ev;

    TRACE ("entering clientCycleEventFilter");

    passdata = (ClientCycleData *) data;
    c = tabwinGetSelected(passdata->tabwin);
    if (c == NULL)
    {
        return EVENT_FILTER_CONTINUE;
    }

    screen_info = c->screen_info;
    display_info = screen_info->display_info;
    cancel = screen_info->params->keys[KEY_CANCEL].keycode;
    left = screen_info->params->keys[KEY_LEFT].keycode;
    right = screen_info->params->keys[KEY_RIGHT].keycode;
    up = screen_info->params->keys[KEY_UP].keycode;
    down = screen_info->params->keys[KEY_DOWN].keycode;
    modifiers = (screen_info->params->keys[KEY_CYCLE_WINDOWS].modifier |
                 screen_info->params->keys[KEY_CYCLE_REVERSE_WINDOWS].modifier);
    status = EVENT_FILTER_STOP;
    removed = NULL;
    cycling = TRUE;
    gone = FALSE;

    /* Update the display time */
    myDisplayUpdateCurrentTime (display_info, xevent);

    switch (xevent->type)
    {
        case DestroyNotify:
            status = EVENT_FILTER_CONTINUE;
            if ((removed = myScreenGetClientFromWindow (screen_info, ((XDestroyWindowEvent *) xevent)->window, SEARCH_WINDOW)) == NULL)
                break; /* No need to go any further */
            gone |= (c == removed);
            /* Walk through */
        case UnmapNotify:
            status = EVENT_FILTER_CONTINUE;
            if (!removed && (removed = myScreenGetClientFromWindow (screen_info, ((XUnmapEvent *) xevent)->window, SEARCH_WINDOW)) == NULL)
                break; /* No need to go any further */
            gone |= (c == removed);
            c = tabwinRemoveClient(passdata->tabwin, removed);
            /* Walk through */
        case KeyPress:
            key_pressed = (xevent->type == KeyPress);
            if (gone || key_pressed)
            {
                if (key_pressed)
                {
                    key = myScreenGetKeyPressed (screen_info, (XKeyEvent *) xevent);
                    /*
                     * We cannot simply check for key == KEY_CANCEL here because of the
                     * modidier being pressed, so we need to look at the keycode directly.
                     */
                    if (xevent->xkey.keycode == cancel)
                    {
                        c2 = tabwinSelectHead (passdata->tabwin);
                        cycling = FALSE;
                    }
                    else if (xevent->xkey.keycode == up)
                    {
                        c2 = tabwinSelectDelta(passdata->tabwin, -1, 0);
                    }
                    else if (xevent->xkey.keycode == down)
                    {
                        c2 = tabwinSelectDelta(passdata->tabwin, 1, 0);
                    }
                    else if (xevent->xkey.keycode == left)
                    {
                        c2 = tabwinSelectDelta(passdata->tabwin, 0, -1);
                    }
                    else if (xevent->xkey.keycode == right)
                    {
                        c2 = tabwinSelectDelta(passdata->tabwin, -0, 1);
                    }
                    else if (key == KEY_CYCLE_REVERSE_WINDOWS)
                    {
                        TRACE ("Cycle: previous");
                        c2 = tabwinSelectPrev(passdata->tabwin);
                    }
                    else if (key == KEY_CYCLE_WINDOWS)
                    {
                        TRACE ("Cycle: next");
                        c2 = tabwinSelectNext(passdata->tabwin);
                    }
                    if (c2)
                    {
                        c = c2;
                    }

                    /* If last key press event had not our modifiers pressed, finish cycling */
                    if (!(xevent->xkey.state & modifiers))
                    {
                        cycling = FALSE;
                    }
                }
            }
            break;
        case KeyRelease:
            {
                int keysym = XLookupKeysym (&xevent->xkey, 0);

                if (IsModifierKey(keysym))
                {
                    if (!(myScreenGetModifierPressed (screen_info) & modifiers))
                    {
                        cycling = FALSE;
                    }
                }
            }
            break;
        case ButtonPress:
            status = EVENT_FILTER_STOP;
            ev = xevent->xbutton;
            /* window of the event, we might accept it later */
            mouse_window = xevent->xbutton.window;
            if (mouse_window != 0)
            {
                /* only accept events for the tab windows */
                for (li = passdata->tabwin->tabwin_list; li != NULL; li = li->next)
                {
                    if (GDK_WINDOW_XID (gtk_widget_get_window (li->data)) == mouse_window)
                    {
                        if  (ev.button == Button1)
                        {
                            cycling = FALSE;
                            c = tabwinSelectHoveredWidget (passdata->tabwin);
                            break;
                        }
                        else if  (ev.button == Button4)
                        {
                            /* Mouse wheel scroll up */
                            TRACE ("Cycle: previous");
                            c2 = tabwinSelectPrev(passdata->tabwin);
                        }
                        else if (ev.button == Button5)
                        {
                            /* Mouse wheel scroll down */
                            TRACE ("Cycle: next");
                            c2 = tabwinSelectNext(passdata->tabwin);
                        }
                    }
                }
                if (c2)
                {
                    c = c2;
                }
            }
            break;
        default:
            status = EVENT_FILTER_CONTINUE;
            break;
    }

    if (!cycling)
    {
        TRACE ("event loop now finished");
        gtk_main_quit ();
    }

    if (status == EVENT_FILTER_STOP)
    {
        if (cycling)
        {
            if (c)
            {
                if (passdata->wireframe)
                {
                    wireframeUpdate (c, passdata->wireframe);
                }
            }
            else
            {
                cycling = FALSE;
            }
        }
    }

    return status;
}
Exemple #14
0
static void
Keyaction(Widget w, XEvent *e, String *p, Cardinal *np)
{
	static unsigned char compose[5];
	static int composing = -2;
    int composed = 0;

	int c, minmod;
	KeySym k, mk;
	Charfunc f;
	Modifiers md;

	/*
	 * I tried using XtGetActionKeysym, but it didn't seem to
	 * do case conversion properly
	 * (at least, with Xterminal servers and R4 intrinsics)
	 */
	if(e->xany.type != KeyPress)
		return;
	XtTranslateKeycode(e->xany.display, (KeyCode)e->xkey.keycode,
		        e->xkey.state, &md, &k);
	/*
	 * The following song and dance is so we can have our chosen
	 * modifier key behave like a compose key, i.e, press and release
	 * and then type the compose sequence, like Plan 9.  We have
	 * to find out which key is the compose key first 'though.
	 */
	if (IsModifierKey(k) && ((GwinWidget)w)->gwin.compose
			&& composing == -2 && modmap) {
		minmod = (((GwinWidget)w)->gwin.compose+2)*keypermod;
		for (c = minmod; c < minmod+keypermod; c++) {
			XtTranslateKeycode(e->xany.display,
					modmap->modifiermap[c],
	        			e->xkey.state, &md, &mk);
			if (k == mk) {
				composing = -1;
				break;
			}
		}
		return;
	}
	/* Handle Multi_key separately, since it isn't a modifier */
	if(k == XK_Multi_key) {
		composing = -1;
		return;
	}
	if(k == NoSymbol)
		return;
	if(k&0xFF00){
		switch(k){
		case XK_BackSpace:
		case XK_Tab:
		case XK_Escape:
		case XK_Delete:
		case XK_KP_0:
		case XK_KP_1:
		case XK_KP_2:
		case XK_KP_3:
		case XK_KP_4:
		case XK_KP_5:
		case XK_KP_6:
		case XK_KP_7:
		case XK_KP_8:
		case XK_KP_9:
		case XK_KP_Divide:
		case XK_KP_Multiply:
		case XK_KP_Subtract:
		case XK_KP_Add:
		case XK_KP_Decimal:
			k &= 0x7F;
			break;
		case XK_Linefeed:
			k = '\r';
			break;
		case XK_KP_Enter:
		case XK_Return:
			k = '\n';
			break;
		case XK_Left:
		case XK_Down:
		case XK_Right:
		case XK_Next:
			k = 0x80; /* VIEW -- "Scroll" */
			break;
		case XK_Up:
		case XK_Prior:
			k = 0x81; /* PREVIEW -- "Scroll back" */
			break;
		default:
			return;	/* not ISO-1 or tty control */
		}
	}
	/* Compensate for servers that call a minus a hyphen */
	if(k == XK_hyphen)
		k = XK_minus;
	/* Do control mapping ourselves if translator doesn't */
	if((e->xkey.state&ControlMask) && !(md&ControlMask))
		k &= 0x9f;
	if(k == NoSymbol)
		return;
	/* Check to see if we are in a composition sequence */
	if (!((GwinWidget)w)->gwin.compose && (e->xkey.state & Mod1Mask)
			&& composing == -2)
		composing = -1;
	if (composing > -2) {
		compose[++composing] = k;
		if ((*compose == 'X') && (composing > 0)) {
			if ((k < '0') || (k > 'f') ||
					((k > '9') && (k < 'a'))) {
				STUFFCOMPOSE();
				c = (unsigned short)k;
				composing = -2;
			} else if (composing == 4) {
				c = unicode(compose);
				if (c == -1) {
					STUFFCOMPOSE();
					c = (unsigned short)compose[4];
				} else
                    composed = 1;
				composing = -2;
			}
		} else if (composing == 1) {
			c = (int)latin1(compose);
			if (c == -1) {
				STUFFCOMPOSE();
				c = (unsigned short)compose[1];
			} else
                composed = 1;
			composing = -2;
		}
	} else {
		if (composing >= 0) {
			composing++;
			STUFFCOMPOSE();
		}
		c = (unsigned short)k;
		composing = -2;
	}

	if (composing >= -1)
		return;

	f = ((GwinWidget)w)->gwin.gotchar;
	if(f)
		(*f)(c, composed);
}