Exemplo n.º 1
0
// Convert gdk key event keyvals to char codes if printable, 0 otherwise
PRUint32 nsConvertCharCodeToUnicode(GdkEventKey* aEvent)
{
    // Anything above 0xf000 is considered a non-printable
    // Exception: directly encoded UCS characters
    if (aEvent->keyval > 0xf000 && (aEvent->keyval & 0xff000000) != 0x01000000) {

        // Keypad keys are an exception: they return a value different
        // from their non-keypad equivalents, but mozilla doesn't distinguish.
        switch (aEvent->keyval)
            {
            case GDK_KP_Space:
                return ' ';
            case GDK_KP_Equal:
                return '=';
            case GDK_KP_Multiply:
                return '*';
            case GDK_KP_Add:
                return '+';
            case GDK_KP_Separator:
                return ',';
            case GDK_KP_Subtract:
                return '-';
            case GDK_KP_Decimal:
                return '.';
            case GDK_KP_Divide:
                return '/';
            case GDK_KP_0:
                return '0';
            case GDK_KP_1:
                return '1';
            case GDK_KP_2:
                return '2';
            case GDK_KP_3:
                return '3';
            case GDK_KP_4:
                return '4';
            case GDK_KP_5:
                return '5';
            case GDK_KP_6:
                return '6';
            case GDK_KP_7:
                return '7';
            case GDK_KP_8:
                return '8';
            case GDK_KP_9:
                return '9';
            }

        // non-printables
        return 0;
    }

    // we're supposedly printable, let's try to convert
    long ucs = keysym2ucs(aEvent->keyval);
    if ((ucs != -1) && (ucs < MAX_UNICODE))
        return ucs;

    // I guess we couldn't convert
    return 0;
}
Exemplo n.º 2
0
void SkOSWindow::loop() {
    Display* dsp = fUnixWindow.fDisplay;
    if (NULL == dsp) {
        return;
    }
    XSelectInput(dsp, fUnixWindow.fWin, EVENT_MASK);

    bool loop = true;
    XEvent evt;
    while (loop) {
        XNextEvent(dsp, &evt);
        switch (evt.type) {
            case Expose:
                if (evt.xexpose.count == 0)
                    this->inval(NULL);
                break;
            case ConfigureNotify:
                this->resize(evt.xconfigure.width, evt.xconfigure.height);
                break;
            case ButtonPress:
                if (evt.xbutton.button == Button1)
                    this->handleClick(evt.xbutton.x, evt.xbutton.y, SkView::Click::kDown_State);
                break;
            case ButtonRelease:
                if (evt.xbutton.button == Button1)
                    this->handleClick(evt.xbutton.x, evt.xbutton.y, SkView::Click::kUp_State);
                break;
            case MotionNotify:
                this->handleClick(evt.xmotion.x, evt.xmotion.y, SkView::Click::kMoved_State);
                break;
            case KeyPress: {
                KeySym keysym = XkbKeycodeToKeysym(dsp, evt.xkey.keycode, 0, 0);
                //SkDebugf("pressed key %i!\n\tKeySym:%i\n", evt.xkey.keycode, XKeycodeToKeysym(dsp, evt.xkey.keycode, 0));
                if (keysym == XK_Escape) {
                    loop = false;
                    break;
                }
                this->handleKey(XKeyToSkKey(keysym));
                long uni = keysym2ucs(keysym);
                if (uni != -1) {
                    this->handleChar((SkUnichar) uni);
                }
                break;
            }
            case KeyRelease:
                //SkDebugf("released key %i\n", evt.xkey.keycode);
                this->handleKeyUp(XKeyToSkKey(XkbKeycodeToKeysym(dsp, evt.xkey.keycode, 0, 0)));
                break;
            case ClientMessage:
                if (SkEvent::ProcessEvent()) {
                    this->post_linuxevent();
                }
                break;
            default:
                // Do nothing for other events
                break;
        }
    }
}
Exemplo n.º 3
0
SkOSWindow::NextXEventResult SkOSWindow::nextXEvent() {
    XEvent evt;
    Display* dsp = fUnixWindow.fDisplay;

    if (!MyXNextEventWithDelay(dsp, &evt)) {
        return kContinue_NextXEventResult;
    }

    switch (evt.type) {
        case Expose:
            if (0 == evt.xexpose.count) {
                return kPaintRequest_NextXEventResult;
            }
            break;
        case ConfigureNotify:
            this->resize(evt.xconfigure.width, evt.xconfigure.height);
            break;
        case ButtonPress:
            if (evt.xbutton.button == Button1)
                this->handleClick(evt.xbutton.x, evt.xbutton.y,
                            SkView::Click::kDown_State, NULL, getModi(evt));
            break;
        case ButtonRelease:
            if (evt.xbutton.button == Button1)
                this->handleClick(evt.xbutton.x, evt.xbutton.y,
                              SkView::Click::kUp_State, NULL, getModi(evt));
            break;
        case MotionNotify:
            this->handleClick(evt.xmotion.x, evt.xmotion.y,
                           SkView::Click::kMoved_State, NULL, getModi(evt));
            break;
        case KeyPress: {
            int shiftLevel = (evt.xkey.state & ShiftMask) ? 1 : 0;
            KeySym keysym = XkbKeycodeToKeysym(dsp, evt.xkey.keycode,
                                               0, shiftLevel);
            if (keysym == XK_Escape) {
                return kQuitRequest_NextXEventResult;
            }
            this->handleKey(XKeyToSkKey(keysym));
            long uni = keysym2ucs(keysym);
            if (uni != -1) {
                this->handleChar((SkUnichar) uni);
            }
            break;
        }
        case KeyRelease:
            this->handleKeyUp(XKeyToSkKey(XkbKeycodeToKeysym(dsp, evt.xkey.keycode, 0, 0)));
            break;
        case ClientMessage:
            if ((Atom)evt.xclient.data.l[0] == wm_delete_window_message) {
                return kQuitRequest_NextXEventResult;
            }
            // fallthrough
        default:
            // Do nothing for other events
            break;
    }
    return kContinue_NextXEventResult;
}
Exemplo n.º 4
0
QString KeySymHelper::getKeySymbol(const QString &opton)
{
    if (keySymbolMap.contains(opton)) {
        return keySymbolMap[opton];
    }

    const char *str = opton.toAscii().data();

#if 0
    //TODO: figure out how to use this so we don't need our own symkey2ucs mapping
    int res = Xutf8LookupString(XIC ic, XKeyPressedEvent * event, char *buffer_return, int bytes_buffer, KeySym * keysym_return, Status * status_return);

#else

    KeySym keysym = XStringToKeysym(str);

    //TODO: make it more generic
//    if( keysym == 0xfe03 )
//  return "L3";

    long ucs = keysym2ucs(keysym);

//    if( ucs == -1 && (keysym >= 0xFE50 && keysym <= 0xFE5F) ) {
//        ucs = 0x0300 + (keysym & 0x000F);
//        qWarning() << "Got dead symbol" << QString("0x%1").arg(keysym, 0, 16) << "named" << opton << "will use" << QString("0x%1").arg(ucs, 0, 16) << "as UCS";
//    }

    if (ucs == -1) {
        nill++;
        qWarning() << "No mapping from keysym:" << QStringLiteral("0x%1").arg(keysym, 0, 16) << "named:" << opton << "to UCS";
    }

    QString ucsStr = QString(QChar((int)ucs));

    // Combining Diacritical Marks
    if (ucs >= 0x0300 && ucs <= 0x036F) {
        ucsStr = " " + ucsStr + " ";
    }

//    qWarning() << "--" << opton << "keysym: " << keysym << QString("0x%1").arg(keysym, 0, 16) << "keysym2string" << XKeysymToString(keysym)
//         << "---" << QString("0x%1").arg(ucs, 0, 16) << ucsStr;

    keySymbolMap[opton] = ucsStr;

    return ucsStr;

#endif

}
Exemplo n.º 5
0
static void handle_key(XGenericEventCookie *cookie)
{
	XIDeviceEvent *ev = (XIDeviceEvent *)cookie->data;
	qboolean down = cookie->evtype == XI_KeyPress;
	int keycode = ev->detail;
	unsigned time = Sys_XTimeToSysTime(ev->time);

	// Ignore shift_level for game key press
	KeySym keysym = XkbKeycodeToKeysym(x11display.dpy, keycode, 0, 0);
	int key = XLateKey( keysym );

	// Set or clear 1 in the shift_level bitmask
	if ( keysym == XK_Shift_L || keysym == XK_Shift_R )
		shift_level ^=  (-down ^ shift_level) & 1;

	// Set or clear 2 in the shift_level bitmask
	else if( keysym == XK_ISO_Level3_Shift )
		shift_level ^=  (-down ^ shift_level) & 2;

	Key_Event(key, down, time);

	if( down )
	{
		// Use shift_level for chat and console input
		qwchar wc = keysym2ucs(XkbKeycodeToKeysym(x11display.dpy, keycode, 0, shift_level));
		if( wc == -1 && key > K_NUMLOCK && key <= KP_EQUAL )
			wc = ( qwchar )key;

		// Convert ctrl-c / ctrl-v combinations to the expected events
		if( Key_IsDown(K_LCTRL) || Key_IsDown(K_RCTRL) )
		{
			if( key == 'v' )
			{
				key = CTRLV;
				wc = CTRLV;
			}
			else if( key == 'c' )
			{
				key = CTRLC;
				wc = CTRLC;
			}
		}
		Key_CharEvent( key, wc );
	}
}
Exemplo n.º 6
0
static void DP_Xutf8LookupString(XKeyEvent * ev,
			 Uchar *uch,
			 KeySym * keysym_return,
			 Status * status_return)
{
	int rc;
	KeySym keysym;
	int codepoint;
	char buffer[64];
	int nbytes = sizeof(buffer);

	rc = XLookupString(ev, buffer, nbytes, &keysym, NULL);

	if (rc > 0) {
		codepoint = buffer[0] & 0xFF;
	} else {
		codepoint = keysym2ucs(keysym);
	}

	if (codepoint < 0) {
		if (keysym == None) {
			*status_return = XLookupNone;
		} else {
			*status_return = XLookupKeySym;
			*keysym_return = keysym;
		}
		*uch = 0;
		return;
	}

	*uch = codepoint;

	if (keysym != None) {
		*keysym_return = keysym;
		*status_return = XLookupBoth;
	} else {
		*status_return = XLookupChars;
	}
}
Exemplo n.º 7
0
bool Window_mac::handleEvent(const XEvent& event) {
    switch (event.type) {
        case MapNotify:
            if (!fGC) {
                fGC = XCreateGC(fDisplay, fWindow, 0, nullptr);
            }
            break;

        case ClientMessage:
            if ((Atom)event.xclient.data.l[0] == fWmDeleteMessage &&
                gWindowMap.count() == 1) {
                return true;
            }
            break;

        case ButtonPress:
            if (event.xbutton.button == Button1) {
                this->onMouse(event.xbutton.x, event.xbutton.y,
                              Window::kDown_InputState, get_modifiers(event));
            }
            break;

        case ButtonRelease:
            if (event.xbutton.button == Button1) {
                this->onMouse(event.xbutton.x, event.xbutton.y,
                              Window::kUp_InputState, get_modifiers(event));
            }
            break;

        case MotionNotify:
            // only track if left button is down
            if (event.xmotion.state & Button1Mask) {
                this->onMouse(event.xmotion.x, event.xmotion.y, 
                              Window::kMove_InputState, get_modifiers(event));
            }
            break;

        case KeyPress: {
            int shiftLevel = (event.xkey.state & ShiftMask) ? 1 : 0;
            KeySym keysym = XkbKeycodeToKeysym(fDisplay, event.xkey.keycode,
                                               0, shiftLevel);
            if (keysym == XK_Escape) {
                return true;
            }
            Window::Key key = get_key(keysym);
            if (key != Window::Key::kNONE) {
                (void) this->onKey(key, Window::kDown_InputState, 
                                   get_modifiers(event));
            } else {
                long uni = keysym2ucs(keysym);
                if (uni != -1) {
                    (void) this->onChar((SkUnichar) uni, 
                                        get_modifiers(event));
                }
            }
        } break;

        case KeyRelease: {
            int shiftLevel = (event.xkey.state & ShiftMask) ? 1 : 0;
            KeySym keysym = XkbKeycodeToKeysym(fDisplay, event.xkey.keycode,
                                               0, shiftLevel);
            Window::Key key = get_key(keysym);
            (void) this->onKey(key, Window::kUp_InputState, 
                               get_modifiers(event));
        } break;
        

        default:
            // these events should be handled in the main event loop
            SkASSERT(event.type != Expose && event.type != ConfigureNotify);
            break;
    }

    return false;
}
Exemplo n.º 8
0
Arquivo: x11.c Projeto: aki5/libdraw3
/*
 *	drawevents2 calls flush to display anything that was drawn.
 */
static Input *
drawevents2(int block, int *ninp)
{
	static int flushing;

	if(!flushing){
		if(screen.dirty){
			drawflush(screen.r);
			flushing = 1;
			screen.dirty = 0;
		}
		ninputs = 0;
	}
	while((block && (flushing || ninputs == 0)) || XPending(display)){
		XEvent ev;
		XNextEvent(display, &ev);
		switch(ev.type){
		case MapNotify:
		case ReparentNotify:
			addredraw();
			continue;
		case Expose:
			addredraw();
			continue;
		case KeyPress:
		case KeyRelease:
			{
				XKeyEvent *ep = &ev.xkey;
				if(0)fprintf(
					stderr,
					"key %s %d (%x) '%c' at (%d,%d) state %x\n",
					ev.type == KeyPress ? "pressed" : "released",
					ep->keycode,
					ep->keycode,
					isprint(ep->keycode) ? ep->keycode : '.',
					ep->x, ep->y,
					ep->state
				);

				u64int mod;
				KeySym keysym;
				int code;
				char keystr[8] = {0};

				keysym = XLookupKeysym(ep, ep->state & (ShiftMask|LockMask));
				if((code = keysym2ucs(keysym)) != -1)
					utf8encode(keystr, sizeof keystr-1, code);
				else
					keystr[0] = '\0';

				switch(keysym){
				case XK_Return:
				case XK_KP_Enter:
					strncpy(keystr, "\n", sizeof keystr-1);
					mod = KeyStr;
					break;
				case XK_Tab:
				case XK_KP_Tab:
				case XK_ISO_Left_Tab:
					strncpy(keystr, "\t", sizeof keystr-1);
					mod = KeyStr;
					break;
				case XK_Break:
					mod = KeyBreak;
					break;
				case XK_BackSpace:
					mod = KeyBackSpace;
					break;
				case XK_Down:
					mod = KeyDown;
					break;
				case XK_End:
					mod = KeyEnd;
					break;
				case XK_Home:
					mod = KeyHome;
					break;
				case XK_Left:
					mod = KeyLeft;
					break;
				case XK_Page_Down:
					mod = KeyPageDown;
					break;
				case XK_Page_Up:
					mod = KeyPageUp;
					break;
				case XK_Right:
					mod = KeyRight;
					break;
				case XK_Up:
					mod = KeyUp;
					break;
				case XK_Shift_L:
				case XK_Shift_R:
					mod = KeyShift;
					break;
				case XK_Control_L:
				case XK_Control_R:
					mod = KeyControl;
					break;
				case XK_Meta_L:
				case XK_Meta_R: 
					mod = KeyMeta;	/* mac command key */
					break;
				case XK_Alt_L:
				case XK_Alt_R:
					mod = KeyAlt;
					break;
				case XK_Super_L:
				case XK_Super_R:
fprintf(stderr, "super\n");
					mod = KeySuper;
					break;
				case XK_Hyper_L:
				case XK_Hyper_R:
fprintf(stderr, "hyper\n");
					mod = KeyHyper;
					break;
				case XK_KP_Insert:
				case XK_Insert:
					mod = KeyIns;
					break;
				case XK_KP_Delete:
				case XK_Delete:
					mod = KeyDel;
					break;
				case XK_Caps_Lock:
					mod = KeyCapsLock;
					break;
				default:
					mod = 0;
					break;
				}

				addinput(
					0, 0,
					keystr,
					mod,
					ev.type == KeyPress,
					ev.type == KeyRelease
				);
			}
			continue;
		case ButtonPress:
		case ButtonRelease:
			{
				XButtonEvent *ep = &ev.xbutton;
				u64int mod;
				switch(ep->button){
				case 0:case 1:case 2:case 3:case 4:
				case 5:case 6:case 7:case 9:case 10:
					mod = Mouse0 << ep->button;
					break;
				default:
					fprintf(stderr, "unsupported mouse button %d\n", ep->button);
					mod = 0;
					break;
				}
				if(mod != 0){
					addinput(
						ep->x, ep->y,
						NULL,
						mod,
						ev.type == ButtonPress,
						ev.type == ButtonRelease
					);
				}
			}
			continue;	
		case EnterNotify:
		case LeaveNotify:
			fprintf(stderr, "enter/leave\n");
			continue;
		case MotionNotify:
			if(input_prevmod != 0){
				XMotionEvent *ep = &ev.xmotion;
				u64int m;
				if(0)fprintf(
					stderr,
					"motion at (%d,%d) state %x\n",
					ep->x, ep->y,
					ep->state
				);
				for(m = Mouse0; m <= LastMouse; m <<= 1){
					addinput(
						ep->x, ep->y,
						NULL,
						m,
						0,0
					);
				}
			}
			continue;
		case ConfigureNotify:
			{
				XConfigureEvent *ce = &ev.xconfigure;
				if(ce->width != width || ce->height != height){
					shmfree();
					width = ce->width;
					height = ce->height;
					if(shminit() == -1){
						*ninp = 0;
						return NULL;
					}
					addredraw();
				}
				continue;
			}
		}
		if(ev.type == XShmGetEventBase(display) + ShmCompletion){
			flushing = 0;
			if(animating){
				addredraw();
			}
			continue;
		}
		fprintf(stderr, "unknown xevent %d\n", ev.type);
	}

	if(!flushing && ninputs > 0){
		*ninp = ninputs;
		return inputs;
	}

	*ninp = 0;
	return NULL;
}
Exemplo n.º 9
0
/*
 * Handles keypresses by converting the keycodes to keysymbols, then the
 * keysymbols to UCS-2. If the conversion succeeded, the glyph is saved in the
 * internal buffers and displayed in the input window.
 *
 * Also handles backspace (deleting one character) and return (sending the
 * command to i3).
 *
 */
static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press_event_t *event) {
    printf("Keypress %d, state raw = %d\n", event->detail, event->state);

    // TODO: port the input handling code from i3lock once libxkbcommon ≥ 0.5.0
    // is available in distros.

    /* See the documentation of xcb_key_symbols_get_keysym for this one.
     * Basically: We get either col 0 or col 1, depending on whether shift is
     * pressed. */
    int col = (event->state & XCB_MOD_MASK_SHIFT);

    /* If modeswitch is currently active, we need to look in group 2 or 3,
     * respectively. */
    if (modeswitch_active)
        col += 2;

    xcb_keysym_t sym = xcb_key_press_lookup_keysym(symbols, event, col);
    if (sym == XK_Mode_switch) {
        printf("Mode switch enabled\n");
        modeswitch_active = true;
        return 1;
    }

    if (sym == XK_Return)
        finish_input();

    if (sym == XK_BackSpace) {
        if (input_position == 0)
            return 1;

        input_position--;
        free(glyphs_utf8[input_position]);

        handle_expose(NULL, conn, NULL);
        return 1;
    }
    if (sym == XK_Escape) {
        exit(0);
    }

    /* TODO: handle all of these? */
    printf("is_keypad_key = %d\n", xcb_is_keypad_key(sym));
    printf("is_private_keypad_key = %d\n", xcb_is_private_keypad_key(sym));
    printf("xcb_is_cursor_key = %d\n", xcb_is_cursor_key(sym));
    printf("xcb_is_pf_key = %d\n", xcb_is_pf_key(sym));
    printf("xcb_is_function_key = %d\n", xcb_is_function_key(sym));
    printf("xcb_is_misc_function_key = %d\n", xcb_is_misc_function_key(sym));
    printf("xcb_is_modifier_key = %d\n", xcb_is_modifier_key(sym));

    if (xcb_is_modifier_key(sym) || xcb_is_cursor_key(sym))
        return 1;

    printf("sym = %c (%d)\n", sym, sym);

    /* convert the keysym to UCS */
    uint16_t ucs = keysym2ucs(sym);
    if ((int16_t)ucs == -1) {
        fprintf(stderr, "Keysym could not be converted to UCS, skipping\n");
        return 1;
    }

    xcb_char2b_t inp;
    inp.byte1 = (ucs & 0xff00) >> 2;
    inp.byte2 = (ucs & 0x00ff) >> 0;

    printf("inp.byte1 = %02x, inp.byte2 = %02x\n", inp.byte1, inp.byte2);
    /* convert it to UTF-8 */
    char *out = convert_ucs2_to_utf8(&inp, 1);
    printf("converted to %s\n", out);

    glyphs_ucs[input_position] = inp;
    glyphs_utf8[input_position] = out;
    input_position++;

    if (input_position == limit)
        finish_input();

    handle_expose(NULL, conn, NULL);
    return 1;
}
static Accessibility_DeviceEvent
spi_keystroke_from_x_key_event (XKeyEvent *x_key_event)
{
  Accessibility_DeviceEvent key_event;
  KeySym keysym;
  const int cbuf_bytes = 20;
  char cbuf [21];
  int nbytes;

  nbytes = XLookupString (x_key_event, cbuf, cbuf_bytes, &keysym, NULL);  
  key_event.id = (dbus_int32_t)(keysym);
  key_event.hw_code = (dbus_int16_t) x_key_event->keycode;
  if (((XEvent *) x_key_event)->type == KeyPress)
    {
      key_event.type = Accessibility_KEY_PRESSED_EVENT;
    }
  else
    {
      key_event.type = Accessibility_KEY_RELEASED_EVENT;
    } 
  key_event.modifiers = (dbus_uint16_t)(x_key_event->state);
  key_event.is_text = FALSE;
  switch (keysym)
    {
      case ' ':
        key_event.event_string = g_strdup ("space");
        break;
      case XK_Tab:
        key_event.event_string = g_strdup ("Tab");
	break;
      case XK_BackSpace:
        key_event.event_string = g_strdup ("Backspace");
	break;
      case XK_Return:
        key_event.event_string = g_strdup ("Return");
	break;
      case XK_Home:
        key_event.event_string = g_strdup ("Home");
	break;
      case XK_Page_Down:
        key_event.event_string = g_strdup ("Page_Down");
	break;
      case XK_Page_Up:
        key_event.event_string = g_strdup ("Page_Up");
	break;
      case XK_F1:
        key_event.event_string = g_strdup ("F1");
	break;
      case XK_F2:
        key_event.event_string = g_strdup ("F2");
	break;
      case XK_F3:
        key_event.event_string = g_strdup ("F3");
	break;
      case XK_F4:
        key_event.event_string = g_strdup ("F4");
	break;
      case XK_F5:
        key_event.event_string = g_strdup ("F5");
	break;
      case XK_F6:
        key_event.event_string = g_strdup ("F6");
	break;
      case XK_F7:
        key_event.event_string = g_strdup ("F7");
	break;
      case XK_F8:
        key_event.event_string = g_strdup ("F8");
	break;
      case XK_F9:
        key_event.event_string = g_strdup ("F9");
	break;
      case XK_F10:
        key_event.event_string = g_strdup ("F10");
	break;
      case XK_F11:
        key_event.event_string = g_strdup ("F11");
	break;
      case XK_F12:
        key_event.event_string = g_strdup ("F12");
	break;
      case XK_End:
        key_event.event_string = g_strdup ("End");
	break;
      case XK_Escape:
        key_event.event_string = g_strdup ("Escape");
	break;
      case XK_Up:
        key_event.event_string = g_strdup ("Up");
	break;
      case XK_Down:
        key_event.event_string = g_strdup ("Down");
	break;
      case XK_Left:
        key_event.event_string = g_strdup ("Left");
	break;
      case XK_Right:
        key_event.event_string = g_strdup ("Right");
	break;
      default:
        if (nbytes > 0)
          {
	    gunichar c;
	    cbuf[nbytes] = '\0'; /* OK since length is cbuf_bytes+1 */
            key_event.event_string = g_strdup (cbuf);
	    c = keysym2ucs (keysym);
	    if (c > 0 && !g_unichar_iscntrl (c))
	      {
	        key_event.is_text = TRUE; 
		/* incorrect for some composed chars? */
	      }
          }
        else
          {
            key_event.event_string = g_strdup ("");
          }
    }

  key_event.timestamp = (dbus_uint32_t) x_key_event->time;
#ifdef SPI_KEYEVENT_DEBUG
  {
    char *pressed_str  = "pressed";
    char *released_str = "released";
    char *state_ptr;

    if (key_event.type == Accessibility_KEY_PRESSED_EVENT)
      state_ptr = pressed_str;
    else
      state_ptr = released_str;
 
    fprintf (stderr,
	     "Key %lu %s (%c), modifiers %d; string=%s [%x] %s\n",
	     (unsigned long) keysym,
	     state_ptr,
	     keysym ? (int) keysym : '*',
	     (int) x_key_event->state,
	     key_event.event_string,
	     key_event.event_string[0],
	     (key_event.is_text == TRUE) ? "(text)" : "(not text)");
  }
#endif
#ifdef SPI_DEBUG
  fprintf (stderr, "%s%c\n",
     (x_key_event->state & Mod1Mask)?"Alt-":"",
     ((x_key_event->state & ShiftMask)^(x_key_event->state & LockMask))?
     g_ascii_toupper (keysym) : g_ascii_tolower (keysym));
  fprintf (stderr, "serial: %x Time: %x\n", x_key_event->serial, x_key_event->time);
#endif /* SPI_DEBUG */
  return key_event;	
}