Example #1
0
/* Mouse hit detection
 */
static void
find_mouse_gear (ModeInfo *mi)
{
  pinion_configuration *pp = &pps[MI_SCREEN(mi)];
  int screen_width = MI_WIDTH (mi);
  int screen_height = MI_HEIGHT (mi);
  GLfloat h = (GLfloat) screen_height / (GLfloat) screen_width;
  int x, y;
  int hits;

  pp->mouse_gear_id = 0;

  /* Poll mouse position */
  {
    Window r, c;
    int rx, ry;
    unsigned int m;
    XQueryPointer (MI_DISPLAY (mi), MI_WINDOW (mi),
                   &r, &c, &rx, &ry, &x, &y, &m);
  }

  if (x < 0 || y < 0 || x > screen_width || y > screen_height)
    return;  /* out of window */

  /* Run OpenGL hit detector */
  {
    GLint vp[4];
    GLuint selbuf[512];

    glSelectBuffer (sizeof(selbuf), selbuf);  /* set up "select" mode */
    glRenderMode (GL_SELECT);
    glMatrixMode (GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glGetIntegerv (GL_VIEWPORT, vp);         /* save old vp */
    gluPickMatrix (x, vp[3]-y, 5, 5, vp);
    gluPerspective (30.0, 1/h, 1.0, 100.0);  /* must match reshape_pinion() */
    glMatrixMode (GL_MODELVIEW);

    draw_gears (mi);                         /* render into "select" buffer */

    glMatrixMode (GL_PROJECTION);            /* restore old vp */
    glPopMatrix ();
    glMatrixMode (GL_MODELVIEW);
    glFlush();
    hits = glRenderMode (GL_RENDER);         /* done selecting */

    if (hits > 0)
      {
        int i;
        GLuint name_count = 0;
        GLuint *p = (GLuint *) selbuf;
        GLuint *pnames = 0;
        GLuint min_z = ~0;

        for (i = 0; i < hits; i++)
          {     
            int names = *p++;
            if (*p < min_z)                  /* find match closest to screen */
              {
                name_count = names;
                min_z = *p;
                pnames = p+2;
              }
            p += names+2;
          }

        if (name_count > 0)                  /* take first hit */
          pp->mouse_gear_id = pnames[0];
      }
  }
}
Example #2
0
static int
new_passwd_window (saver_info *si)
{
  passwd_dialog_data *pw;
  Screen *screen;
  Colormap cmap;
  char *f;  /* temp variable for user with getting strings from config */
  saver_screen_info *ssi = &si->screens [mouse_screen (si)];

  pw = (passwd_dialog_data *) calloc (1, sizeof(*pw));
  if (!pw)
    return -1;

  pw->passwd_cursor = XCreateFontCursor (si->dpy, XC_top_left_arrow);

  pw->prompt_screen = ssi;

  screen = pw->prompt_screen->screen;
  cmap = DefaultColormapOfScreen (screen);

  pw->show_stars_p = get_boolean_resource(si->dpy, "passwd.asterisks",
					  "Boolean");

  pw->passwd_string = strdup("");

  f = get_string_resource(si->dpy, "passwd.passwdFont", "Dialog.Font");
  pw->passwd_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
  if (!pw->passwd_font) pw->passwd_font = XLoadQueryFont (si->dpy, "fixed");
  if (f) free (f);

  f = get_string_resource(si->dpy, "passwd.unameFont", "Dialog.Font");
  pw->uname_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
  if (!pw->uname_font) pw->uname_font = XLoadQueryFont (si->dpy, "fixed");
  if (f) free (f);

  pw->foreground = get_pixel_resource (si->dpy, cmap,
				       "passwd.foreground",
				       "Dialog.Foreground" );
  pw->background = get_pixel_resource (si->dpy, cmap,
				       "passwd.background",
				       "Dialog.Background" );

  if (pw->foreground == pw->background)
    {
      /* Make sure the error messages show up. */
      pw->foreground = BlackPixelOfScreen (screen);
      pw->background = WhitePixelOfScreen (screen);
    }

  pw->passwd_foreground = get_pixel_resource (si->dpy, cmap,
					      "passwd.text.foreground",
					      "Dialog.Text.Foreground" );
  pw->passwd_background = get_pixel_resource (si->dpy, cmap,
					      "passwd.text.background",
					      "Dialog.Text.Background" );
  /* [email protected] - Get Chrome OS specific options */
  pw->passwd_field_width = get_integer_resource(si->dpy, "chromeos.password.width", "Integer");
  pw->passwd_field_height = get_integer_resource(si->dpy, "chromeos.password.height", "Integer");
  pw->width = get_integer_resource(si->dpy, "chromeos.background.width", "Integer");
  pw->height = get_integer_resource(si->dpy, "chromeos.background.height", "Integer");

  {
    Window pointer_root, pointer_child;
    int root_x, root_y, win_x, win_y;
    unsigned int mask;
    pw->previous_mouse_x = 0;
    pw->previous_mouse_y = 0;
    if (XQueryPointer (si->dpy, RootWindowOfScreen (pw->prompt_screen->screen),
                       &pointer_root, &pointer_child,
                       &root_x, &root_y, &win_x, &win_y, &mask))
      {
        pw->previous_mouse_x = root_x;
        pw->previous_mouse_y = root_y;
        if (si->prefs.verbose_p)
          fprintf (stderr, "%s: %d: mouse is at %d,%d.\n",
                   blurb(), pw->prompt_screen->number,
                   pw->previous_mouse_x, pw->previous_mouse_y);
      }
    else if (si->prefs.verbose_p)
      fprintf (stderr, "%s: %d: unable to determine mouse position?\n",
               blurb(), pw->prompt_screen->number);
  }

  /* Before mapping the window, save a pixmap of the current screen.
     When we lower the window, we
     restore these bits.  This works, because the running screenhack
     has already been sent SIGSTOP, so we know nothing else is drawing
     right now! */
  {
    XGCValues gcv;
    GC gc;
    pw->save_under = XCreatePixmap (si->dpy,
				    pw->prompt_screen->screensaver_window,
				    pw->prompt_screen->width,
				    pw->prompt_screen->height,
				    pw->prompt_screen->current_depth);
    gcv.function = GXcopy;
    gc = XCreateGC (si->dpy, pw->save_under, GCFunction, &gcv);
    XCopyArea (si->dpy, pw->prompt_screen->screensaver_window,
	       pw->save_under, gc,
	       0, 0,
	       pw->prompt_screen->width, pw->prompt_screen->height,
	       0, 0);
    XFreeGC (si->dpy, gc);
  }

  si->pw_data = pw;
  return 0;
}
Example #3
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);

}
Example #4
0
/*****************************************************************************
 *
 * Builtin which determines if the button press was a click or double click...
 *
 ****************************************************************************/
void ComplexFunction(XEvent * eventp, Window w, FvwmWindow * tmp_win,
                     unsigned long context, char *action, int *Module)
{
    char type = MOTION;
    char c;
    MenuItem *mi;
    Bool Persist = False;
    Bool HaveDoubleClick = False;
    Bool NeedsTarget = False;
    char *arguments[10], *junk, *taction;
    int x, y, i;
    XEvent d, *ev;
    MenuRoot *mr;
    extern Bool desperate;

    mr = FindPopup(action);
    if (mr == NULL) {
        if (!desperate)
            fvwm_msg(ERR, "ComplexFunction", "No such function %s", action);
        return;
    }
    desperate = 0;
    /* Get the argument list */
    /* First entry in action is the function-name, ignore it */
    action = GetNextToken(action, &junk);
    if (junk != NULL)
        free(junk);
    for (i = 0; i < 10; i++)
        action = GetNextToken(action, &arguments[i]);
    /* These built-ins require a selected window
     * The function code is >= 100 and < 1000
     * F_RESIZE
     * F_MOVE
     * F_ICONIFY
     * F_RAISE
     * F_LOWER
     * F_DESTROY
     * F_DELETE
     * F_STICK
     * F_RAISELOWER
     * F_MAXIMIZE
     * F_FOCUS
     *
     * These do not:
     * The function code is < 100
     * F_NOP
     * F_TITLE
     * F_BEEP
     * F_SCROLL
     * F_MOVECURSOR
     * F_RESTART
     * F_EXEC
     * F_REFRESH
     * F_GOTO_PAGE
     * F_TOGGLE_PAGE
     * F_CIRCULATE_UP
     * F_CIRCULATE_DOWN
     * F_WARP
     * F_DESK
     * F_MODULE
     * F_POPUP
     * F_QUIT
     * F_WINDOWLIST
     * F_FUNCTION
     * F_SEND_WINDOW_LIST
     */
    ev = eventp;
    /* In case we want to perform an action on a button press, we
     * need to fool other routines */
    if (eventp->type == ButtonPress)
        eventp->type = ButtonRelease;
    mi = mr->first;
    while (mi != NULL) {
        /* make lower case */
        c = *(mi->item);
        if ((mi->func_type >= 100) && (mi->func_type < 1000))
            NeedsTarget = True;
        if (isupper(c))
            c = tolower(c);
        if (c == DOUBLE_CLICK) {
            HaveDoubleClick = True;
            Persist = True;
        } else if (c == IMMEDIATE) {
            if (tmp_win)
                w = tmp_win->frame;
            else
                w = None;
            taction = expand(mi->action, arguments, tmp_win);
            ExecuteFunction(taction, tmp_win, eventp, context, -2);
            free(taction);
        } else
            Persist = True;
        mi = mi->next;
    }

    if (!Persist) {
        for (i = 0; i < 10; i++)
            if (arguments[i] != NULL)
                free(arguments[i]);
        return;
    }

    /* Only defer execution if there is a possibility of needing
     * a window to operate on */
    if (NeedsTarget) {
        if (DeferExecution
                (eventp, &w, &tmp_win, &context, SELECT, ButtonPress)) {
            WaitForButtonsUp();
            for (i = 0; i < 10; i++)
                if (arguments[i] != NULL)
                    free(arguments[i]);
            return;
        }
    }

    if (!GrabEm(SELECT)) {
        XBell(dpy, Scr.screen);
        for (i = 0; i < 10; i++)
            if (arguments[i] != NULL)
                free(arguments[i]);
        return;
    }
    XQueryPointer(dpy, Scr.Root, &JunkRoot, &JunkChild,
                  &x, &y, &JunkX, &JunkY, &JunkMask);


    /* Wait and see if we have a click, or a move */
    /* wait 100 msec, see if the user releases the button */
    if (IsClick(x, y, ButtonReleaseMask, &d)) {
        ev = &d;
        type = CLICK;
    }

    /* If it was a click, wait to see if its a double click */
    if ((HaveDoubleClick) && (type == CLICK) &&
            (IsClick(x, y, ButtonPressMask, &d))) {
        type = ONE_AND_A_HALF_CLICKS;
        ev = &d;
    }
    if ((HaveDoubleClick) && (type == ONE_AND_A_HALF_CLICKS) &&
            (IsClick(x, y, ButtonReleaseMask, &d))) {
        type = DOUBLE_CLICK;
        ev = &d;
    }
    /* some functions operate on button release instead of
     * presses. These gets really weird for complex functions ... */
    if (ev->type == ButtonPress)
        ev->type = ButtonRelease;

    mi = mr->first;
    while (mi != NULL) {
        /* make lower case */
        c = *(mi->item);
        if (isupper(c))
            c = tolower(c);
        if (c == type) {
            if (tmp_win)
                w = tmp_win->frame;
            else
                w = None;
            taction = expand(mi->action, arguments, tmp_win);
            ExecuteFunction(taction, tmp_win, ev, context, -2);
            free(taction);
        }
        mi = mi->next;
    }
    WaitForButtonsUp();
    UngrabEm();
    for (i = 0; i < 10; i++)
        if (arguments[i] != NULL)
            free(arguments[i]);
}
Example #5
0
/**
 * Grab a frame from x11 (public device demuxer API).
 *
 * @param s1 Context from avformat core
 * @param pkt Packet holding the brabbed frame
 * @return frame size in bytes
 */
static int
x11grab_read_packet(AVFormatContext *s1, AVPacket *pkt)
{
    struct x11grab *s = s1->priv_data;
    Display *dpy = s->dpy;
    XImage *image = s->image;
    int x_off = s->x_off;
    int y_off = s->y_off;

    int screen;
    Window root;
    int follow_mouse = s->follow_mouse;

    int64_t curtime, delay;
    struct timespec ts;

    /* Calculate the time of the next frame */
    s->time_frame += INT64_C(1000000);

    /* wait based on the frame rate */
    for(;;) {
        curtime = av_gettime();
        delay = s->time_frame * av_q2d(s->time_base) - curtime;
        if (delay <= 0) {
            if (delay < INT64_C(-1000000) * av_q2d(s->time_base)) {
                s->time_frame += INT64_C(1000000);
            }
            break;
        }
        ts.tv_sec = delay / 1000000;
        ts.tv_nsec = (delay % 1000000) * 1000;
        nanosleep(&ts, NULL);
    }

    av_init_packet(pkt);
    pkt->data = image->data;
    pkt->size = s->frame_size;
    pkt->pts = curtime;

    screen = DefaultScreen(dpy);
    root = RootWindow(dpy, screen);
    if (follow_mouse) {
        int screen_w, screen_h;
        int pointer_x, pointer_y, _;
        Window w;

        screen_w = DisplayWidth(dpy, screen);
        screen_h = DisplayHeight(dpy, screen);
        XQueryPointer(dpy, root, &w, &w, &pointer_x, &pointer_y, &_, &_, &_);
        if (follow_mouse == -1) {
            // follow the mouse, put it at center of grabbing region
            x_off += pointer_x - s->width  / 2 - x_off;
            y_off += pointer_y - s->height / 2 - y_off;
        } else {
            // follow the mouse, but only move the grabbing region when mouse
            // reaches within certain pixels to the edge.
            if (pointer_x > x_off + s->width - follow_mouse) {
                x_off += pointer_x - (x_off + s->width - follow_mouse);
            } else if (pointer_x < x_off + follow_mouse)
                x_off -= (x_off + follow_mouse) - pointer_x;
            if (pointer_y > y_off + s->height - follow_mouse) {
                y_off += pointer_y - (y_off + s->height - follow_mouse);
            } else if (pointer_y < y_off + follow_mouse)
                y_off -= (y_off + follow_mouse) - pointer_y;
        }
        // adjust grabbing region position if it goes out of screen.
        s->x_off = x_off = FFMIN(FFMAX(x_off, 0), screen_w - s->width);
        s->y_off = y_off = FFMIN(FFMAX(y_off, 0), screen_h - s->height);

        if (s->show_region && s->region_win)
            XMoveWindow(dpy, s->region_win,
                        s->x_off - REGION_WIN_BORDER,
                        s->y_off - REGION_WIN_BORDER);
    }

    if (s->show_region) {
        if (s->region_win) {
            XEvent evt;
            // clean up the events, and do the initinal draw or redraw.
            for (evt.type = NoEventMask; XCheckMaskEvent(dpy, ExposureMask | StructureNotifyMask, &evt); );
            if (evt.type)
                x11grab_draw_region_win(s);
        } else {
            x11grab_region_win_init(s);
        }
    }

    if(s->use_shm) {
        if (!XShmGetImage(dpy, root, image, x_off, y_off, AllPlanes)) {
            av_log (s1, AV_LOG_INFO, "XShmGetImage() failed\n");
        }
    } else {
        if (!xget_zpixmap(dpy, root, image, x_off, y_off)) {
            av_log (s1, AV_LOG_INFO, "XGetZPixmap() failed\n");
        }
    }

    if (s->draw_mouse) {
        paint_mouse_pointer(image, s);
    }

    return s->frame_size;
}
Example #6
0
static void
setup(void)
{
	int x, y;
	XSetWindowAttributes swa;
	XIM xim;
#ifdef XINERAMA
	XineramaScreenInfo *info;
	Window w, pw, dw, *dws;
	XWindowAttributes wa;
	int a, j, di, n, i = 0, area = 0;
	unsigned int du;
#endif

	/* init appearance */
	scheme[SchemeNorm].bg = drw_clr_create(drw, normbgcolor);
	scheme[SchemeNorm].fg = drw_clr_create(drw, normfgcolor);
	scheme[SchemeSel].bg = drw_clr_create(drw, selbgcolor);
	scheme[SchemeSel].fg = drw_clr_create(drw, selfgcolor);
	scheme[SchemeOut].bg = drw_clr_create(drw, outbgcolor);
	scheme[SchemeOut].fg = drw_clr_create(drw, outfgcolor);

	clip = XInternAtom(dpy, "CLIPBOARD",   False);
	utf8 = XInternAtom(dpy, "UTF8_STRING", False);

	/* calculate menu geometry */
	bh = drw->fonts[0]->h + 2;
	lines = MAX(lines, 0);
	mh = (lines + 1) * bh;
#ifdef XINERAMA
	if ((info = XineramaQueryScreens(dpy, &n))) {
		XGetInputFocus(dpy, &w, &di);
		if (mon != -1 && mon < n)
			i = mon;
		if (!i && w != root && w != PointerRoot && w != None) {
			/* find top-level window containing current input focus */
			do {
				if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws)
					XFree(dws);
			} while (w != root && w != pw);
			/* find xinerama screen with which the window intersects most */
			if (XGetWindowAttributes(dpy, pw, &wa))
				for (j = 0; j < n; j++)
					if ((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) {
						area = a;
						i = j;
					}
		}
		/* no focused window is on screen, so use pointer location instead */
		if (mon == -1 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du))
			for (i = 0; i < n; i++)
				if (INTERSECT(x, y, 1, 1, info[i]))
					break;

		x = info[i].x_org;
		y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
		mw = info[i].width;
		XFree(info);
	} else
#endif
	{
		x = 0;
		y = topbar ? 0 : sh - mh;
		mw = sw;
	}
	promptw = (prompt && *prompt) ? TEXTW(prompt) : 0;
	inputw = MIN(inputw, mw/3);
	match();

	/* create menu window */
	swa.override_redirect = True;
	swa.background_pixel = scheme[SchemeNorm].bg->pix;
	swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
	win = XCreateWindow(dpy, root, x, y, mw, mh, 0,
	                    DefaultDepth(dpy, screen), CopyFromParent,
	                    DefaultVisual(dpy, screen),
	                    CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);

	/* open input methods */
	xim = XOpenIM(dpy, NULL, NULL, NULL);
	xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
	                XNClientWindow, win, XNFocusWindow, win, NULL);

	XMapRaised(dpy, win);
	drw_resize(drw, mw, mh);
	drawmenu();
}
Example #7
0
int LinuxSwapBuffers(){
	LibGE_LinuxContext* context = (LibGE_LinuxContext*)libge_context->syscontext;

	if(ev_thid == NULL){
		ev_thid = geCreateThread("LibGE Event Thread", _ev_thread, 0);
		geThreadStart(ev_thid, sizeof(LibGE_LinuxContext*), context);
	}
/*
	if(pending_wup_release && keys_pressed[GEK_MWHEELUP]){
		keys_pressed[GEK_MWHEELUP] = false;
		keys_released[GEK_MWHEELUP] = true;
		pending_wup_release = false;
	}
	if(pending_wdown_release && keys_pressed[GEK_MWHEELDOWN]){
		keys_pressed[GEK_MWHEELDOWN] = false;
		keys_released[GEK_MWHEELDOWN] = true;
		pending_wdown_release = false;
	}
*/

	if(wheel_i == -1){
		int i = 0;
		for(i=0; i<32; i++){
			wheel_ev[i].type = -1;
		}
		wheel_i = 0;
	}

	if(wheel_ev[wheel_i].type >= 0){
		if(wheel_ev[wheel_i].button == GEK_MWHEELUP){
			keys_pressed[GEK_MWHEELUP] = (wheel_ev[wheel_i].type == ButtonPress);
			keys_released[GEK_MWHEELUP] = (wheel_ev[wheel_i].type == ButtonRelease);
		}
		if(wheel_ev[wheel_i].button == GEK_MWHEELDOWN){
			keys_pressed[GEK_MWHEELDOWN] = (wheel_ev[wheel_i].type == ButtonPress);
			keys_released[GEK_MWHEELDOWN] = (wheel_ev[wheel_i].type == ButtonRelease);
		}
		wheel_ev[wheel_i].type = -1;
		wheel_i = (wheel_i + 1) % 32;
	}
	/*
	mouse_warp_x = warp_x;
	mouse_warp_y = warp_y;
	reset = true;
*/
	int unused, mx, my;
	Window unwin;
	if(XQueryPointer(context->dpy, context->win, &unwin, &unwin, &unused, &unused, &mx, &my, (u32*)&unused)){
		if(libge_context->mouse_round){
			mouse_warp_x = mx - libge_context->width / 2;
			mouse_warp_y = my - libge_context->height / 2;
			libge_context->mouse_x = libge_context->width / 2;
			libge_context->mouse_y = libge_context->height / 2;
			changed = true;
			XWarpPointer(context->dpy, context->win, context->win, 0, 0, 0, 0, libge_context->mouse_x, libge_context->mouse_y);
		}else{
			mouse_last_x = libge_context->mouse_x;
			mouse_last_y = libge_context->mouse_y;
			libge_context->mouse_x = mx;
			libge_context->mouse_y = my;
			mouse_warp_x = libge_context->mouse_x - mouse_last_x;
			mouse_warp_y = libge_context->mouse_y - mouse_last_y;
		}
	}


	glXSwapBuffers(context->dpy, context->win);

	if(new_w > 0 && new_h > 0 && (new_w != libge_context->width || new_h != libge_context->height)){
		libge_context->width = new_w;
		libge_context->height = new_h;
		libge_context->projection_matrix[0] = (float)0xFFFFFFFF;
		geGraphicsInit();
		geDrawingMode(libge_context->drawing_mode | 0xF0000000);
	}

	if(_to_close){
		CloseFullScreen();
		exit(0);
	}

	return (current_buf^=1);
}
Example #8
0
/******************************************************************************
  MakeMeWindow - Create and setup the window we will need
******************************************************************************/
void MakeMeWindow(void)
{
  XSizeHints hints;
  XGCValues gcval;
  unsigned long gcmask;
  unsigned int dummy1, dummy2;
  int x, y, ret, count;
  Window dummyroot, dummychild;
  int i;

  
  if ((count = ItemCountD(&windows))==0 && Transient) ShutMeDown(0);
  AdjustWindow();

  hints.width=win_width;
  hints.height=win_height;
  hints.win_gravity=NorthWestGravity;
  hints.flags=PSize|PWinGravity|PResizeInc;
  hints.width_inc=0;
  hints.height_inc=0;

  if (geometry!= NULL)
  {
    ret=XParseGeometry(geometry,&x,&y,&dummy1,&dummy2);

    if (ret&XValue && ret &YValue)
    {
      hints.x=x;
      if (ret&XNegative)
        hints.x+=XDisplayWidth(dpy,screen)-win_width;

      hints.y=y;
      if (ret&YNegative)
        hints.y+=XDisplayHeight(dpy,screen)-win_height;

      hints.flags|=USPosition;
    }

    if (ret&XNegative)
    {
      if (ret&YNegative) hints.win_gravity=SouthEastGravity;
      else  hints.win_gravity=NorthEastGravity;
    }
    else
    {
      if (ret&YNegative) hints.win_gravity=SouthWestGravity;
      else  hints.win_gravity=NorthWestGravity;
    }

  }

  if (Transient)
  {
    XQueryPointer(dpy,Root,&dummyroot,&dummychild,&hints.x,&hints.y,&x,&y,&dummy1);
    hints.win_gravity=NorthWestGravity;
    hints.flags |= USPosition;
  }
  win_grav=hints.win_gravity;
  win_x=hints.x;
  win_y=hints.y;


  for (i = 0; i != MAX_COLOUR_SETS; i++)
  if(d_depth < 2)
  {
    back[i] = GetColor("white");
    fore[i] = GetColor("black");
  }
  else
  {
    back[i] = GetColor(BackColor[i] == NULL ? BackColor[0] : BackColor[i]);
    fore[i] = GetColor(ForeColor[i] == NULL ? ForeColor[0] : ForeColor[i]);
  }

  win=XCreateSimpleWindow(dpy,Root,hints.x,hints.y,hints.width,hints.height,1,
    fore[0],back[0]);

  wm_del_win=XInternAtom(dpy,"WM_DELETE_WINDOW",False);
  XSetWMProtocols(dpy,win,&wm_del_win,1);
  
  XSetWMNormalHints(dpy,win,&hints);

  if (!Transient)
  {
    XGrabButton(dpy,1,AnyModifier,win,True,GRAB_EVENTS,GrabModeAsync,
      GrabModeAsync,None,None);
    XGrabButton(dpy,2,AnyModifier,win,True,GRAB_EVENTS,GrabModeAsync,
      GrabModeAsync,None,None);
    XGrabButton(dpy,3,AnyModifier,win,True,GRAB_EVENTS,GrabModeAsync,
      GrabModeAsync,None,None);
    SetMwmHints(MWM_DECOR_ALL|MWM_DECOR_RESIZEH|MWM_DECOR_MAXIMIZE|MWM_DECOR_MINIMIZE,
      MWM_FUNC_ALL|MWM_FUNC_RESIZE|MWM_FUNC_MAXIMIZE|MWM_FUNC_MINIMIZE,
      MWM_INPUT_MODELESS);
  }
  else
  {
    SetMwmHints(0,MWM_FUNC_ALL,MWM_INPUT_MODELESS);
  }

  for (i = 0; i != MAX_COLOUR_SETS; i++)
  {
    gcval.foreground=fore[i];
    gcval.background=back[i];
    gcval.font=ButtonFont->fid;
    gcmask=GCForeground|GCBackground|GCFont;
    graph[i]=XCreateGC(dpy,Root,gcmask,&gcval);

    if(d_depth < 2) 
      gcval.foreground=GetShadow(fore[i]);
    else 
      gcval.foreground=GetShadow(back[i]);
    gcval.background=back[i];
    gcmask=GCForeground|GCBackground;
    shadow[i]=XCreateGC(dpy,Root,gcmask,&gcval);

    gcval.foreground=GetHilite(back[i]);
    gcval.background=back[i];
    gcmask=GCForeground|GCBackground;
    hilite[i]=XCreateGC(dpy,Root,gcmask,&gcval);

    gcval.foreground=back[i];
    gcmask=GCForeground;
    background[i]=XCreateGC(dpy,Root,gcmask,&gcval);
  }
  
  XSelectInput(dpy,win,(ExposureMask | KeyPressMask));

  ChangeWindowName(&Module[1]);

  if (ItemCountD(&windows) > 0)
  {
    XMapRaised(dpy,win);
    WaitForExpose();
    WindowIsUp=1;
  } else WindowIsUp=2;

  if (Transient)
  {
    if ( XGrabPointer(dpy,win,True,GRAB_EVENTS,GrabModeAsync,GrabModeAsync,
      None,None,CurrentTime)!=GrabSuccess) ShutMeDown(1);
    XQueryPointer(dpy,Root,&dummyroot,&dummychild,&hints.x,&hints.y,&x,&y,&dummy1);
    if (!SomeButtonDown(dummy1)) ShutMeDown(0);
  }

}
PsychError SCREENGetMouseHelper(void)
{
    const char *valuatorInfo[]={"label", "min", "max", "resolution", "mode", "sourceID"};
    int numValuatorStructFieldNames = 6;
    int numIValuators = 0;
    PsychGenericScriptType *valuatorStruct = NULL;

#if PSYCH_SYSTEM == PSYCH_OSX
    Point   mouseXY;
    UInt32  buttonState;
    double  *buttonArray;
    int     numButtons, i;
    psych_bool  doButtonArray;
    PsychWindowRecordType   *windowRecord;
    int32_t deltaX, deltaY;
    double myvaluators[2];

    //all subfunctions should have these two lines.
    PsychPushHelp(useString, synopsisString, seeAlsoString);
    if (PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);};

    //cap the numbers of inputs and outputs
    PsychErrorExit(PsychCapNumInputArgs(3));   //The maximum number of inputs
    PsychErrorExit(PsychCapNumOutputArgs(6));  //The maximum number of outputs

    // Buttons.
    // The only way I know to detect the  number number of mouse buttons is directly via HID.  The device reports
    // that information but OS X seems to ignore it above the level of the HID driver, that is, no OS X API above the HID driver
    // exposes it.  So GetMouse.m function calls PsychHID detect the number of buttons and then passes that value to GetMouseHelper
    // which returns that number of button values in a vector.
    PsychCopyInIntegerArg(1, kPsychArgRequired, &numButtons);
    if (numButtons > 32)
        PsychErrorExitMsg(PsychErorr_argumentValueOutOfRange, "numButtons must not exceed 32");

    // Special codes -10 to -15? --> Console keyboard queries:
    if (numButtons <= -10 && numButtons >= -15) {
        ConsoleInputHelper((int) numButtons);
        return(PsychError_none);
    }

    if (numButtons < 1)
        PsychErrorExitMsg(PsychErorr_argumentValueOutOfRange, "numButtons must exceed 1");

    doButtonArray=PsychAllocOutDoubleMatArg(3, kPsychArgOptional, (int)1, (int)numButtons, (int)1, &buttonArray);
    if (doButtonArray) {
        buttonState=GetCurrentButtonState();
        for(i=0;i<numButtons;i++)
            buttonArray[i]=(double)(buttonState & (1<<i));
    }

    // Get cursor position:
    HIPoint outPoint;
    HIGetMousePosition(kHICoordSpaceScreenPixel, NULL, &outPoint);
    PsychCopyOutDoubleArg(1, kPsychArgOptional, (double) outPoint.x);
    PsychCopyOutDoubleArg(2, kPsychArgOptional, (double) outPoint.y);

    // Return optional keyboard input focus status:
    if (numButtons > 0) {
        // Window provided?
        if (PsychIsWindowIndexArg(2)) {
            // Yes: Check if it has focus.
            PsychAllocInWindowRecordArg(2, TRUE, &windowRecord);
            if (!PsychIsOnscreenWindow(windowRecord)) {
                PsychErrorExitMsg(PsychError_user, "Provided window handle isn't an onscreen window, as required.");
            }

            PsychCopyOutDoubleArg(4, kPsychArgOptional, (double) (PsychCocoaGetUserFocusWindow() == windowRecord->targetSpecific.windowHandle) ? 1 : 0);
        } else {
            // No. Just always return "has focus":
            PsychCopyOutDoubleArg(4, kPsychArgOptional, (double) 1);
        }
    }

    // Return optional valuator values: On OSX we use two valuators to return deltaX and deltaY,
    // the mouse delta movement since last call to this function:
    CGGetLastMouseDelta(&deltaX, &deltaY);
    myvaluators[0] = (double) deltaX;
    myvaluators[1] = (double) deltaY;
    PsychCopyOutDoubleMatArg(5, kPsychArgOptional, (int) 1, (int) 2, (int) 1, &myvaluators[0]);

    // Return optional valuator info struct array as argument 6:
    if (PsychIsArgPresent(PsychArgOut, 6)) {
        // Usercode wants valuator info structs:
        PsychAllocOutStructArray(6, TRUE, 2, numValuatorStructFieldNames, valuatorInfo, &valuatorStruct);

        // Valuator 0: Encodes DeltaX - relative X motion, aka mouse deltaX:
        PsychSetStructArrayStringElement("label", 0, "DeltaX", valuatorStruct);

        // Other fields are meaningless or undefined on OSX, so set to 0 default:
        PsychSetStructArrayDoubleElement("min", 0, (double) 0, valuatorStruct);
        PsychSetStructArrayDoubleElement("max", 0, (double) 0, valuatorStruct);
        PsychSetStructArrayDoubleElement("resolution", 0, (double) 0, valuatorStruct);
        PsychSetStructArrayDoubleElement("mode", 0, (double) 0, valuatorStruct);
        PsychSetStructArrayDoubleElement("sourceID", 0, (double) 0, valuatorStruct);

        // Valuator 1: Encodes DeltaY - relative Y motion, aka mouse deltaY:
        PsychSetStructArrayStringElement("label", 1, "DeltaY", valuatorStruct);

        // Other fields are meaningless or undefined on OSX, so set to 0 default:
        PsychSetStructArrayDoubleElement("min", 1, (double) 0, valuatorStruct);
        PsychSetStructArrayDoubleElement("max", 1, (double) 0, valuatorStruct);
        PsychSetStructArrayDoubleElement("resolution", 1, (double) 0, valuatorStruct);
        PsychSetStructArrayDoubleElement("mode", 1, (double) 0, valuatorStruct);
        PsychSetStructArrayDoubleElement("sourceID", 1, (double) 0, valuatorStruct);
    }
#endif

#if PSYCH_SYSTEM == PSYCH_WINDOWS
    static unsigned char disabledKeys[256];
    static unsigned char firsttime = 1;
    int keysdown, i, priorityLevel;
    unsigned char keyState[256];
    double* buttonArray;
    double numButtons, timestamp;
    PsychNativeBooleanType* buttonStates;
    POINT   point;
    HANDLE  currentProcess;
    DWORD   oldPriority = NORMAL_PRIORITY_CLASS;
    const DWORD realtime_class = REALTIME_PRIORITY_CLASS;
    PsychWindowRecordType *windowRecord;

    PsychPushHelp(useString, synopsisString, seeAlsoString);
    if (PsychIsGiveHelp()) { PsychGiveHelp(); return(PsychError_none); };

    // Retrieve optional number of mouse buttons:
    numButtons = 0;
    PsychCopyInDoubleArg(1, FALSE, &numButtons);

    // Are we operating in 'GetMouseHelper' mode? numButtons>=0 indicates this.
    if (numButtons >= 0) {
        // GetMouse-Mode: Return mouse button states and mouse cursor position:
        PsychAllocOutDoubleMatArg(3, kPsychArgOptional, (int)1, (int)3, (int)1, &buttonArray);
        // Query and return mouse button state:
        PsychGetMouseButtonState(buttonArray);
        // Query and return cursor position in global coordinates:
        GetCursorPos(&point);
        PsychCopyOutDoubleArg(1, kPsychArgOptional, (double) point.x);
        PsychCopyOutDoubleArg(2, kPsychArgOptional, (double) point.y);

        // Window provided?
        if (PsychIsWindowIndexArg(2)) {
            // Yes: Check if it has focus.
            PsychAllocInWindowRecordArg(2, TRUE, &windowRecord);
            if (!PsychIsOnscreenWindow(windowRecord)) {
                PsychErrorExitMsg(PsychError_user, "Provided window handle isn't an onscreen window, as required.");
            }

            PsychCopyOutDoubleArg(4, kPsychArgOptional, (double) (GetForegroundWindow() == windowRecord->targetSpecific.windowHandle) ? 1 : 0);
        } else {
            // No. Just always return "has focus":
            PsychCopyOutDoubleArg(4, kPsychArgOptional, (double) 1);
        }

        // Return optional valuator values: Unimplemented on Windows. Just return an empty matrix.
        // The &timestamp is just a dummy assignment without any meaning.
        PsychCopyOutDoubleMatArg(5, kPsychArgOptional, (int) 1, (int) 0, (int) 1, &timestamp);
        PsychCopyOutDoubleMatArg(6, kPsychArgOptional, (int) 1, (int) 0, (int) 1, buttonArray);
    }
    else {
        // 'KeyboardHelper' mode: We implement either KbCheck() or KbWait() via X11.
        // This is a hack to provide keyboard queries until a PsychHID() implementation
        // for Microsoft Windows is available...

        // Special codes -10 to -15? --> Console keyboard queries:
        if (numButtons <= -10 && numButtons >= -15) {
            ConsoleInputHelper((int) numButtons);
            return(PsychError_none);
        }

        if (firsttime) {
                // First time init:
                firsttime = 0;
                memset(keyState, 0, sizeof(keyState));
                memset(disabledKeys, 0, sizeof(disabledKeys));
                // These keycodes are always disabled: 0, 255:
                disabledKeys[0]=1;
                disabledKeys[255]=1;
                // Mouse buttone (left, right, middle) are also disabled by default:
                disabledKeys[1]=1;
                disabledKeys[2]=1;
                disabledKeys[4]=1;
        }

        if (numButtons==-1 || numButtons==-2) {
            // KbCheck()/KbWait() mode
            do {
                // Reset overall key state to "none pressed":
                keysdown=0;

                // Request current time of query:
                PsychGetAdjustedPrecisionTimerSeconds(&timestamp);

                // Query state of all keys:
                for(i=1;i<255;i++){
                    keyState[i] = (GetAsyncKeyState(i) & -32768) ? 1 : 0;
                }

                // Disable all keys that are registered in disabledKeys. Check if
                // any non-disabled key is down.
                for (i=0; i<256; i++) {
                    if (disabledKeys[i]>0) keyState[i] = 0;
                    keysdown+=(unsigned int) keyState[i];
                }

                // We repeat until any key pressed if in KbWait() mode, otherwise we
                // exit the loop after first iteration in KbCheck mode.
                if ((numButtons==-1) || ((numButtons==-2) && (keysdown>0))) break;

                // Sleep for a millisecond before next KbWait loop iteration:
                PsychWaitIntervalSeconds(0.001);
            } while(1);

            if (numButtons==-2) {
                // KbWait mode: Copy out time value.
                PsychCopyOutDoubleArg(1, kPsychArgOptional, timestamp);
            }
            else {
                // KbCheck mode:

                // Copy out overall keystate:
                PsychCopyOutDoubleArg(1, kPsychArgOptional, (keysdown>0) ? 1 : 0);

                // Copy out timestamp:
                PsychCopyOutDoubleArg(2, kPsychArgOptional, timestamp);

                // Copy out keyboard state:
                PsychAllocOutBooleanMatArg(3, kPsychArgOptional, 1, 256, 1, &buttonStates);

                // Build 256 elements return vector:
                for (i=0; i<255; i++) {
                    buttonStates[i] = (PsychNativeBooleanType)((keyState[i+1]) ? 1 : 0);
                }

                // Special case: Null out last element:
                buttonStates[255] = (PsychNativeBooleanType) 0;
            }
        }

        if (numButtons==-3) {
            // Priority() - helper mode: The 2nd argument is the priority level:

            // Determine our processID:
            currentProcess = GetCurrentProcess();

            // Get current scheduling policy:
            oldPriority = GetPriorityClass(currentProcess);

            // Map to PTB's scheme:
            switch(oldPriority) {
                case NORMAL_PRIORITY_CLASS:
                    priorityLevel = 0;
                break;

                case HIGH_PRIORITY_CLASS:
                    priorityLevel = 1;
                break;

                case REALTIME_PRIORITY_CLASS:
                    priorityLevel = 2;
                break;

                default:
                    priorityLevel = 0;
            }

            // Copy it out as optional return argument:
            PsychCopyOutDoubleArg(1, kPsychArgOptional, (double) priorityLevel);

            // Query if a new level should be set:
            priorityLevel = -1;
            PsychCopyInIntegerArg(2, kPsychArgOptional, &priorityLevel);

            // Priority level provided?
            if (priorityLevel > -1) {
                // Map to new scheduling class:
                if (priorityLevel > 2) PsychErrorExitMsg(PsychErorr_argumentValueOutOfRange, "Invalid Priority level: Requested Priority() level must not exceed 2.");

                switch (priorityLevel) {
                    case 0: // Standard scheduling:
                        SetPriorityClass(currentProcess, NORMAL_PRIORITY_CLASS);

                        // Disable any MMCSS scheduling for us:
                        PsychSetThreadPriority((psych_thread*) 0x1, 0, 0);
                    break;

                    case 1: // High priority scheduling:
                        SetPriorityClass(currentProcess, HIGH_PRIORITY_CLASS);

                        // Additionally try to schedule us MMCSS: This will lift us roughly into the
                        // same scheduling range as REALTIME_PRIORITY_CLASS, even if we are non-admin users
                        // on Vista and Windows-7 and later, however with a scheduler safety net applied.
                        PsychSetThreadPriority((psych_thread*) 0x1, 10, 0);
                    break;

                    case 2: // Realtime scheduling:
                        // This can fail if Matlab is not running under a user account with proper permissions:
                        if ((0 == SetPriorityClass(currentProcess, REALTIME_PRIORITY_CLASS)) || (REALTIME_PRIORITY_CLASS != GetPriorityClass(currentProcess))) {
                            // Failed to get RT-Scheduling. Let's try at least high priority scheduling:
                            SetPriorityClass(currentProcess, HIGH_PRIORITY_CLASS);

                            // Additionally try to schedule us MMCSS: This will lift us roughly into the
                            // same scheduling range as REALTIME_PRIORITY_CLASS, even if we are non-admin users
                            // on Vista and Windows-7 and later, however with a scheduler safety net applied.
                            PsychSetThreadPriority((psych_thread*) 0x1, 10, 0);
                        }
                    break;
                }
            }
            // End of Priority() helper for Win32.
        }
    }
#endif

#if PSYCH_SYSTEM == PSYCH_LINUX
    double myvaluators[100];
    int    numvaluators;
    unsigned char keys_return[32];
    char* keystring;
    PsychGenericScriptType *kbNames;
    CGDirectDisplayID dpy;
    Window rootwin, childwin, mywin = 0;
    int i, j, mx, my, dx, dy;
    double mxd, myd, dxd, dyd;
    unsigned int mask_return;
    double timestamp;
    int numButtons;
    double* buttonArray;
    PsychNativeBooleanType* buttonStates;
    int keysdown;
    XEvent event_return;
    XKeyPressedEvent keypressevent;
    int screenNumber;
    int priorityLevel;
    struct sched_param schedulingparam;
    PsychWindowRecordType *windowRecord = NULL;
    int mouseIndex;
    XIButtonState buttons_return;
    XIModifierState modifiers_return;
    XIGroupState group_return;

    PsychPushHelp(useString, synopsisString, seeAlsoString);
    if (PsychIsGiveHelp()) { PsychGiveHelp(); return(PsychError_none); };

    PsychCopyInIntegerArg(1, kPsychArgRequired, &numButtons);

    // Retrieve optional screenNumber argument:
    if (numButtons!=-5) {
        screenNumber = 0;
        if (PsychIsScreenNumberArg(2)) {
            PsychCopyInScreenNumberArg(2, FALSE, &screenNumber);
        }

        // Map screenNumber to X11 display handle and screenid:
        PsychGetCGDisplayIDFromScreenNumber(&dpy, screenNumber);

        if (PsychIsWindowIndexArg(2)) {
            PsychAllocInWindowRecordArg(2, TRUE, &windowRecord);
            if (!PsychIsOnscreenWindow(windowRecord)) {
                PsychErrorExitMsg(PsychError_user, "Provided window handle isn't an onscreen window, as required.");
            }

            screenNumber = windowRecord->screenNumber;
            #ifndef PTB_USE_WAYLAND
            mywin = windowRecord->targetSpecific.xwindowHandle;
            #else
            // TODO Wayland.
            mywin = None;
            #endif
            // Map screenNumber to X11 display handle and screenid:
            PsychGetCGDisplayIDFromScreenNumber(&dpy, screenNumber);
        } else {
            PsychLockDisplay();
            #ifndef PTB_USE_WAYLAND
            mywin = RootWindow(dpy, PsychGetXScreenIdForScreen(screenNumber));
            #else
            // TODO Wayland.
            mywin = None;
            #endif
            PsychUnlockDisplay();
        }
    }

    // Default to "old school" mouse query - System default mouse via X core protocol:
    mouseIndex = -1;
    PsychCopyInIntegerArg(3, FALSE, &mouseIndex);

    // Are we operating in 'GetMouseHelper' mode? numButtons>=0 indicates this.
    if (numButtons >= 0) {
        // Mouse pointer query mode:
        numvaluators = 0;

        #ifdef PTB_USE_WAYLAND
        {
            void* focusWindow = NULL;
            // Copy out mouse x and y position:
            // Alloc out mouse button state:
            PsychAllocOutDoubleMatArg(3, kPsychArgOptional, (int) 1, (int) numButtons, (int) 1, &buttonArray);

            // Query Wayland backend for mouse state:
            if (!PsychWaylandGetMouseState(mouseIndex, &mx, &my, numButtons, &(buttonArray[0]), &focusWindow)) {
                // Failed: Likely invalid mouseIndex.
                PsychErrorExitMsg(PsychError_user, "Invalid 'mouseIndex' provided. No such device.");
            }

            PsychCopyOutDoubleArg(1, kPsychArgOptional, (double) mx);
            PsychCopyOutDoubleArg(2, kPsychArgOptional, (double) my);

            // Return window focus state: Currently simply 0 for "not focused":
            PsychCopyOutDoubleArg(4, kPsychArgOptional, (double) (windowRecord && (windowRecord->targetSpecific.xwindowHandle == focusWindow)) ? 1 : 0);

            // Return optional valuator values: Currently empty due to numvaluators == 0:
            PsychCopyOutDoubleMatArg(5, kPsychArgOptional, (int) 1, (int) numvaluators, (int) 1, &myvaluators[0]);

            return(PsychError_none);
        }
        #endif

        if (mouseIndex >= 0) {
            // XInput-2 query for handling of multiple mouse pointers:

            // Query input device list for screen:
            int nDevices;
            XIDeviceInfo* indevs = PsychGetInputDevicesForScreen(screenNumber, &nDevices);

            // Sanity check:
            if (NULL == indevs) PsychErrorExitMsg(PsychError_user, "Sorry, your system does not support individual mouse pointer queries.");
            if (mouseIndex >= nDevices) PsychErrorExitMsg(PsychError_user, "Invalid 'mouseIndex' provided. No such device.");
            if ((indevs[mouseIndex].use != XIMasterPointer) && (indevs[mouseIndex].use != XISlavePointer) && (indevs[mouseIndex].use != XIFloatingSlave)) {
                PsychErrorExitMsg(PsychError_user, "Invalid 'mouseIndex' provided. Not a pointer device.");
            }

            // We requery the device info struct to retrieve updated live device state:
            // Crucial for slave pointers to get any state at all, but also needed on
            // master pointers to get the state of additional valuators, e.g., pen pressure,
            // touch area, tilt etc. for digitizer tablets, touch pads etc. For master pointers,
            // the primary 2 axis for 2D (x,y) position and the button/modifier state will be
            // queried via a dedicated XIQueryPointer() call, so that info gets overriden.
            PsychLockDisplay();
            indevs = XIQueryDevice(dpy, indevs[mouseIndex].deviceid, &numButtons);
            PsychUnlockDisplay();
            modifiers_return.effective = 0;

            // Query real number of mouse buttons and the raw button and axis state
            // stored inside the device itself. This is done mostly because slave pointer
            // devices don't support XIQueryPointer() so we get their relevant info from the
            // XIDeviceInfo struct itself:
            numButtons = 0;
            numvaluators = 0;
            memset(myvaluators, 0, sizeof(myvaluators));

            if (PsychIsArgPresent(PsychArgOut, 6)) {
                // Usercode wants valuator info structs:
                for (i = 0; i < indevs->num_classes; i++) if (indevs->classes[i]->type == XIValuatorClass) numIValuators++;
                PsychAllocOutStructArray(6, TRUE, numIValuators, numValuatorStructFieldNames, valuatorInfo, &valuatorStruct);
            }

            for (i = 0; i < indevs->num_classes; i++) {
                // printf("Class %i: Type %i\n", i, (int) indevs->classes[i]->type);
                if (indevs->classes[i]->type == XIButtonClass) {
                    // Number of buttons: For all pointers.
                    numButtons = ((XIButtonClassInfo*) indevs->classes[i])->num_buttons;

                    // Button state for slave pointers. Will get overriden for master pointers:
                    buttons_return.mask = ((XIButtonClassInfo*) indevs->classes[i])->state.mask;
                    buttons_return.mask_len = ((XIButtonClassInfo*) indevs->classes[i])->state.mask_len;
                }

                // Axis state for slave pointers. First two axis (x,y) will get overriden for master pointers:
                if (indevs->classes[i]->type == XIValuatorClass) {
                    XIValuatorClassInfo* axis = (XIValuatorClassInfo*) indevs->classes[i];
                    if (axis->number == 0) mxd = axis->value;  // x-Axis.
                    if (axis->number == 1) myd = axis->value;  // y-Axis.

                    // Additional axis, e.g., digitizer tablet, touchpads etc.:
                    if (axis->number >= 0 && axis->number < 100) {
                        myvaluators[axis->number] = axis->value;
                        numvaluators = (numvaluators >= axis->number + 1) ? numvaluators : axis->number + 1;
                    }

                    // Assign valuator info struct, if requested:
                    if (valuatorStruct) {
                        if (axis->label != None) {
                            PsychLockDisplay();
                            char* atomlabel =  XGetAtomName(dpy, axis->label);
                            PsychSetStructArrayStringElement("label", axis->number, atomlabel, valuatorStruct);
                            XFree(atomlabel);
                            PsychUnlockDisplay();
                        } else {
                            PsychSetStructArrayStringElement("label", axis->number, "None", valuatorStruct);
                        }

                        PsychSetStructArrayDoubleElement("min", axis->number, (double) axis->min, valuatorStruct);
                        PsychSetStructArrayDoubleElement("max", axis->number, (double) axis->max, valuatorStruct);
                        PsychSetStructArrayDoubleElement("resolution", axis->number, (double) axis->resolution, valuatorStruct);
                        PsychSetStructArrayDoubleElement("mode", axis->number, (double) axis->mode, valuatorStruct);
                        PsychSetStructArrayDoubleElement("sourceID", axis->number, (double) axis->sourceid, valuatorStruct);
                    }
                    // printf("AXIS %i, LABEL = %s, MIN = %f, MAX = %f, VAL = %f\n", axis->number, (char*) "NONE", (float) axis->min, (float) axis->max, (float) axis->value);
                }
            }

            // Add 32 buttons for modifier key state vector:
            numButtons += 32;

            // A real master pointer: Use official query for mouse devices.
            if (indevs->use == XIMasterPointer) {
                // Query pointer location and state:
                PsychLockDisplay();
                XIQueryPointer(dpy, indevs->deviceid, RootWindow(dpy, PsychGetXScreenIdForScreen(screenNumber)), &rootwin, &childwin, &mxd, &myd, &dxd, &dyd,
                               &buttons_return, &modifiers_return, &group_return);
                PsychUnlockDisplay();
            }

            // Copy out mouse x and y position:
            PsychCopyOutDoubleArg(1, kPsychArgOptional, mxd);
            PsychCopyOutDoubleArg(2, kPsychArgOptional, myd);

            // Copy out mouse button state:
            PsychAllocOutDoubleMatArg(3, kPsychArgOptional, (int)1, (int) numButtons, (int)1, &buttonArray);
            memset(buttonArray, 0, sizeof(double) * numButtons);

            if (numButtons > 0) {
                // Mouse buttons:
                const int buttonOffset = 1; // Buttons start at bit 1, not 0 for some strange reason? At least so on Ubuntu 10.10 and 11.10 with 2 mice and 1 joystick?
                for (i = buttonOffset; (i < numButtons - 32) && ((i / 8 ) < buttons_return.mask_len); i++) {
                    buttonArray[i - buttonOffset] = (double) ((buttons_return.mask[i / 8] & (1 << (i % 8))) ? 1 : 0);
                }

                // Free mask if retrieved via XIQueryPointer():
                if (indevs->use == XIMasterPointer) free(buttons_return.mask);

                // Append modifier key state from associated master keyboard. Last 32 entries:
                for (i = 0; i < 32; i++) {
                    buttonArray[numButtons - 32 + i] = (double) ((modifiers_return.effective & (1 << i)) ? 1 : 0);
                }
            }

            // Release live state info structure:
            XIFreeDeviceInfo(indevs);
        }
        else {
            // Old school core protocol query of virtual core pointer:
            PsychLockDisplay();
            XQueryPointer(dpy, RootWindow(dpy, PsychGetXScreenIdForScreen(screenNumber)), &rootwin, &childwin, &mx, &my, &dx, &dy, &mask_return);
            PsychUnlockDisplay();

            // Copy out mouse x and y position:
            PsychCopyOutDoubleArg(1, kPsychArgOptional, (double) mx);
            PsychCopyOutDoubleArg(2, kPsychArgOptional, (double) my);

            // Copy out mouse button state:
            PsychAllocOutDoubleMatArg(3, kPsychArgOptional, (int)1, (int)numButtons, (int)1, &buttonArray);

            // Bits 8, 9 and 10 of mask_return seem to correspond to mouse buttons
            // 1, 2 and 3 of a mouse for some weird reason. Bits 0-7 describe keyboard modifier keys
            // like Alt, Ctrl, Shift, ScrollLock, NumLock, CapsLock...
            // We remap here, so the first three returned entries correspond to the mouse buttons and
            // the rest is attached behind, if requested...

            // Mouse buttons: Left, Middle, Right == 0, 1, 2, aka 1,2,3 in Matlab space...
            for (i=0; i<numButtons && i<3; i++) {
                buttonArray[i] = (mask_return & (1<<(i+8))) ? 1 : 0;
            }

            // Modifier keys 0 to 7 appended:
            for (i=3; i<numButtons && i<3+8; i++) {
                buttonArray[i] = (mask_return & (1<<(i-3))) ? 1 : 0;
            }

            // Everything else appended:
            for (i=11; i<numButtons; i++) {
                buttonArray[i] = (mask_return & (1<<i)) ? 1 : 0;
            }
        }

        // Return optional 4th argument: Focus state. Returns 1 if our window has
        // keyboard input focus, zero otherwise:
        PsychLockDisplay();
        XGetInputFocus(dpy, &rootwin, &i);
        PsychUnlockDisplay();
        PsychCopyOutDoubleArg(4, kPsychArgOptional, (double) (rootwin == mywin) ? 1 : 0);

        // Return optional valuator values:
        PsychCopyOutDoubleMatArg(5, kPsychArgOptional, (int) 1, (int) numvaluators, (int) 1, &myvaluators[0]);
    }
    else {
        // 'KeyboardHelper' mode: We implement either KbCheck() or KbWait() via X11.
        // This is a hack to provide keyboard queries until a PsychHID() implementation
        // for Linux is available...

        // Special codes -10 to -15? --> Console keyboard queries:
        if(numButtons <= -10 && numButtons >= -15) {
            ConsoleInputHelper((int) numButtons);
            return(PsychError_none);
        }

        if (numButtons==-1 || numButtons==-2) {
            // KbCheck()/KbWait() mode:

            #ifdef PTB_USE_WAYLAND
                // Only implement KbCheck mode. KbWait mode isn't used anymore...

                // Alloc out keyboard state:
                PsychAllocOutBooleanMatArg(3, kPsychArgOptional, 1, 256, 1, &buttonStates);

                // Query Wayland backend for mouse state:
                if (!PsychWaylandGetKeyboardState(mouseIndex, 256, &(buttonStates[0]), &timestamp)) {
                    // Failed: Likely invalid mouseIndex.
                    PsychErrorExitMsg(PsychError_user, "Invalid 'keyboardIndex' provided. No such device.");
                }

                // Any key down?
                keysdown = 0;
                for (i = 0; i < 256; i++) keysdown += (unsigned int) buttonStates[i];

                // Copy out overall keystate:
                PsychCopyOutDoubleArg(1, kPsychArgOptional, (keysdown > 0) ? 1 : 0);

                // Copy out timestamp:
                PsychCopyOutDoubleArg(2, kPsychArgOptional, timestamp);

                return(PsychError_none);
            #endif

            // Switch X-Server into synchronous mode: We need this to get
            // a higher timing precision.
            PsychLockDisplay();
            XSynchronize(dpy, TRUE);
            PsychUnlockDisplay();

            do {
                // Reset overall key state to "none pressed":
                keysdown=0;

                // Request current keyboard state from X-Server:
                PsychLockDisplay();
                XQueryKeymap(dpy, keys_return);
                PsychUnlockDisplay();

                // Request current time of query:
                PsychGetAdjustedPrecisionTimerSeconds(&timestamp);

                // Any key down?
                for (i=0; i<32; i++) keysdown+=(unsigned int) keys_return[i];

                // We repeat until any key pressed if in KbWait() mode, otherwise we
                // exit the loop after first iteration in KbCheck mode.
                if ((numButtons==-1) || ((numButtons==-2) && (keysdown>0))) break;

                // Sleep for a few milliseconds before next KbWait loop iteration:
                PsychWaitIntervalSeconds(0.01);
            } while(1);

            if (numButtons==-2) {
                // Copy out time:
                PsychCopyOutDoubleArg(1, kPsychArgOptional, timestamp);
            }
            else {
                // KbCheck mode:

                // Copy out overall keystate:
                PsychCopyOutDoubleArg(1, kPsychArgOptional, (keysdown>0) ? 1 : 0);
                // copy out timestamp:
                PsychCopyOutDoubleArg(2, kPsychArgOptional, timestamp);
                // Copy keyboard state:
                PsychAllocOutBooleanMatArg(3, kPsychArgOptional, 1, 256, 1, &buttonStates);

                // Map 32 times 8 bitvector to 256 element return vector:
                for (i=0; i<32; i++) {
                    for(j=0; j<8; j++) {
                        buttonStates[i*8 + j] = (PsychNativeBooleanType)(keys_return[i] & (1<<j)) ? 1 : 0;
                    }
                }
            }
        }
        else if (numButtons == -3) {
            // numButtons == -3 --> KbName mapping mode:
            // Return the full keyboard keycode to ASCII character code mapping table...
            PsychAllocOutCellVector(1, kPsychArgOptional, 256, &kbNames);
            #ifdef PTB_USE_WAYLAND
                PsychWaylandGetKbNames(kbNames);
            #else
                for(i = 0; i < 256; i++) {
                    // Map keyboard scan code to KeySym:
                    PsychLockDisplay();
                    keystring = XKeysymToString(XKeycodeToKeysym(dpy, i, 0));
                    PsychUnlockDisplay();
                    if (keystring) {
                        // Character found: Return its ASCII name string:
                        PsychSetCellVectorStringElement(i, keystring, kbNames);
                    }
                    else {
                        // No character for this keycode:
                        PsychSetCellVectorStringElement(i, "", kbNames);
                    }
                }
            #endif
        }
        else if (numButtons == -4) {
            // GetChar() emulation. Dead.
        }
        else if (numButtons==-5) {
            // Priority() - helper mode: The 2nd argument is the priority level:

            // Query scheduling policy and priority:
            pthread_getschedparam(pthread_self(), &priorityLevel, &schedulingparam);

            // If scheduling mode is a realtime mode (RoundRobin realtime RR, or FIFO realtime),
            // then assign RT priority level (range 1-99) as current priorityLevel, otherwise
            // assign non realtime priority level zero:
            priorityLevel = (priorityLevel == SCHED_RR || priorityLevel == SCHED_FIFO) ? schedulingparam.sched_priority : 0;

            // Copy it out as optional return argument:
            PsychCopyOutDoubleArg(1, kPsychArgOptional, (double) priorityLevel);

            // Query if a new level should be set:
            priorityLevel = -1;
            PsychCopyInIntegerArg(2, kPsychArgOptional, &priorityLevel);

            errno=0;
            // Priority level provided?
            if (priorityLevel > -1) {
                // Map to new scheduling class:
                if (priorityLevel > 99 || priorityLevel < 0)
                    PsychErrorExitMsg(PsychErorr_argumentValueOutOfRange, "Invalid Priority level: Requested Priority() level must be between zero and 99!");

                if (priorityLevel > 0) {
                    // Realtime FIFO scheduling and all pages of Matlab/Octave locked into memory:
                    schedulingparam.sched_priority = priorityLevel;
                    priorityLevel = pthread_setschedparam(pthread_self(), SCHED_FIFO, &schedulingparam);
                    if (priorityLevel == -1) {
                        // Failed!
                        if(!PsychPrefStateGet_SuppressAllWarnings()) {
                            printf("PTB-ERROR: Failed to enable realtime-scheduling with Priority(%i) [%s]!\n", schedulingparam.sched_priority, strerror(errno));
                            if (errno==EPERM) {
                                printf("PTB-ERROR: You need to run Matlab/Octave with root-privileges, or run the script PsychLinuxConfiguration once for this to work.\n");
                            }
                        }
                        errno=0;
                    }
                    else {
                        // RT-Scheduling active. Lock all current and future memory:
                        priorityLevel = mlockall(MCL_CURRENT | MCL_FUTURE);
                        if (priorityLevel!=0) {
                            // Failed! Report problem as warning, but don't worry further.
                            if(!PsychPrefStateGet_SuppressAllWarnings())
                                printf("PTB-WARNING: Failed to enable system memory locking with Priority(%i) [%s]!\n", schedulingparam.sched_priority, strerror(errno));

                            // Undo any possibly partial mlocks....
                            munlockall();
                            errno=0;
                        }
                    }
                }
                else {
                    // Standard scheduling and no memory locking:
                    schedulingparam.sched_priority = 0;
                    priorityLevel = pthread_setschedparam(pthread_self(), SCHED_OTHER, &schedulingparam);
                    if (priorityLevel == -1) {
                        // Failed!
                        if(!PsychPrefStateGet_SuppressAllWarnings()) {
                            printf("PTB-ERROR: Failed to disable realtime-scheduling with Priority(%i) [%s]!\n", schedulingparam.sched_priority, strerror(errno));
                            if (errno==EPERM) {
                                printf("PTB-ERROR: You need to run Matlab/Octave with root-privileges, or run the script PsychLinuxConfiguration once for this to work.\n");
                            }
                        }
                        errno=0;
                    }

                    munlockall();
                    errno=0;
                }
                // End of setup of new Priority...
            }
            // End of Priority() helper for Linux.
        }
    }   // End of special functions handling for Linux...
#endif
    return(PsychError_none);
}
Example #10
0
bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const std::string &output, int *winstate)
{
  bool changeWindow = false;
  bool changeSize = false;
  float mouseX = 0.5;
  float mouseY = 0.5;

  if (!m_mainWindow)
  {
    CInputManager::GetInstance().SetMouseActive(false);
  }

  if (m_mainWindow && ((m_bFullScreen != fullscreen) || m_currentOutput.compare(output) != 0 || m_windowDirty))
  {
    // set mouse to last known position
    // we can't trust values after an xrr event
    if (m_bIsInternalXrr && m_MouseX >= 0 && m_MouseY >= 0)
    {
      mouseX = (float)m_MouseX/m_nWidth;
      mouseY = (float)m_MouseY/m_nHeight;
    }
    else if (!m_windowDirty)
    {
      Window root_return, child_return;
      int root_x_return, root_y_return;
      int win_x_return, win_y_return;
      unsigned int mask_return;
      bool isInWin = XQueryPointer(m_dpy, m_mainWindow, &root_return, &child_return,
                                   &root_x_return, &root_y_return,
                                   &win_x_return, &win_y_return,
                                   &mask_return);

      if (isInWin)
      {
        mouseX = (float)win_x_return/m_nWidth;
        mouseY = (float)win_y_return/m_nHeight;
      }
    }

    CInputManager::GetInstance().SetMouseActive(false);
    OnLostDevice();
    DestroyWindow();
    m_windowDirty = true;
  }

  // create main window
  if (!m_mainWindow)
  {
    EnableSystemScreenSaver(false);

    Colormap cmap;
    XSetWindowAttributes swa;
    XVisualInfo *vi;
    int x0 = 0;
    int y0 = 0;

    XOutput *out = g_xrandr.GetOutput(output);
    if (!out)
      out = g_xrandr.GetOutput(m_currentOutput);
    if (out)
    {
      m_nScreen = out->screen;
      x0 = out->x;
      y0 = out->y;
    }

    vi = GetVisual();
    if (!vi)
    {
      CLog::Log(LOGERROR, "Failed to find matching visual");
      return false;
    }

    cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone);

    bool hasWM = HasWindowManager();

    int def_vis = (vi->visual == DefaultVisual(m_dpy, vi->screen));
    swa.override_redirect = hasWM ? False : True;
    swa.border_pixel = fullscreen ? 0 : 5;
    swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0;
    swa.colormap = cmap;
    swa.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask |
                     ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
                     PropertyChangeMask | StructureNotifyMask | KeymapStateMask |
                     EnterWindowMask | LeaveWindowMask | ExposureMask;
    unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask;

    m_mainWindow = XCreateWindow(m_dpy, RootWindow(m_dpy, vi->screen),
                    x0, y0, width, height, 0, vi->depth,
                    InputOutput, vi->visual,
                    mask, &swa);

    swa.override_redirect = False;
    swa.border_pixel = 0;
    swa.event_mask = ExposureMask;
    mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWColormap | CWEventMask;

    m_glWindow = XCreateWindow(m_dpy, m_mainWindow,
                    0, 0, width, height, 0, vi->depth,
                    InputOutput, vi->visual,
                    mask, &swa);

    if (fullscreen && hasWM)
    {
      Atom fs = XInternAtom(m_dpy, "_NET_WM_STATE_FULLSCREEN", True);
      XChangeProperty(m_dpy, m_mainWindow, XInternAtom(m_dpy, "_NET_WM_STATE", True), XA_ATOM, 32, PropModeReplace, (unsigned char *) &fs, 1);
      // disable desktop compositing for KDE, when Kodi is in full-screen mode
      int one = 1;
      XChangeProperty(m_dpy, m_mainWindow, XInternAtom(m_dpy, "_KDE_NET_WM_BLOCK_COMPOSITING", True), XA_CARDINAL, 32,
                      PropModeReplace, (unsigned char*) &one,  1);
    }

    // define invisible cursor
    Pixmap bitmapNoData;
    XColor black;
    static char noData[] = { 0,0,0,0,0,0,0,0 };
    black.red = black.green = black.blue = 0;

    bitmapNoData = XCreateBitmapFromData(m_dpy, m_mainWindow, noData, 8, 8);
    m_invisibleCursor = XCreatePixmapCursor(m_dpy, bitmapNoData, bitmapNoData,
                                            &black, &black, 0, 0);
    XFreePixmap(m_dpy, bitmapNoData);
    XDefineCursor(m_dpy,m_mainWindow, m_invisibleCursor);
    XFree(vi);

    //init X11 events
    CWinEventsX11Imp::Init(m_dpy, m_mainWindow);

    changeWindow = true;
    changeSize = true;
  }

  if (!CWinEventsX11Imp::HasStructureChanged() && ((width != m_nWidth) || (height != m_nHeight)))
  {
    changeSize = true;
  }

  if (changeSize || changeWindow)
  {
    XResizeWindow(m_dpy, m_mainWindow, width, height);
  }

  if ((width != m_nWidth) || (height != m_nHeight) || changeWindow)
  {
    XResizeWindow(m_dpy, m_glWindow, width, height);
  }

  if (changeWindow)
  {
    m_icon = None;
    {
      CreateIconPixmap();
      XWMHints *wm_hints;
      XClassHint *class_hints;
      XTextProperty windowName, iconName;

      std::string titleString = CCompileInfo::GetAppName();
      std::string classString = titleString;
      char *title = (char*)titleString.c_str();

      XStringListToTextProperty(&title, 1, &windowName);
      XStringListToTextProperty(&title, 1, &iconName);

      wm_hints = XAllocWMHints();
      wm_hints->initial_state = NormalState;
      wm_hints->icon_pixmap = m_icon;
      wm_hints->flags = StateHint | IconPixmapHint;

      class_hints = XAllocClassHint();
      class_hints->res_class = (char*)classString.c_str();
      class_hints->res_name = (char*)classString.c_str();

      XSetWMProperties(m_dpy, m_mainWindow, &windowName, &iconName,
                            NULL, 0, NULL, wm_hints,
                            class_hints);
      XFree(class_hints);
      XFree(wm_hints);

      // register interest in the delete window message
      Atom wmDeleteMessage = XInternAtom(m_dpy, "WM_DELETE_WINDOW", False);
      XSetWMProtocols(m_dpy, m_mainWindow, &wmDeleteMessage, 1);
    }

    // placement of window may follow mouse
    XWarpPointer(m_dpy, None, m_mainWindow, 0, 0, 0, 0, mouseX*width, mouseY*height);

    XMapRaised(m_dpy, m_glWindow);
    XMapRaised(m_dpy, m_mainWindow);

    // discard events generated by creating the window, i.e. xrr events
    XSync(m_dpy, TRUE);

    if (winstate)
      *winstate = 1;
  }

  UpdateCrtc();

  return true;
}
Example #11
0
/******************************************************************************
  LoopOnEvents - Process all the X events we get
******************************************************************************/
void LoopOnEvents()
{
  int num;
  char buffer[10];
  XEvent Event;
  Window dummyroot,dummychild;
  int x,x1,y,y1;
  unsigned int dummy1;

  if (Transient && !Checked)
  {
    XQueryPointer(dpy,win,&dummyroot,&dummychild,&x1,&y1,&x,&y,&dummy1);
    num=WhichButton(&buttons,x,y);
    if (num!=-1)
    {
      Pressed=1;
      ButPressed=num;
      SwitchButton(&buttons,num);
    } else Pressed=0;
    Checked=1;
  }

  while(XPending(dpy))
  {
    XNextEvent(dpy,&Event);

    switch(Event.type)
    {
      case ButtonRelease:
        if (Pressed)
        {
          num=WhichButton(&buttons,Event.xbutton.x,Event.xbutton.y);
          if (num!=-1)
          {
            SendFvwmPipe(ClickAction[(Transient) ? 0:Event.xbutton.button-1],
              ItemID(&windows,num));
            SwitchButton(&buttons,num);
          }
        }
        if (Transient) ShutMeDown(0);
        Pressed=0;
        ButPressed=-1;
        break;
      case ButtonPress:
        num=WhichButton(&buttons,Event.xbutton.x,Event.xbutton.y);
        if (num != -1)
        {
          SwitchButton(&buttons,num);
          ButPressed=num;
        } else ButPressed=-1;
        Pressed=1;
        break;
      case Expose:
        if (Event.xexpose.count==0)
          RedrawWindow(1);
        break;
      case KeyPress:
        num=XLookupString(&Event.xkey,buffer,10,NULL,0);
        if (num==1)
        {
          if (buffer[0]=='q' || buffer[0]=='Q') ShutMeDown(0);
          else if (buffer[0]=='i' || buffer[0]=='I') PrintList(&windows);
          else if (buffer[0]=='b' || buffer[0]=='B') PrintButtons(&buttons);
        }
        break;
      case ClientMessage:
        if ((Event.xclient.format==32) && (Event.xclient.data.l[0]==wm_del_win))
          ShutMeDown(0);
      case EnterNotify:
        if (!SomeButtonDown(Event.xcrossing.state)) break;
        num=WhichButton(&buttons,Event.xcrossing.x,Event.xcrossing.y);
        if (num!=-1)
        {
          SwitchButton(&buttons,num);
          ButPressed=num;
        } else ButPressed=-1;
        Pressed=1;
        break;
      case LeaveNotify:
        if (!SomeButtonDown(Event.xcrossing.state)) break;
        if (ButPressed!=-1) SwitchButton(&buttons,ButPressed);
        Pressed=0;
        break;
      case MotionNotify:
        if (!Pressed) break;
        num=WhichButton(&buttons,Event.xmotion.x,Event.xmotion.y);
        if (num==ButPressed) break;
        if (ButPressed!=-1) SwitchButton(&buttons,ButPressed);
        if (num!=-1)
        {
          SwitchButton(&buttons,num);
          ButPressed=num;
        }
        else ButPressed=-1;

        break;
    }
  }
} 
Example #12
0
bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays)
{
  XOutput out;
  XMode mode;

  if (fullScreen)
  {
    out.name = res.strOutput;
    mode.w   = res.iWidth;
    mode.h   = res.iHeight;
    mode.hz  = res.fRefreshRate;
    mode.id  = res.strId;
  }
  else
  {
    out.name = CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP).strOutput;
    mode.w   = CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP).iWidth;
    mode.h   = CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP).iHeight;
    mode.hz  = CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP).fRefreshRate;
    mode.id  = CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP).strId;
  }
 
  XMode   currmode = g_xrandr.GetCurrentMode(out.name);
  if (!currmode.name.empty())
  {
    // flip h/w when rotated
    if (m_bIsRotated)
    {
      int w = mode.w;
      mode.w = mode.h;
      mode.h = w;
    }

    // only call xrandr if mode changes
    if (m_mainWindow)
    {
      if (currmode.w != mode.w || currmode.h != mode.h ||
          currmode.hz != mode.hz || currmode.id != mode.id)
      {
        CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr");

        // remember last position of mouse
        Window root_return, child_return;
        int root_x_return, root_y_return;
        int win_x_return, win_y_return;
        unsigned int mask_return;
        bool isInWin = XQueryPointer(m_dpy, m_mainWindow, &root_return, &child_return,
                                     &root_x_return, &root_y_return,
                                     &win_x_return, &win_y_return,
                                     &mask_return);

        if (isInWin)
        {
          m_MouseX = win_x_return;
          m_MouseY = win_y_return;
        }
        else
        {
          m_MouseX = -1;
          m_MouseY = -1;
        }

        OnLostDevice();
        m_bIsInternalXrr = true;
        g_xrandr.SetMode(out, mode);
        return true;
      }
    }
  }

  if (!SetWindow(res.iWidth, res.iHeight, fullScreen, m_userOutput))
    return false;

  m_nWidth      = res.iWidth;
  m_nHeight     = res.iHeight;
  m_bFullScreen = fullScreen;
  m_currentOutput = m_userOutput;

  return true;
}
Example #13
0
void _mouse_xy(int *ret, Window win) {
    if (!_check_init()) {
        return;
    }
    Window query_window;
    if(win == 0) {
        query_window = DefaultRootWindow(defaults->display);
        logit(LOG_LEVEL_EXTRA_VERBOSE, "%s", "Getting mouse xy against root window\n");
    } else {
        if(is_valid(win)) {
            query_window = find_outer_parent(win);
            logit(LOG_LEVEL_EXTRA_VERBOSE, "Getting mouse xy against window %lu\n", win);
        } else {
            fprintf(stderr, "Window %lu was not valid for xy -"
                    " returning absolute coordinates\n", win);
            _mouse_xy(ret, 0);
            return;
        }
    }

    //Both root xy and window xy come along for the ride.
    //Later we'll get the one we really want.
    Window root_return_ignored;
    Window child_return_ignored;
    int rootx;
    int rooty;
    int winx;
    int winy;
    unsigned int mask_return_ignored;
    int success =
        XQueryPointer(
            defaults->display,
            query_window,
            &root_return_ignored,
            &child_return_ignored,
            &rootx,
            &rooty,
            &winx,
            &winy,
            &mask_return_ignored);

    if(success) {
        if(is_valid(win)) {
            logit(LOG_LEVEL_EXTRA_VERBOSE,
                    "Mouse is at %d X %d relative to window %lu\n",
                    winx, winy, win);
            ret[0] = winx;
            ret[1] = winy;
        } else {
            logit(LOG_LEVEL_EXTRA_VERBOSE,
                    "Mouse is at %d X %d relative to the root window\n",
                    winx, winy);
            ret[0] = rootx;
            ret[1] = rooty;
        }
    } else {
        fprintf(stderr, "Query for mouse x and y failed.  Returning %d\n", INT_MIN);
        ret[0] = INT_MIN;
        ret[1] = INT_MIN;
    }
}
Example #14
0
/**
 * Initialize the x11 grab device demuxer (public device demuxer API).
 *
 * @param s1 Context from avformat core
 * @return <ul>
 *          <li>AVERROR(ENOMEM) no memory left</li>
 *          <li>AVERROR(EIO) other failure case</li>
 *          <li>0 success</li>
 *         </ul>
 */
static int x11grab_read_header(AVFormatContext *s1)
{
    X11GrabContext *x11grab = s1->priv_data;
    Display *dpy;
    AVStream *st = NULL;
    XImage *image;
    int x_off = 0, y_off = 0, ret = 0, screen, use_shm;
    char *param, *offset;
    AVRational framerate;

    param = av_strdup(s1->filename);
    if (!param)
        goto out;

    offset = strchr(param, '+');
    if (offset) {
        sscanf(offset, "%d,%d", &x_off, &y_off);
        x11grab->draw_mouse = !strstr(offset, "nomouse");
        *offset = 0;
    }

    ret = av_parse_video_size(&x11grab->width, &x11grab->height,
                              x11grab->video_size);
    if (ret < 0) {
        av_log(s1, AV_LOG_ERROR, "Couldn't parse video size.\n");
        goto out;
    }

    ret = av_parse_video_rate(&framerate, x11grab->framerate);
    if (ret < 0) {
        av_log(s1, AV_LOG_ERROR, "Could not parse framerate: %s.\n",
               x11grab->framerate);
        goto out;
    }
    av_log(s1, AV_LOG_INFO,
           "device: %s -> display: %s x: %d y: %d width: %d height: %d\n",
           s1->filename, param, x_off, y_off, x11grab->width, x11grab->height);

    dpy = XOpenDisplay(param);
    if (!dpy) {
        av_log(s1, AV_LOG_ERROR, "Could not open X display.\n");
        ret = AVERROR(EIO);
        goto out;
    }

    st = avformat_new_stream(s1, NULL);
    if (!st) {
        ret = AVERROR(ENOMEM);
        goto out;
    }
    avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */

    screen = DefaultScreen(dpy);

    if (x11grab->follow_mouse) {
        int screen_w, screen_h;
        Window w;

        screen_w = DisplayWidth(dpy, screen);
        screen_h = DisplayHeight(dpy, screen);
        XQueryPointer(dpy, RootWindow(dpy, screen), &w, &w, &x_off, &y_off,
                      &ret, &ret, &ret);
        x_off -= x11grab->width / 2;
        y_off -= x11grab->height / 2;
        x_off  = FFMIN(FFMAX(x_off, 0), screen_w - x11grab->width);
        y_off  = FFMIN(FFMAX(y_off, 0), screen_h - x11grab->height);
        av_log(s1, AV_LOG_INFO,
               "followmouse is enabled, resetting grabbing region to x: %d y: %d\n",
               x_off, y_off);
    }

    use_shm = XShmQueryExtension(dpy);
    av_log(s1, AV_LOG_INFO,
           "shared memory extension %sfound\n", use_shm ? "" : "not ");

    if (use_shm && setup_shm(s1, dpy, &image) < 0) {
        av_log(s1, AV_LOG_WARNING, "Falling back to XGetImage\n");
        use_shm = 0;
    }

    if (!use_shm) {
        image = XGetImage(dpy, RootWindow(dpy, screen),
                          x_off, y_off,
                          x11grab->width, x11grab->height,
                          AllPlanes, ZPixmap);
    }

    if (x11grab->draw_mouse && setup_mouse(dpy, screen) < 0) {
        av_log(s1, AV_LOG_WARNING,
               "XFixes not available, cannot draw the mouse cursor\n");
        x11grab->draw_mouse = 0;
    }

    x11grab->frame_size = x11grab->width * x11grab->height * image->bits_per_pixel / 8;
    x11grab->dpy        = dpy;
    x11grab->time_base  = (AVRational) { framerate.den, framerate.num };
    x11grab->time_frame = av_gettime() / av_q2d(x11grab->time_base);
    x11grab->x_off      = x_off;
    x11grab->y_off      = y_off;
    x11grab->image      = image;
    x11grab->use_shm    = use_shm;

    ret = pixfmt_from_image(s1, image, &st->codec->pix_fmt);
    if (ret < 0)
        goto out;

    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    st->codec->codec_id   = AV_CODEC_ID_RAWVIDEO;
    st->codec->width      = x11grab->width;
    st->codec->height     = x11grab->height;
    st->codec->time_base  = x11grab->time_base;
    st->codec->bit_rate   = x11grab->frame_size * 1 / av_q2d(x11grab->time_base) * 8;

out:
    av_free(param);
    return ret;
}
Example #15
0
void KillWindow::start()
{
    static Cursor kill_cursor = 0;
    if(!kill_cursor)
        kill_cursor = XCreateFontCursor(qt_xdisplay(), XC_pirate);

    if(XGrabPointer(qt_xdisplay(), qt_xrootwin(), False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask,
                    GrabModeAsync, GrabModeAsync, None, kill_cursor, CurrentTime)
       == GrabSuccess)
    {
        XGrabKeyboard(qt_xdisplay(), qt_xrootwin(), False, GrabModeAsync, GrabModeAsync, CurrentTime);

        XEvent ev;
        int return_pressed = 0;
        int escape_pressed = 0;
        int button_released = 0;

        grabXServer();

        while(!return_pressed && !escape_pressed && !button_released)
        {
            XMaskEvent(qt_xdisplay(), KeyPressMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask, &ev);

            if(ev.type == KeyPress)
            {
                int kc = XKeycodeToKeysym(qt_xdisplay(), ev.xkey.keycode, 0);
                int mx = 0;
                int my = 0;
                return_pressed = (kc == XK_Return) || (kc == XK_space);
                escape_pressed = (kc == XK_Escape);
                if(kc == XK_Left)
                    mx = -10;
                if(kc == XK_Right)
                    mx = 10;
                if(kc == XK_Up)
                    my = -10;
                if(kc == XK_Down)
                    my = 10;
                if(ev.xkey.state & ControlMask)
                {
                    mx /= 10;
                    my /= 10;
                }
                QCursor::setPos(QCursor::pos() + QPoint(mx, my));
            }

            if(ev.type == ButtonRelease)
            {
                button_released = (ev.xbutton.button == Button1);
                if(ev.xbutton.button == Button3)
                {
                    escape_pressed = TRUE;
                    break;
                }
                if(ev.xbutton.button == Button1 || ev.xbutton.button == Button2)
                    workspace->killWindowId(ev.xbutton.subwindow);
            }
            continue;
        }
        if(return_pressed)
        {
            Window root, child;
            int dummy1, dummy2, dummy3, dummy4;
            unsigned int dummy5;
            if(XQueryPointer(qt_xdisplay(), qt_xrootwin(), &root, &child, &dummy1, &dummy2, &dummy3, &dummy4, &dummy5) == true && child != None)
                workspace->killWindowId(child);
        }

        ungrabXServer();

        XUngrabKeyboard(qt_xdisplay(), CurrentTime);
        XUngrabPointer(qt_xdisplay(), CurrentTime);
    }
}
Example #16
0
void
draw_swarm(ModeInfo * mi)
{
	Display    *display = MI_DISPLAY(mi);
	Window      window = MI_WINDOW(mi);
	GC          gc = MI_GC(mi);
	int         b, newlimit;
	Bool        track_p = trackmouse;
	int         cx, cy;
	short       prev;
	float       speed;
	swarmstruct *sp;

	if (swarms == NULL)
		return;
	sp = &swarms[MI_SCREEN(mi)];
	if (sp->segs == NULL)
		return;

	MI_IS_DRAWN(mi) = True;
	if (track_p) {
		Window      r, c;
		int         rx, ry;
		unsigned int m;

		(void) XQueryPointer(display, window,
				     &r, &c, &rx, &ry, &cx, &cy, &m);
		if (cx <= sp->border || cy <= sp->border ||
		    cx >= MI_WIDTH(mi) - 1 - sp->border ||
		    cy >= MI_HEIGHT(mi) - 1 - sp->border)
			track_p = False;
	}
	/* <=- Wasp -=> */
	/* Age the arrays. */
	sp->wx[2] = sp->wx[1];
	sp->wx[1] = sp->wx[0];
	sp->wy[2] = sp->wy[1];
	sp->wy[1] = sp->wy[0];
	if (track_p) {
		sp->wx[0] = cx;
		sp->wy[0] = cy;
	} else {

		/* Accelerate */
		sp->wxv += balance_rand(WASPACC);
		sp->wyv += balance_rand(WASPACC);

		/* Speed Limit Checks */
		speed = sqrt((double) sp->wxv * sp->wxv + sp->wyv * sp->wyv);
		if (speed > WASPVEL) {
			newlimit = (int) ((NRAND(WASPVEL) + WASPVEL / 2) / speed);
			sp->wxv *= newlimit;
			sp->wyv *= newlimit;
		}
		/* Move */
		sp->wx[0] = sp->wx[1] + sp->wxv;
		sp->wy[0] = sp->wy[1] + sp->wyv;

		/* Bounce Checks */
		if ((sp->wx[0] < sp->border) || (sp->wx[0] > sp->width - sp->border - 1)) {
			sp->wxv = -sp->wxv;
			sp->wx[0] += sp->wxv;
		}
		if ((sp->wy[0] < sp->border) || (sp->wy[0] > sp->height - sp->border - 1)) {
			sp->wyv = -sp->wyv;
			sp->wy[0] += sp->wyv;
		}
		/* Don't let things settle down. */
		sp->xv[NRAND(sp->beecount)] += balance_rand(3);
		sp->yv[NRAND(sp->beecount)] += balance_rand(3);
	}
	/* <=- Bees -=> */
	sp->tick = ++(sp->tick) % (sp->taillen);
	prev = (sp->tick) ? sp->tick - 1 : sp->taillen - 1;
	if (sp->tick == sp->taillen - 1)
		sp->rolloverflag = 1;
	for (b = 0; b < sp->beecount; b++) {
		int         distance, dx, dy;

		/* Accelerate */
		dx = (int) (sp->wx[1] - X(prev, b));
		dy = (int) (sp->wy[1] - Y(prev, b));
		distance = (int) sqrt((double) dx * dx + dy * dy);
		if (distance == 0)
			distance = 1;
		sp->xv[b] += dx * BEEACC / (2 * distance);
		sp->yv[b] += dy * BEEACC / (2 * distance);

		/* Speed Limit Checks */
		speed = sqrt(sp->xv[b] * sp->xv[b] + sp->yv[b] * sp->yv[b]);
		if (speed > BEEVEL) {
			newlimit = (int) ((NRAND(BEEVEL) + BEEVEL / 2) / speed);
			sp->xv[b] *= newlimit;
			sp->yv[b] *= newlimit;
		}
		/* Move */
		X(sp->tick, b) = X(prev, b) + sp->xv[b];
		Y(sp->tick, b) = Y(prev, b) + sp->yv[b];

		/* Fill the segment lists. */
		sp->segs[b].x1 = (short) X(sp->tick, b);
		sp->segs[b].y1 = (short) Y(sp->tick, b);
		sp->segs[b].x2 = (short) X(prev, b);
		sp->segs[b].y2 = (short) Y(prev, b);
		sp->old_segs[b].x1 = (short) X(((sp->tick+2)%sp->taillen), b);
		sp->old_segs[b].y1 = (short) Y(((sp->tick+2)%sp->taillen), b);
		sp->old_segs[b].x2 = (short) X(((sp->tick+1)%sp->taillen), b);
		sp->old_segs[b].y2 = (short) Y(((sp->tick+1)%sp->taillen), b);
	}

	XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
	XDrawLine(display, window, gc,
		  sp->wx[1], sp->wy[1], sp->wx[2], sp->wy[2]);
	if (sp->rolloverflag) {
		XDrawSegments(display, window, gc, sp->old_segs, sp->beecount);
	}
	XSetForeground(display, gc, MI_WHITE_PIXEL(mi));
	XDrawLine(display, window, gc,
		  sp->wx[0], sp->wy[0], sp->wx[1], sp->wy[1]);
	if (MI_NPIXELS(mi) > 2) {
		XSetForeground(display, gc, MI_PIXEL(mi, sp->pix));
		if (++sp->pix >= MI_NPIXELS(mi))
			sp->pix = 0;
	}
	XDrawSegments(display, window, gc, sp->segs, sp->beecount);
}
void getInput(Display *display, Window root, char* devName) {
    int fd, rd, i, root_x, root_y;
    struct input_event ev[64];
    Window window_returned;
    int win_x, win_y;
    unsigned int mask_return;
    int prev_x, prev_y;

    int slots = 0;

    fd = open(devName, O_RDONLY);

    if(fd < 0) {
        printf("Error Opening device. Are you root?\n");
    }

    while(1) {
        rd = read(fd, ev, sizeof(struct input_event) * 64);

        if(rd < (int) sizeof(struct input_event)) {
            printf("Error Reading Input");
        }

        for(i = 0; i < rd / sizeof(struct input_event); i++) {
            if(ev[i].code >= 47 && ev[i].code <= 60) {
                //Get current pointer information
                XQueryPointer(display, root, &window_returned,
                              &window_returned, &root_x, &root_y, &win_x, &win_y,
                              &mask_return);

                int ii;

                //Fill the slots
                if(ev[i].code == ABS_MT_SLOT && (ev[i].value - slots) == 1){
                    slots++;
                    printf("ADD SLOTS: %d\n",slots);
                }

                //X-Axis
                if(ev[i].code == ABS_MT_POSITION_X) {
                    mouseMove(display, root, ev[i].value, root_y);
                    prev_x = ev[i].value;
                }
                //Y-Axis
                if(ev[i].code == ABS_MT_POSITION_Y) {
                    mouseMove(display, root, root_x, ev[i].value);
                    prev_y = ev[i].value;
                }

                if(ev[i].code == ABS_MT_TRACKING_ID && ev[i].value == -1){
                    
                    slots--;
                    printf("REMOVE SLOTS: %d\n",slots);
                    
                    //We can click with one slot ;)
                    /*if(slots == 0){
                        mouseClick(display, root, Button1);
                    }*/
                    mouseClick(display, root, Button1);
                }
            }
        }

    }

    close(fd);

}
Example #18
0
File: CheckBox.c Project: att/uwin
void EvtMouseCheckBox(struct XObj *xobj, XButtonEvent *EvtButton)
{
  static XEvent event;
  int End = 1;
  unsigned int modif;
  int x1,x2,y1,y2;
  Window Win1,Win2;
  Window WinBut = 0;
  int In = 0;
  XSegment segm[2];
  int asc,desc,dir;
  XCharStruct struc;
  
  while (End)
  {
    XNextEvent(dpy, &event);
    switch (event.type)
    {
    case EnterNotify:
      XQueryPointer(dpy, *xobj->ParentWin,
		    &Win1, &Win2, &x1, &y1, &x2, &y2, &modif);
      if (WinBut == 0)
      {
	WinBut = Win2;
	/* Mouse on button */
	XTextExtents(xobj->xfont, "lp", strlen("lp"), &dir, &asc, &desc, &struc);
	DrawReliefRect(0, asc-11, xobj->height, xobj->height, xobj, shad, hili);
	In = 1;
      }
      else
      {
	if (Win2 == WinBut)
	{
	  /* Mouse on button */
	  DrawReliefRect(0, asc-11, xobj->height, xobj->height,
			 xobj, shad, hili);
	  In = 1;
	}
	else if (In)
	{
	  In = 0;
	  /* Mouse not on button */
	  DrawReliefRect(0, asc-11, xobj->height, xobj->height,
			 xobj, hili, shad);
	}
      }
      break;
    case LeaveNotify:
      XQueryPointer(dpy, *xobj->ParentWin,
		    &Win1, &Win2, &x1, &y1, &x2, &y2, &modif);
      if (Win2 == WinBut)
      {
	In = 1;
	/* Mouse on button */
	DrawReliefRect(0, asc-11, xobj->height, xobj->height, xobj, shad, hili);
      }
      else if (In)
      {
	/* Mouse not on button */
	DrawReliefRect(0, asc-11, xobj->height, xobj->height, xobj, hili, shad);
	In = 0;
      }
      break;
    case ButtonRelease:
      End = 0;
      /* Mouse not on button */
      if (In)
      {
	/* Envoie d'un message vide de type SingleClic pour un clique souris */
	xobj->value = !xobj->value;
	DrawReliefRect(0, asc-11, xobj->height, xobj->height, xobj, hili, shad);
	SendMsg(xobj,SingleClic);
      }
      if (xobj->value)
      {
	XSetLineAttributes(dpy, xobj->gc, 2,
			   LineSolid, CapProjecting, JoinMiter);
	segm[0].x1 = 5;
	segm[0].y1 = 5;
	segm[0].x2 = xobj->height - 6;
	segm[0].y2 = xobj->height - 6;
	segm[1].x1 = 5;
	segm[1].y1 = xobj->height - 6;
	segm[1].x2 = xobj->height - 6;
	segm[1].y2 = 5;
	XSetForeground(dpy, xobj->gc, xobj->TabColor[fore]);
	XDrawSegments(dpy, xobj->win, xobj->gc, segm, 2);
	XSetLineAttributes(dpy, xobj->gc, 1, LineSolid, CapRound, JoinMiter);
      }
      else
      {
	XClearArea(dpy, xobj->win, 4, 4, xobj->height-8, xobj->height-8, False);
      }
      break;
    }
  }
}
Example #19
0
void
make_splash_dialog (saver_info *si)
{
  int x, y, bw;
  XSetWindowAttributes attrs;
  unsigned long attrmask = 0;
  splash_dialog_data *sp;
  saver_screen_info *ssi;
  Colormap cmap;
  char *f;

  if (si->sp_data)
    return;
  if (!si->prefs.splash_p ||
      si->prefs.splash_duration <= 0)
    return;

  ssi = &si->screens[mouse_screen (si)];
  cmap = DefaultColormapOfScreen (ssi->screen);

  sp = (splash_dialog_data *) calloc (1, sizeof(*sp));
  sp->prompt_screen = ssi;

  sp->heading_label = get_string_resource (si->dpy,
                                           "splash.heading.label",
					   "Dialog.Label.Label");
  sp->body_label = get_string_resource (si->dpy,
                                        "splash.body.label",
					"Dialog.Label.Label");
  sp->body2_label = get_string_resource (si->dpy,
                                         "splash.body2.label",
					 "Dialog.Label.Label");
  sp->demo_label = get_string_resource (si->dpy,
                                        "splash.demo.label",
					"Dialog.Button.Label");
#ifdef PREFS_BUTTON
  sp->prefs_label = get_string_resource (si->dpy,
                                         "splash.prefs.label",
					"Dialog.Button.Label");
#endif /* PREFS_BUTTON */
  sp->help_label = get_string_resource (si->dpy,
                                        "splash.help.label",
					"Dialog.Button.Label");

  if (!sp->heading_label)
    sp->heading_label = strdup("ERROR: REESOURCES NOT INSTALLED CORRECTLY");
  if (!sp->body_label)
    sp->body_label = strdup("ERROR: REESOURCES NOT INSTALLED CORRECTLY");
  if (!sp->body2_label)
    sp->body2_label = strdup("ERROR: REESOURCES NOT INSTALLED CORRECTLY");
  if (!sp->demo_label) sp->demo_label = strdup("ERROR");
#ifdef PREFS_BUTTON
  if (!sp->prefs_label) sp->prefs_label = strdup("ERROR");
#endif /* PREFS_BUTTON */
  if (!sp->help_label) sp->help_label = strdup("ERROR");

  /* Put the version number in the label. */
  {
    char *s = (char *) malloc (strlen(sp->heading_label) + 20);
    sprintf(s, sp->heading_label, si->version);
    free (sp->heading_label);
    sp->heading_label = s;
  }

  f = get_string_resource (si->dpy, "splash.headingFont", "Dialog.Font");
  sp->heading_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
  if (!sp->heading_font) sp->heading_font = XLoadQueryFont (si->dpy, "fixed");
  if (f) free (f);

  f = get_string_resource(si->dpy, "splash.bodyFont", "Dialog.Font");
  sp->body_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
  if (!sp->body_font) sp->body_font = XLoadQueryFont (si->dpy, "fixed");
  if (f) free (f);

  f = get_string_resource(si->dpy, "splash.buttonFont", "Dialog.Font");
  sp->button_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
  if (!sp->button_font) sp->button_font = XLoadQueryFont (si->dpy, "fixed");
  if (f) free (f);

  sp->foreground = get_pixel_resource (si->dpy, cmap,
                                       "splash.foreground",
				       "Dialog.Foreground");
  sp->background = get_pixel_resource (si->dpy, cmap, 
                                       "splash.background",
				       "Dialog.Background");

  if (sp->foreground == sp->background)
    {
      /* Make sure the error messages show up. */
      sp->foreground = BlackPixelOfScreen (ssi->screen);
      sp->background = WhitePixelOfScreen (ssi->screen);
    }

  sp->button_foreground = get_pixel_resource (si->dpy, cmap,
                                              "splash.Button.foreground",
					      "Dialog.Button.Foreground");
  sp->button_background = get_pixel_resource (si->dpy, cmap,
                                              "splash.Button.background",
					      "Dialog.Button.Background");
  sp->shadow_top = get_pixel_resource (si->dpy, cmap,
                                       "splash.topShadowColor",
				       "Dialog.Foreground");
  sp->shadow_bottom = get_pixel_resource (si->dpy, cmap,
                                          "splash.bottomShadowColor",
					  "Dialog.Background");

  sp->logo_width = get_integer_resource (si->dpy, 
                                         "splash.logo.width",
					 "Dialog.Logo.Width");
  sp->logo_height = get_integer_resource (si->dpy, 
                                          "splash.logo.height",
					  "Dialog.Logo.Height");
  sp->internal_border = get_integer_resource (si->dpy, 
                                              "splash.internalBorderWidth",
					      "Dialog.InternalBorderWidth");
  sp->shadow_width = get_integer_resource (si->dpy, 
                                           "splash.shadowThickness",
					   "Dialog.ShadowThickness");

  if (sp->logo_width == 0)  sp->logo_width = 150;
  if (sp->logo_height == 0) sp->logo_height = 150;
  if (sp->internal_border == 0) sp->internal_border = 15;
  if (sp->shadow_width == 0) sp->shadow_width = 4;

  {
    int direction, ascent, descent;
    XCharStruct overall;

    sp->width = 0;
    sp->height = 0;

    /* Measure the heading_label. */
    XTextExtents (sp->heading_font,
		  sp->heading_label, strlen(sp->heading_label),
		  &direction, &ascent, &descent, &overall);
    if (overall.width > sp->width) sp->width = overall.width;
    sp->height += ascent + descent;

    /* Measure the body_label. */
    XTextExtents (sp->body_font,
		  sp->body_label, strlen(sp->body_label),
		  &direction, &ascent, &descent, &overall);
    if (overall.width > sp->width) sp->width = overall.width;
    sp->height += ascent + descent;

    /* Measure the body2_label. */
    XTextExtents (sp->body_font,
		  sp->body2_label, strlen(sp->body2_label),
		  &direction, &ascent, &descent, &overall);
    if (overall.width > sp->width) sp->width = overall.width;
    sp->height += ascent + descent;

    {
      Dimension w2 = 0, w3 = 0, w4 = 0;
      Dimension h2 = 0, h3 = 0, h4 = 0;

      /* Measure the Demo button. */
      XTextExtents (sp->button_font,
		    sp->demo_label, strlen(sp->demo_label),
		    &direction, &ascent, &descent, &overall);
      w2 = overall.width;
      h2 = ascent + descent;

#ifdef PREFS_BUTTON
      /* Measure the Prefs button. */
      XTextExtents (sp->button_font,
		    sp->prefs_label, strlen(sp->prefs_label),
		    &direction, &ascent, &descent, &overall);
      w3 = overall.width;
      h3 = ascent + descent;
#else  /* !PREFS_BUTTON */
      w3 = 0;
      h3 = 0;
#endif /* !PREFS_BUTTON */

      /* Measure the Help button. */
      XTextExtents (sp->button_font,
		    sp->help_label, strlen(sp->help_label),
		    &direction, &ascent, &descent, &overall);
      w4 = overall.width;
      h4 = ascent + descent;

      w2 = MAX(w2, w3); w2 = MAX(w2, w4);
      h2 = MAX(h2, h3); h2 = MAX(h2, h4);

      /* Add some horizontal padding inside the buttons. */
      w2 += ascent;

      w2 += ((ascent + descent) / 2) + (sp->shadow_width * 2);
      h2 += ((ascent + descent) / 2) + (sp->shadow_width * 2);

      sp->button_width = w2;
      sp->button_height = h2;

#ifdef PREFS_BUTTON
      w2 *= 3;
#else  /* !PREFS_BUTTON */
      w2 *= 2;
#endif /* !PREFS_BUTTON */

      w2 += ((ascent + descent) * 2);  /* for space between buttons */

      if (w2 > sp->width) sp->width = w2;
      sp->height += h2;
    }

    sp->width  += (sp->internal_border * 2);
    sp->height += (sp->internal_border * 3);

    if (sp->logo_height > sp->height)
      sp->height = sp->logo_height;
    else if (sp->height > sp->logo_height)
      sp->logo_height = sp->height;

    sp->logo_width = sp->logo_height;

    sp->width += sp->logo_width;
  }

  attrmask |= CWOverrideRedirect; attrs.override_redirect = True;
  attrmask |= CWEventMask;
  attrs.event_mask = (ExposureMask | ButtonPressMask | ButtonReleaseMask);

  {
    int sx, sy, w, h;
    int mouse_x = 0, mouse_y = 0;

    {
      Window pointer_root, pointer_child;
      int root_x, root_y, win_x, win_y;
      unsigned int mask;
      if (XQueryPointer (si->dpy,
                         RootWindowOfScreen (ssi->screen),
                         &pointer_root, &pointer_child,
                         &root_x, &root_y, &win_x, &win_y, &mask))
        {
          mouse_x = root_x;
          mouse_y = root_y;
        }
    }

    get_screen_viewport (ssi, &sx, &sy, &w, &h, mouse_x, mouse_y, False);
    if (si->prefs.debug_p) w /= 2;
    x = sx + (((w + sp->width)  / 2) - sp->width);
    y = sy + (((h + sp->height) / 2) - sp->height);
    if (x < sx) x = sx;
    if (y < sy) y = sy;
  }

  bw = get_integer_resource (si->dpy, 
                             "splash.borderWidth",
                             "Dialog.BorderWidth");

  si->splash_dialog =
    XCreateWindow (si->dpy,
		   RootWindowOfScreen(ssi->screen),
		   x, y, sp->width, sp->height, bw,
		   DefaultDepthOfScreen (ssi->screen), InputOutput,
		   DefaultVisualOfScreen(ssi->screen),
		   attrmask, &attrs);
  XSetWindowBackground (si->dpy, si->splash_dialog, sp->background);

  sp->logo_pixmap = xscreensaver_logo (ssi->screen, 
                                       /* same visual as si->splash_dialog */
                                       DefaultVisualOfScreen (ssi->screen),
                                       si->splash_dialog, cmap,
                                       sp->background, 
                                       &sp->logo_pixels, &sp->logo_npixels,
                                       &sp->logo_clipmask, True);

  XMapRaised (si->dpy, si->splash_dialog);
  XSync (si->dpy, False);

  si->sp_data = sp;

  sp->timer = XtAppAddTimeOut (si->app, si->prefs.splash_duration,
			       unsplash_timer, (XtPointer) si);

  draw_splash_window (si);
  XSync (si->dpy, False);
}
Example #20
0
/****************************************************************************
 *
 * Initiates a menu pop-up
 *
 * Style = 1 = sticky menu, stays up on initial button release.
 * Style = 0 = transient menu, drops on initial release.
 ***************************************************************************/
int do_menu(MenuRoot * menu, int style)
{
  int prevStashedX = 0, prevStashedY = 0;
  MenuRoot *PrevActiveMenu = 0;
  MenuItem *PrevActiveItem = 0;
  int retval = MENU_NOP;
  int x, y;
  Time t0;
  extern Time lastTimestamp;
  int PrevMenuX = PrevActiveMenuX;

  /* this condition could get ugly */
  if (menu->in_use)
    return MENU_ERROR;

  /* In case we wind up with a move from a menu which is
   * from a window border, we'll return to here to start
   * the move */
  XQueryPointer(dpy, Scr.Root, &JunkRoot, &JunkChild,
		&x, &y, &JunkX, &JunkY, &JunkMask);

  if (menu_on) {
    prevStashedX = Stashed_X;
    prevStashedY = Stashed_Y;

    PrevActiveMenu = ActiveMenu;
    PrevActiveItem = ActiveItem;

    if (ActiveMenu)
      x = Stashed_X + ActiveMenu->width - 3;

    if (ActiveItem)
      y = ActiveItem->y_offset + MenuY;
  } else {
    mouse_moved = 0;
    t0 = lastTimestamp;
    if (!GrabEm(MENU)) {
      XBell(dpy, Scr.screen);
      return MENU_DONE;
    }
    x += 2;
  }
  if (PopUpMenu(menu, x, y)) {
    retval = UpdateMenu(style);
  } else
    XBell(dpy, Scr.screen);

  ActiveMenu = PrevActiveMenu;
  ActiveItem = PrevActiveItem;
  if ((ActiveItem) && (menu_on))
    ActiveItem->state = 1;
  Stashed_X = prevStashedX;
  Stashed_Y = prevStashedY;


  if (!menu_on) {
    UngrabEm();
    WaitForButtonsUp();
  }
  if (((lastTimestamp - t0) < 3 * Scr.ClickTime) && (mouse_moved == 0))
    menu_aborted = 1;
  else
    menu_aborted = 0;

  PrevActiveMenuX = PrevMenuX;
  return retval;
}
Example #21
0
void KSnapshot::performGrab()
{
    grabber->releaseMouse();
    grabber->hide();
    grabTimer.stop();
    XGrabServer( qt_xdisplay());
    if ( mainWidget->mode() == WindowUnderCursor ) {
        Window root;
        Window child;
        uint mask;
        int rootX, rootY, winX, winY;
        XQueryPointer( qt_xdisplay(), qt_xrootwin(), &root, &child,
                   &rootX, &rootY, &winX, &winY,
                   &mask);
        if( child == None )
            child = qt_xrootwin();
        if( !mainWidget->includeDecorations()) {
            Window real_child = findRealWindow( child );
            if( real_child != None ) // test just in case
                child = real_child;
        }
        int x, y;
        unsigned int w, h;
        unsigned int border;
        unsigned int depth;
        XGetGeometry( qt_xdisplay(), child, &root, &x, &y,
                  &w, &h, &border, &depth );
        w += 2 * border;
        h += 2 * border;

        Window parent;
        Window* children;
        unsigned int nchildren;
        if( XQueryTree( qt_xdisplay(), child, &root, &parent,
                &children, &nchildren ) != 0 ) {
            if( children != NULL )
                XFree( children );
            int newx, newy;
            Window dummy;
            if( XTranslateCoordinates( qt_xdisplay(), parent, qt_xrootwin(),
                           x, y, &newx, &newy, &dummy )) {
                x = newx;
                y = newy;
            }
        }

        snapshot = QPixmap::grabWindow( qt_xrootwin(), x, y, w, h );

#ifdef HAVE_X11_EXTENSIONS_SHAPE_H
        //No XShape - no work.
        if (haveXShape) {
            QBitmap mask(w, h);
            //As the first step, get the mask from XShape.
            int count, order;
            XRectangle* rects = XShapeGetRectangles( qt_xdisplay(), child,
                                 ShapeBounding, &count, &order);
            //The ShapeBounding region is the outermost shape of the window;
            //ShapeBounding - ShapeClipping is defined to be the border.
            //Since the border area is part of the window, we use bounding
            // to limit our work region
            if (rects) {
                //Create a QRegion from the rectangles describing the bounding mask.
                QRegion contents;
                for (int pos = 0; pos < count; pos++)
                    contents += QRegion(rects[pos].x, rects[pos].y,
                                rects[pos].width, rects[pos].height);
                XFree(rects);

                //Create the bounding box.
                QRegion bbox(0, 0, snapshot.width(), snapshot.height());
                
                if( border > 0 ) {
                    contents.translate( border, border );
                    contents += QRegion( 0, 0, border, h );
                    contents += QRegion( 0, 0, w, border );
                    contents += QRegion( 0, h - border, w, border );
                    contents += QRegion( w - border, 0, border, h );
                }
                
                //Get the masked away area.
                QRegion maskedAway = bbox - contents;
                QMemArray<QRect> maskedAwayRects = maskedAway.rects();

                //Construct a bitmap mask from the rectangles
                QPainter p(&mask);
                p.fillRect(0, 0, w, h, Qt::color1);
                for (uint pos = 0; pos < maskedAwayRects.count(); pos++)
                    p.fillRect(maskedAwayRects[pos], Qt::color0);
                p.end();

                snapshot.setMask(mask);
            }
        }
#endif
    }
    else {
        snapshot = QPixmap::grabWindow( qt_xrootwin() );
    }
    XUngrabServer( qt_xdisplay());
    updatePreview();
    QApplication::restoreOverrideCursor();
    modified = true;
//     show();
    slotOk();
}
Example #22
0
// ---------------------------------------------------------------------------
void X11WindowImpl::processEvent(XEvent& ev)
{
  char   keybuffer[8];
  KeySym keysym;
  XComposeStatus compose;
  int    count, keycode;
  ::Window root, child;
  int    rootx, rooty, winx, winy;
  unsigned int  mask;
  
  switch(ev.type) {
    case ButtonPress:
      switch(ev.xbutton.button) {
        case 1:
          if (window)
            window->buttonPress( GUI_ButtonLeft, ev.xbutton.x, ev.xbutton.y );
          break;
        case 2:
          if (window)
            window->buttonPress( GUI_ButtonMiddle, ev.xbutton.x, ev.xbutton.y );
          break;
        case 3:
          if (window)
            window->buttonPress( GUI_ButtonRight, ev.xbutton.x, ev.xbutton.y );
          break;
        case 4:
          if (window)
            window->wheelRotate( GUI_WheelForward );
          break;
        case 5:
          if (window)
            window->wheelRotate( GUI_WheelBackward );
          break;
      }
      break;
    case ButtonRelease:
      switch(ev.xbutton.button) {
        case 1:
          if (window)
            window->buttonRelease( GUI_ButtonLeft, ev.xbutton.x, ev.xbutton.y );
          break;
        case 2:
          if (window)
            window->buttonRelease( GUI_ButtonMiddle, ev.xbutton.x, ev.xbutton.y );
          break;
        case 3:
          if (window)
            window->buttonRelease( GUI_ButtonRight, ev.xbutton.x, ev.xbutton.y );
          break;
      }
      break;
    case KeyPress:
      count = XLookupString(&ev.xkey, keybuffer, sizeof(keybuffer), &keysym, &compose);
      keycode = translate_key(keysym);
      if (keycode)
        if (window)
          window->keyPress(keycode);
      break;
    case KeyRelease:
      count = XLookupString(&ev.xkey, keybuffer, sizeof(keybuffer), &keysym, &compose);
      keycode = translate_key(keysym);
      if (keycode)
        if (window)
          window->keyRelease(keycode);
      break;
    case MappingNotify:
      XRefreshKeyboardMapping(&ev.xmapping);
      break;
    case MotionNotify:
      if( XQueryPointer(factory->xdisplay, xwindow, &root, &child, &rootx, &rooty, &winx, &winy, &mask) == True )
        if (window)
          window->mouseMove( winx, winy );
      break;
    case Expose:
      if (ev.xexpose.count == 0) {
        if (window) {
          if (window->skipRedraw) break;
          window->paint();
        }  
        swap();
      }
      break;
    case ConfigureNotify:
      if (window)
        window->resize( ev.xconfigure.width, ev.xconfigure.height );
      break;
    case MapNotify:
      if (window)
        window->show();
      break;
    case UnmapNotify:
      if (window)
        window->hide();
      break;
    case ClientMessage:
      if ( ( (::Atom) ev.xclient.data.l[0] ) == factory->atoms[GUI_X11_ATOM_WM_DELETE])
        if (window)
          window->on_close();
      break;
    case DestroyNotify:
      factory->notifyDelete(xwindow);
      xwindow = 0;
      if (window)
        window->notifyDestroy();
      delete this;
      break;
  }
}
Example #23
0
/**
 * Initialize the x11 grab device demuxer (public device demuxer API).
 *
 * @param s1 Context from avformat core
 * @return <ul>
 *          <li>AVERROR(ENOMEM) no memory left</li>
 *          <li>AVERROR(EIO) other failure case</li>
 *          <li>0 success</li>
 *         </ul>
 */
static int
x11grab_read_header(AVFormatContext *s1)
{
    struct x11grab *x11grab = s1->priv_data;
    Display *dpy;
    AVStream *st = NULL;
    enum PixelFormat input_pixfmt;
    XImage *image;
    int x_off = 0;
    int y_off = 0;
    int screen;
    int use_shm;
    char *dpyname, *offset;
    int ret = 0;
    AVRational framerate;

    dpyname = av_strdup(s1->filename);
    if (!dpyname)
        goto out;

    offset = strchr(dpyname, '+');
    if (offset) {
        sscanf(offset, "%d,%d", &x_off, &y_off);
        if (strstr(offset, "nomouse")) {
            av_log(s1, AV_LOG_WARNING,
                   "'nomouse' specification in argument is deprecated: "
                   "use 'draw_mouse' option with value 0 instead\n");
            x11grab->draw_mouse = 0;
        }
        *offset= 0;
    }

    if ((ret = av_parse_video_rate(&framerate, x11grab->framerate)) < 0) {
        av_log(s1, AV_LOG_ERROR, "Could not parse framerate: %s.\n", x11grab->framerate);
        goto out;
    }
    av_log(s1, AV_LOG_INFO, "device: %s -> display: %s x: %d y: %d width: %d height: %d\n",
           s1->filename, dpyname, x_off, y_off, x11grab->width, x11grab->height);

    dpy = XOpenDisplay(dpyname);
    av_freep(&dpyname);
    if(!dpy) {
        av_log(s1, AV_LOG_ERROR, "Could not open X display.\n");
        ret = AVERROR(EIO);
        goto out;
    }

    st = avformat_new_stream(s1, NULL);
    if (!st) {
        ret = AVERROR(ENOMEM);
        goto out;
    }
    avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */

    screen = DefaultScreen(dpy);

    if (x11grab->follow_mouse) {
        int screen_w, screen_h;
        Window w;

        screen_w = DisplayWidth(dpy, screen);
        screen_h = DisplayHeight(dpy, screen);
        XQueryPointer(dpy, RootWindow(dpy, screen), &w, &w, &x_off, &y_off, &ret, &ret, &ret);
        x_off -= x11grab->width / 2;
        y_off -= x11grab->height / 2;
        x_off = FFMIN(FFMAX(x_off, 0), screen_w - x11grab->width);
        y_off = FFMIN(FFMAX(y_off, 0), screen_h - x11grab->height);
        av_log(s1, AV_LOG_INFO, "followmouse is enabled, resetting grabbing region to x: %d y: %d\n", x_off, y_off);
    }

    use_shm = XShmQueryExtension(dpy);
    av_log(s1, AV_LOG_INFO, "shared memory extension%s found\n", use_shm ? "" : " not");

    if(use_shm) {
        int scr = XDefaultScreen(dpy);
        image = XShmCreateImage(dpy,
                                DefaultVisual(dpy, scr),
                                DefaultDepth(dpy, scr),
                                ZPixmap,
                                NULL,
                                &x11grab->shminfo,
                                x11grab->width, x11grab->height);
        x11grab->shminfo.shmid = shmget(IPC_PRIVATE,
                                        image->bytes_per_line * image->height,
                                        IPC_CREAT|0777);
        if (x11grab->shminfo.shmid == -1) {
            av_log(s1, AV_LOG_ERROR, "Fatal: Can't get shared memory!\n");
            ret = AVERROR(ENOMEM);
            goto out;
        }
        x11grab->shminfo.shmaddr = image->data = shmat(x11grab->shminfo.shmid, 0, 0);
        x11grab->shminfo.readOnly = False;

        if (!XShmAttach(dpy, &x11grab->shminfo)) {
            av_log(s1, AV_LOG_ERROR, "Fatal: Failed to attach shared memory!\n");
            /* needs some better error subroutine :) */
            ret = AVERROR(EIO);
            goto out;
        }
    } else {
        image = XGetImage(dpy, RootWindow(dpy, screen),
                          x_off,y_off,
                          x11grab->width, x11grab->height,
                          AllPlanes, ZPixmap);
    }

    switch (image->bits_per_pixel) {
    case 8:
        av_log (s1, AV_LOG_DEBUG, "8 bit palette\n");
        input_pixfmt = PIX_FMT_PAL8;
        break;
    case 16:
        if (       image->red_mask   == 0xf800 &&
                   image->green_mask == 0x07e0 &&
                   image->blue_mask  == 0x001f ) {
            av_log (s1, AV_LOG_DEBUG, "16 bit RGB565\n");
            input_pixfmt = PIX_FMT_RGB565;
        } else if (image->red_mask   == 0x7c00 &&
                   image->green_mask == 0x03e0 &&
                   image->blue_mask  == 0x001f ) {
            av_log(s1, AV_LOG_DEBUG, "16 bit RGB555\n");
            input_pixfmt = PIX_FMT_RGB555;
        } else {
            av_log(s1, AV_LOG_ERROR, "RGB ordering at image depth %i not supported ... aborting\n", image->bits_per_pixel);
            av_log(s1, AV_LOG_ERROR, "color masks: r 0x%.6lx g 0x%.6lx b 0x%.6lx\n", image->red_mask, image->green_mask, image->blue_mask);
            ret = AVERROR(EIO);
            goto out;
        }
        break;
    case 24:
        if (        image->red_mask   == 0xff0000 &&
                    image->green_mask == 0x00ff00 &&
                    image->blue_mask  == 0x0000ff ) {
            input_pixfmt = PIX_FMT_BGR24;
        } else if ( image->red_mask   == 0x0000ff &&
                    image->green_mask == 0x00ff00 &&
                    image->blue_mask  == 0xff0000 ) {
            input_pixfmt = PIX_FMT_RGB24;
        } else {
            av_log(s1, AV_LOG_ERROR,"rgb ordering at image depth %i not supported ... aborting\n", image->bits_per_pixel);
            av_log(s1, AV_LOG_ERROR, "color masks: r 0x%.6lx g 0x%.6lx b 0x%.6lx\n", image->red_mask, image->green_mask, image->blue_mask);
            ret = AVERROR(EIO);
            goto out;
        }
        break;
    case 32:
        input_pixfmt = PIX_FMT_0RGB32;
        break;
    default:
        av_log(s1, AV_LOG_ERROR, "image depth %i not supported ... aborting\n", image->bits_per_pixel);
        ret = AVERROR(EINVAL);
        goto out;
    }

    x11grab->frame_size = x11grab->width * x11grab->height * image->bits_per_pixel/8;
    x11grab->dpy = dpy;
    x11grab->time_base  = av_inv_q(framerate);
    x11grab->time_frame = av_gettime() / av_q2d(x11grab->time_base);
    x11grab->x_off = x_off;
    x11grab->y_off = y_off;
    x11grab->image = image;
    x11grab->use_shm = use_shm;

    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    st->codec->codec_id = AV_CODEC_ID_RAWVIDEO;
    st->codec->width  = x11grab->width;
    st->codec->height = x11grab->height;
    st->codec->pix_fmt = input_pixfmt;
    st->codec->time_base = x11grab->time_base;
    st->codec->bit_rate = x11grab->frame_size * 1/av_q2d(x11grab->time_base) * 8;

out:
    av_free(dpyname);
    return ret;
}
Example #24
0
int main(int argc,char *argv[])
{

    printf("\n\n // \t EL PROGRAMA SOLO MAXIMIZA Y MINIMIZA LA VENTANA ACTIVA \n");
    printf(" // \t SE DEBE CORRER COMO SUPERUSUARIO \n\n\n");
    
    int fd;
    struct input_event ie;
    Display *dpy;
    Window root, child;
    XWindowAttributes winDD;
    int rootX, rootY, winX, winY;
    unsigned int mask;


    gtk_init(&argc,&argv);
    gdk_init(&argc,&argv);


    dpy = XOpenDisplay(NULL);
    XGetWindowAttributes(dpy,DefaultRootWindow(dpy),&winDD);
    XQueryPointer(dpy,DefaultRootWindow(dpy),&root,&child,
    &rootX,&rootY,&winX,&winY,&mask);

    if((fd = open(MOUSEFILE, O_RDONLY)) == -1) {
        perror("opening device");
        exit(EXIT_FAILURE);
    }


    int moves = 0,c = 0;
    int prevX,prevY;
    prevX = rootX;
    prevY = rootY;
    int mm = 0;
    int max_min = 0;
    while(read(fd, &ie, sizeof(struct input_event))) {
        moves++;
        c++;
        if (moves > 90){

            XQueryPointer(dpy,DefaultRootWindow(dpy),&root,&child,
            &rootX,&rootY,&winX,&winY,&mask);

            int dir = calculaDireccion(prevX,prevY,rootX,rootY);
            printf("X: %d \t Y: %d \t Direccion: %d \n\n", rootX,rootY,dir); 
            moves = 0;
            prevX = rootX;
            prevY = rootY;

           if(max_min)
            max_min  = 0;
            else 
                max_min = 1;

            max_unmax(max_min);
        }

        if(c > 200){
            mm++;
            //max_unmax(mm);

            //allWindows();

            if(mm>1)
                mm = -1;

            c = 0;
        }
    }

    return 0;
}
Example #25
0
//---------------------------------------------------------------------------
bool hxc_popup::create(Display *d,Window daddy,int _x,int _y,HXC_POPUPNOTIFYPROC np,void *o)
{
  if (handle) close(true);

  XD=d;
	notifyproc=np;
	owner=o;

  sy=0;
  sel=-1;
  clicked_in=0;

  hxc::load_res(XD);

  if (itemheight==0){
    itemheight=hxc::font->ascent+hxc::font->descent+2;
    if (lpig) itemheight=max(itemheight,lpig->IconHeight+2);
  }
  w=0;
  int iw=0;
  if (lpig) iw=lpig->IconWidth+2;
  for (int n=0;n<menu.NumStrings;n++){
    w=max(border+6+iw+(int)hxc::get_text_width(XD,menu[n].String)+6+border,w);
  }
  h=menu.NumStrings*itemheight+border*2;

  int move_h=0;
  if (daddy==0){
    if (_x==POP_CURSORPOS){
      Window in_win,in_child;
      int rootx,rooty;
      x=XDisplayWidth(XD,XDefaultScreen(XD))/2;
      y=XDisplayWidth(XD,XDefaultScreen(XD))/2;
      UINT mask;
      XQueryPointer(XD,XDefaultRootWindow(XD),&in_win,&in_child,
                        &rootx,&rooty,&x,&y,&mask);
    }else{
      x=_x,y=_y;
    }
  }else{
    Window child;
    XTranslateCoordinates(XD,daddy,XDefaultRootWindow(XD),_x,_y,&x,&y,&child);

    XWindowAttributes wa;
    XGetWindowAttributes(XD,daddy,&wa);
    move_h=wa.height;
  }

  int sw=XDisplayWidth(XD,XDefaultScreen(XD));
  int sh=XDisplayHeight(XD,XDefaultScreen(XD));
  if (move_h>=sh) move_h=0;

  if (x+w>sw) x=sw-w;
	if (y+h>sh){
    if (y-h-move_h>=0){
      y-=h+move_h;
    }else{
      y-=(y+h)-sh;
    }
  }

  XSetWindowAttributes swa;
  swa.backing_store=NotUseful;
  swa.override_redirect=True;
  swa.cursor=hxc::arrow_cursor;
  handle=XCreateWindow(XD,XDefaultRootWindow(XD),x,y,w,h,0,
                           CopyFromParent,InputOutput,CopyFromParent,
                           CWBackingStore | CWOverrideRedirect | CWCursor,
                           &swa);

  SetProp(XD,handle,cWinProc,(DWORD)WinProc);
  SetProp(XD,handle,cWinThis,(DWORD)this);
  SetProp(XD,handle,hxc::cModal,(DWORD)0xffffffff);

  XSelectInput(XD,handle,KeyPressMask | KeyReleaseMask |
                            ButtonPressMask | ButtonReleaseMask |
                            ExposureMask | FocusChangeMask |
                            PointerMotionMask | LeaveWindowMask);

  XMapWindow(XD,handle);

  XGrabPointer(XD,handle,False,PointerMotionMask | ButtonPressMask |
          			ButtonReleaseMask,GrabModeAsync,GrabModeAsync,None,
           			None,CurrentTime);
              
  hxc::popup_active=handle;

  return false;
}
Example #26
0
bool
XInterface::QueryPointer()
{
	Window dummy_win;
	int dummy;
	unsigned int mask;
	int root_x;
	int root_y;
	int i;
	time_t now;
	bool found = false;

	if(!XQueryPointer(_display, _pointer_root, &_pointer_root, &dummy_win, 
			  &root_x, &root_y, &dummy, &dummy, &mask))
	{
		//Pointer has moved to another screen
		for(i = 0; i < ScreenCount(_display); i++)
		{
			if(_pointer_root == RootWindow(_display, i))
			{
				_pointer_screen = ScreenOfDisplay(_display, i);
				found = true;
				break;
			}
		}
		if(!found)
		{
			dprintf(D_ALWAYS, "Lost connection to X server.\n");
			g_connected = false;
		}
	}

	if(root_x == _pointer_prev_x && root_y == _pointer_prev_y && 
	   mask == _pointer_prev_mask)
	{
		// Pointer has not moved.
		return false;
	}
	else
	{
		int cx = root_x - _pointer_prev_x, cy = root_y - _pointer_prev_y;
		bool small_move = (cx < _small_move_delta && cx > -_small_move_delta) && (cy < _small_move_delta && cy > -_small_move_delta);

		time(&now);
		time_t sec_since_last_event = now - _last_event;

		bool mouse_active = false;

		// if we have been idle,
		bool bump_check =  small_move && (sec_since_last_event > (_bump_check_after_idle_time_sec));

		dprintf(D_FULLDEBUG,"mouse moved to %d,%d,%x delta is %d,%d %.3f sec%s\n",
				root_x, root_y, mask, cx, cy, (double)sec_since_last_event,
				bump_check ? " performing bump check" : "");

		if (bump_check) {
			sleep(1);
			// check for further mouse movement
			int x = root_x, y = root_y;
			if ( ! XQueryPointer(_display, _pointer_root, &_pointer_root, &dummy_win,  &x, &y, &dummy, &dummy, &mask) ||
				root_x != x || root_y != y) {
				dprintf(D_FULLDEBUG,"not a bump - mouse moved to %d,%d,%x delta is %d,%d\n", x, y, mask, x-root_x, y-root_y);
				mouse_active = true;
				root_x = x; root_y = y;
			} else {
				mouse_active = false;
			}
		} else {
			mouse_active = true;
		}

		_pointer_prev_x = root_x;
		_pointer_prev_y = root_y;
		_pointer_prev_mask = mask;
		if (mouse_active) {
			// Pointer has indeed moved.
			_last_event = now;
		}
		return mouse_active;
	}
}
Example #27
0
static GdkNativeWindow
select_window_x11 (GdkScreen *screen)
{
  Display      *x_dpy       = GDK_SCREEN_XDISPLAY (screen);
  gint          x_scr       = GDK_SCREEN_XNUMBER (screen);
  Window        x_root      = RootWindow (x_dpy, x_scr);
  Window        x_win       = None;
  GC            x_gc          = None;
  Cursor        x_cursor    = XCreateFontCursor (x_dpy, GDK_CROSSHAIR);
  GdkKeymapKey *keys        = NULL;
  gint          status;
  gint          i, num_keys;
  gint          buttons     = 0;
  gint          mask        = ButtonPressMask | ButtonReleaseMask;
  gboolean      cancel      = FALSE;

  if (shootvals.shoot_type == SHOOT_REGION)
    mask |= PointerMotionMask;

  status = XGrabPointer (x_dpy, x_root, False,
                         mask, GrabModeSync, GrabModeAsync,
                         x_root, x_cursor, CurrentTime);

  if (status != GrabSuccess)
    {
      gint  x, y;
      guint xmask;

      /* if we can't grab the pointer, return the window under the pointer */
      XQueryPointer (x_dpy, x_root, &x_root, &x_win, &x, &y, &x, &y, &xmask);

      if (x_win == None || x_win == x_root)
        g_message (_("Error selecting the window"));
    }

  if (shootvals.shoot_type == SHOOT_REGION)
    {
      XGCValues gc_values;

      gc_values.function           = GXxor;
      gc_values.plane_mask         = AllPlanes;
      gc_values.foreground         = WhitePixel (x_dpy, x_scr);
      gc_values.background         = BlackPixel (x_dpy, x_scr);
      gc_values.line_width         = 0;
      gc_values.line_style         = LineSolid;
      gc_values.fill_style         = FillSolid;
      gc_values.cap_style          = CapButt;
      gc_values.join_style         = JoinMiter;
      gc_values.graphics_exposures = FALSE;
      gc_values.clip_x_origin      = 0;
      gc_values.clip_y_origin      = 0;
      gc_values.clip_mask          = None;
      gc_values.subwindow_mode     = IncludeInferiors;

      x_gc = XCreateGC (x_dpy, x_root,
                        GCFunction | GCPlaneMask | GCForeground | GCLineWidth |
                        GCLineStyle | GCCapStyle | GCJoinStyle |
                        GCGraphicsExposures | GCBackground | GCFillStyle |
                        GCClipXOrigin | GCClipYOrigin | GCClipMask |
                        GCSubwindowMode,
                        &gc_values);
    }

  if (gdk_keymap_get_entries_for_keyval (NULL, GDK_Escape, &keys, &num_keys))
    {
      gdk_error_trap_push ();

#define X_GRAB_KEY(index, modifiers) \
      XGrabKey (x_dpy, keys[index].keycode, modifiers, x_root, False, \
                GrabModeAsync, GrabModeAsync)

      for (i = 0; i < num_keys; i++)
        {
          X_GRAB_KEY (i, 0);
          X_GRAB_KEY (i, LockMask);            /* CapsLock              */
          X_GRAB_KEY (i, Mod2Mask);            /* NumLock               */
          X_GRAB_KEY (i, Mod5Mask);            /* ScrollLock            */
          X_GRAB_KEY (i, LockMask | Mod2Mask); /* CapsLock + NumLock    */
          X_GRAB_KEY (i, LockMask | Mod5Mask); /* CapsLock + ScrollLock */
          X_GRAB_KEY (i, Mod2Mask | Mod5Mask); /* NumLock  + ScrollLock */
          X_GRAB_KEY (i, LockMask | Mod2Mask | Mod5Mask); /* all        */
        }

#undef X_GRAB_KEY

      gdk_flush ();
      gdk_error_trap_pop ();
    }

  while (! cancel && ((x_win == None) || (buttons != 0)))
    {
      XEvent x_event;
      gint   x, y, w, h;

      XAllowEvents (x_dpy, SyncPointer, CurrentTime);
      XWindowEvent (x_dpy, x_root, mask | KeyPressMask, &x_event);

      switch (x_event.type)
        {
        case ButtonPress:
          if (x_win == None)
            {
              x_win = x_event.xbutton.subwindow;

              if (x_win == None)
                x_win = x_root;
#ifdef HAVE_X11_XMU_WINUTIL_H
              else if (! shootvals.decorate)
                x_win = XmuClientWindow (x_dpy, x_win);
#endif

              shootvals.x2 = shootvals.x1 = x_event.xbutton.x_root;
              shootvals.y2 = shootvals.y1 = x_event.xbutton.y_root;
            }

          buttons++;
          break;

        case ButtonRelease:
          if (buttons > 0)
            buttons--;

          if (! buttons && shootvals.shoot_type == SHOOT_REGION)
            {
              x = MIN (shootvals.x1, shootvals.x2);
              y = MIN (shootvals.y1, shootvals.y2);
              w = ABS (shootvals.x2 - shootvals.x1);
              h = ABS (shootvals.y2 - shootvals.y1);

              if (w > 0 && h > 0)
                XDrawRectangle (x_dpy, x_root, x_gc, x, y, w, h);

              shootvals.x2 = x_event.xbutton.x_root;
              shootvals.y2 = x_event.xbutton.y_root;
            }
          break;

        case MotionNotify:
          if (buttons > 0)
            {
              x = MIN (shootvals.x1, shootvals.x2);
              y = MIN (shootvals.y1, shootvals.y2);
              w = ABS (shootvals.x2 - shootvals.x1);
              h = ABS (shootvals.y2 - shootvals.y1);

              if (w > 0 && h > 0)
                XDrawRectangle (x_dpy, x_root, x_gc, x, y, w, h);

              shootvals.x2 = x_event.xmotion.x_root;
              shootvals.y2 = x_event.xmotion.y_root;

              x = MIN (shootvals.x1, shootvals.x2);
              y = MIN (shootvals.y1, shootvals.y2);
              w = ABS (shootvals.x2 - shootvals.x1);
              h = ABS (shootvals.y2 - shootvals.y1);

              if (w > 0 && h > 0)
                XDrawRectangle (x_dpy, x_root, x_gc, x, y, w, h);
            }
          break;

        case KeyPress:
          {
            guint *keyvals;
            gint   n;

            if (gdk_keymap_get_entries_for_keycode (NULL, x_event.xkey.keycode,
                                                    NULL, &keyvals, &n))
              {
                gint i;

                for (i = 0; i < n && ! cancel; i++)
                  if (keyvals[i] == GDK_Escape)
                    cancel = TRUE;

                g_free (keyvals);
              }
          }
          break;

        default:
          break;
        }
    }

  if (keys)
    {
#define X_UNGRAB_KEY(index, modifiers) \
      XUngrabKey (x_dpy, keys[index].keycode, modifiers, x_root)

      for (i = 0; i < num_keys; i++)
        {
          X_UNGRAB_KEY (i, 0);
          X_UNGRAB_KEY (i, LockMask);            /* CapsLock              */
          X_UNGRAB_KEY (i, Mod2Mask);            /* NumLock               */
          X_UNGRAB_KEY (i, Mod5Mask);            /* ScrollLock            */
          X_UNGRAB_KEY (i, LockMask | Mod2Mask); /* CapsLock + NumLock    */
          X_UNGRAB_KEY (i, LockMask | Mod5Mask); /* CapsLock + ScrollLock */
          X_UNGRAB_KEY (i, Mod2Mask | Mod5Mask); /* NumLock  + ScrollLock */
          X_UNGRAB_KEY (i, LockMask | Mod2Mask | Mod5Mask); /* all        */
        }
#undef X_UNGRAB_KEY

      g_free (keys);
    }

  if (status == GrabSuccess)
    XUngrabPointer (x_dpy, CurrentTime);

  XFreeCursor (x_dpy, x_cursor);

  if (x_gc != None)
    XFreeGC (x_dpy, x_gc);

  return x_win;
}
Example #28
0
/*
 * Remembers the current visual settings, so that
 * we can change them and restore later...
 */
static void fghRememberState( void )
{
#if TARGET_HOST_UNIX_X11

    /*
     * This highly depends on the XFree86 extensions,
     * not approved as X Consortium standards
     */
#   ifdef X_XF86VidModeGetModeLine


    /*
     * Remember the current ViewPort location of the screen to be able to
     * restore the ViewPort on LeaveGameMode():
     */
    if( !XF86VidModeGetViewPort(
             fgDisplay.Display,
             fgDisplay.Screen,
             &fgDisplay.DisplayViewPortX,
             &fgDisplay.DisplayViewPortY ) )
        fgWarning( "XF86VidModeGetViewPort failed" );

    /*
     * Remember the current pointer location before going fullscreen
     * for restoring it later:
     */
    {
        Window junk_window;
        unsigned int mask;

        XQueryPointer(
            fgDisplay.Display, fgDisplay.RootWindow,
            &junk_window, &junk_window,
            &fgDisplay.DisplayPointerX, &fgDisplay.DisplayPointerY,
            &fgDisplay.DisplayPointerX, &fgDisplay.DisplayPointerY, &mask
        );
    }

    /* Query the current display settings: */
    fgDisplay.DisplayModeValid =
      XF86VidModeGetModeLine(
        fgDisplay.Display,
        fgDisplay.Screen,
        &fgDisplay.DisplayModeClock,
        &fgDisplay.DisplayMode
    );

    if( !fgDisplay.DisplayModeValid )
            fgWarning( "XF86VidModeGetModeLine failed" );

#   else
    /*
     * XXX warning fghRememberState: missing XFree86 video mode extensions,
     * XXX game mode will not change screen resolution when activated
     */
#   endif

#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE

/*    DEVMODE devMode; */

    /* Grab the current desktop settings... */

/* hack to get around my stupid cross-gcc headers */
#define FREEGLUT_ENUM_CURRENT_SETTINGS -1

    EnumDisplaySettings( NULL, FREEGLUT_ENUM_CURRENT_SETTINGS,
                         &fgDisplay.DisplayMode );

    /* Make sure we will be restoring all settings needed */
    fgDisplay.DisplayMode.dmFields |=
        DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;

#endif
}
Example #29
0
int
Tk_Grab(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Window tkwin,		/* Window on whose behalf the pointer is to be
				 * grabbed. */
    int grabGlobal)		/* Non-zero means issue a grab to the server
				 * so that no other application gets mouse or
				 * keyboard events. Zero means the grab only
				 * applies within this application. */
{
    int grabResult, numTries;
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkDisplay *dispPtr = winPtr->dispPtr;
    TkWindow *winPtr2;
    unsigned int serial;

    ReleaseButtonGrab(dispPtr);
    if (dispPtr->eventualGrabWinPtr != NULL) {
	if ((dispPtr->eventualGrabWinPtr == winPtr)
		&& (grabGlobal == ((dispPtr->grabFlags & GRAB_GLOBAL) != 0))) {
	    return TCL_OK;
	}
	if (dispPtr->eventualGrabWinPtr->mainPtr != winPtr->mainPtr) {
	alreadyGrabbed:
	    Tcl_SetResult(interp, "grab failed: another application has grab",
		    TCL_STATIC);
	    return TCL_ERROR;
	}
	Tk_Ungrab((Tk_Window) dispPtr->eventualGrabWinPtr);
    }

    Tk_MakeWindowExist(tkwin);
#ifndef MAC_OSX_TK
    if (!grabGlobal)
#else
    if (0)
#endif
    {
	Window dummy1, dummy2;
	int dummy3, dummy4, dummy5, dummy6;
	unsigned int state;

	/*
	 * Local grab. However, if any mouse buttons are down, turn it into a
	 * global grab temporarily, until the last button goes up. This does
	 * two things: (a) it makes sure that we see the button-up event; and
	 * (b) it allows us to track mouse motion among all of the windows of
	 * this application.
	 */

	dispPtr->grabFlags &= ~(GRAB_GLOBAL|GRAB_TEMP_GLOBAL);
	XQueryPointer(dispPtr->display, winPtr->window, &dummy1,
		&dummy2, &dummy3, &dummy4, &dummy5, &dummy6, &state);
	if ((state & ALL_BUTTONS) != 0) {
	    dispPtr->grabFlags |= GRAB_TEMP_GLOBAL;
	    goto setGlobalGrab;
	}
    } else {
	dispPtr->grabFlags |= GRAB_GLOBAL;
    setGlobalGrab:

	/*
	 * Tricky point: must ungrab before grabbing. This is needed in case
	 * there is a button auto-grab already in effect. If there is, and the
	 * mouse has moved to a different window, X won't generate enter and
	 * leave events to move the mouse if we grab without ungrabbing.
	 */

	XUngrabPointer(dispPtr->display, CurrentTime);
	serial = NextRequest(dispPtr->display);

	/*
	 * Another tricky point: there are races with some window managers
	 * that can cause grabs to fail because the window manager hasn't
	 * released its grab quickly enough. To work around this problem,
	 * retry a few times after AlreadyGrabbed errors to give the grab
	 * release enough time to register with the server.
	 */

	grabResult = 0;			/* Needed only to prevent gcc compiler
					 * warnings. */
	for (numTries = 0; numTries < 10; numTries++) {
	    grabResult = XGrabPointer(dispPtr->display, winPtr->window,
		    True, ButtonPressMask|ButtonReleaseMask|ButtonMotionMask
		    |PointerMotionMask, GrabModeAsync, GrabModeAsync, None,
		    None, CurrentTime);
	    if (grabResult != AlreadyGrabbed) {
		break;
	    }
	    Tcl_Sleep(100);
	}
	if (grabResult != 0) {
	grabError:
	    if (grabResult == GrabNotViewable) {
		Tcl_SetResult(interp, "grab failed: window not viewable",
			TCL_STATIC);
	    } else if (grabResult == AlreadyGrabbed) {
		goto alreadyGrabbed;
	    } else if (grabResult == GrabFrozen) {
		Tcl_SetResult(interp,
			"grab failed: keyboard or pointer frozen", TCL_STATIC);
	    } else if (grabResult == GrabInvalidTime) {
		Tcl_SetResult(interp, "grab failed: invalid time",
			TCL_STATIC);
	    } else {
		char msg[64 + TCL_INTEGER_SPACE];

		sprintf(msg, "grab failed for unknown reason (code %d)",
			grabResult);
		Tcl_AppendResult(interp, msg, NULL);
	    }
	    return TCL_ERROR;
	}
	grabResult = XGrabKeyboard(dispPtr->display, Tk_WindowId(tkwin),
		False, GrabModeAsync, GrabModeAsync, CurrentTime);
	if (grabResult != 0) {
	    XUngrabPointer(dispPtr->display, CurrentTime);
	    goto grabError;
	}

	/*
	 * Eat up any grab-related events generated by the server for the
	 * grab. There are several reasons for doing this:
	 *
	 * 1. We have to synthesize the events for local grabs anyway, since
	 *    the server doesn't participate in them.
	 * 2. The server doesn't always generate the right events for global
	 *    grabs (e.g. it generates events even if the current window is in
	 *    the grab tree, which we don't want).
	 * 3. We want all the grab-related events to be processed immediately
	 *    (before other events that are already queued); events coming
	 *    from the server will be in the wrong place, but events we
	 *    synthesize here will go to the front of the queue.
	 */

	EatGrabEvents(dispPtr, serial);
    }

    /*
     * Synthesize leave events to move the pointer from its current window up
     * to the lowest ancestor that it has in common with the grab window.
     * However, only do this if the pointer is outside the grab window's
     * subtree but inside the grab window's application.
     */

    if ((dispPtr->serverWinPtr != NULL)
	    && (dispPtr->serverWinPtr->mainPtr == winPtr->mainPtr)) {
	for (winPtr2 = dispPtr->serverWinPtr; ; winPtr2 = winPtr2->parentPtr) {
	    if (winPtr2 == winPtr) {
		break;
	    }
	    if (winPtr2 == NULL) {
		MovePointer2(dispPtr->serverWinPtr, winPtr, NotifyGrab, 1, 0);
		break;
	    }
	}
    }
    QueueGrabWindowChange(dispPtr, winPtr);
    return TCL_OK;
}
main(int argc, char * argv [])
{
    Display * sdpy = XOpenDisplay(argv[1]);
    Display * tdpy = XOpenDisplay(argv[2]);
    int sscr = XDefaultScreen(sdpy);
    int tscr = XDefaultScreen(tdpy);
    GC tgc = DefaultGC(tdpy,tscr);
    Window swin=RootWindow (sdpy,sscr);
    int width, height, dummy;
    XGetGeometry(sdpy, swin, (Window *)&dummy, &dummy, &dummy, &width, &height, &dummy, &dummy);
    Window twin=CreateWindow(tdpy,tscr,width,height);
    XSelectInput(sdpy, swin, PointerMotionMask);
    XImage * image;
    XImage * simage;
    XImage * timage;
    int use_shm=1;
    XShmSegmentInfo xshm_sinfo;
    XShmSegmentInfo xshm_tinfo;
    if(use_shm) createShmImage(width,height,&xshm_sinfo,&xshm_tinfo,sdpy,tdpy,sscr,tscr,&simage,&timage);
    int frame=0;
    for(;;) {
        XEvent e;
        XNextEvent(tdpy, &e);
        if (e.type == MapNotify)
            break;
    }

    int emulate_events=0;

    int xmouse, ymouse;
    while(1)
    {
        {
            XEvent e;
            //long mask=ButtonPressMask|ButtonReleaseMask|MotionNotifyMask;
            //while(XCheckWindowEvent(tdpy, twin, mask, &e)!=False)
            while(XCheckTypedWindowEvent(tdpy, twin, ButtonPress, &e)!=False ||
                  XCheckTypedWindowEvent(tdpy, twin, ButtonRelease, &e)!=False)
            {
                printf("button event\n");
                if(emulate_events)
                {
                    e.xbutton.display=sdpy;
                    e.xbutton.window=swin;
                    e.xbutton.root=swin;
                    e.xbutton.window=swin;
                    e.xbutton.x_root=e.xbutton.x;
                    e.xbutton.y_root=e.xbutton.y;
                    //XSendEvent( sdpy, swin, True, mask, &e );
                    XPutBackEvent( sdpy, &e );
                    //XTestFakeMotionEvent(sdpy,sscr,e.xbutton.x,e.xbutton.y,0);
                    XTestFakeButtonEvent(sdpy,e.xbutton.button,e.xbutton.type==ButtonPress,0);
                }
            }
            while(XCheckTypedWindowEvent(sdpy, swin, MotionNotify, &e)!=False)
            {
                //printf("motion event\n");
                xmouse=e.xbutton.x_root;
                ymouse=e.xbutton.y_root;
            }
        }
        //printf("frame %d\n", frame++);
        usleep(60000);
        if(!use_shm)
        {
            image=CaptRoot(sdpy,sscr);
            DrawImage(tdpy,twin,image);
            XDestroyImage(image);
        }
        else
        {
//            XShmAttach(sdpy, &xshm_sinfo);
            XShmGetImage (sdpy, swin, simage, 0, 0, AllPlanes);
//            XShmAttach(sdpy, &xshm_tinfo);
            //printf("simage: w:%d h:%d d:%d\n",simage->width, simage->height, simage->depth);
            //printf("timage: w:%d h:%d d:%d\n",timage->width, timage->height, timage->depth);
            if(!emulate_events)
            {
                Window rwin,cwin;
                int xmouse,ymouse,x,y,mask;
                XQueryPointer(sdpy,swin,&rwin,&cwin,&xmouse,&ymouse,&x,&y,&mask);
                drawMouse(timage, xmouse, ymouse);
            }

            XShmPutImage (tdpy, twin, tgc, timage, 0, 0, 0, 0, timage->width, timage->height, False);
            //XPutImage (tdpy, twin, tgc, timage, 0, 0, 0, 0, timage->width, timage->height);
        }
        //XFlush(sdpy);
        XFlush(tdpy);
//        getchar();
    }
}