예제 #1
0
파일: OGLwin.cpp 프로젝트: xeniatay/cs488
/*
 * Name      : void vGetNextEvent(XEvent *tEvent)
 *
 * Parameters: None.
 *
 * Returns   : void
 *
 * Purpose   : Creates the main viewing window.
 */
void vGetNextEvent(XEvent *tEvent)
{
    /* Get the next event, however, event compression is used */
    /* for MotionNotify events.  MotionNotify events are disregarded */
    /* until the queue is empty. */
    do {
        XNextEvent(display, tEvent);
        if (tEvent->type == ConfigureNotify) {
            vInitGL(tEvent->xconfigure.width, tEvent->xconfigure.height);
            nWinHeight = tEvent->xconfigure.height;
            nWinWidth = tEvent->xconfigure.width;
            continue;
        }
        if (QLength(display) == 0) {
            break;
        }
    } while (tEvent->type == MotionNotify);
}
static Bool
LookAhead(Widget w, XEvent *event)
{
    XEvent newEvent;
    struct EventData eventData;

    if (QLength(XtDisplay(w)) == 0)
	return (False);

    eventData.count = 0;
    eventData.oldEvent = event;

    XPeekIfEvent(XtDisplay(w), &newEvent, PeekNotifyEvent, (char*)&eventData);

    if (CompareEvents(event, &newEvent))
	return (True);

    return (False);
}
예제 #3
0
파일: xbat.c 프로젝트: tmathmeyer/XBat
void run(void) {
    XEvent xe;
    while(1){
        while(QLength(disp)) {
            XNextEvent(disp, &xe);
        }
        int bat = get_battery_percent(bat_id);
        height = bat*3;
        resize(width, height);
        XMoveResizeWindow(disp, win, x-width, y-height, width, height);

        colorR = color_in_range("#ff0000", "#00ff00", bat);

        draw_rectangle(0,0,width,height,1,colorW);
        draw_rectangle(border,border,
                width-(2*border),height-(2*border),1,colorR);
        remap(win, width, height);
        usleep(60000000);
    }
}
예제 #4
0
int
TkUnixDoOneXEvent(
    Tcl_Time *timePtr)		/* Specifies the absolute time when the call
				 * should time out. */
{
    TkDisplay *dispPtr;
    static fd_mask readMask[MASK_SIZE];
    struct timeval blockTime, *timeoutPtr;
    Tcl_Time now;
    int fd, index, numFound, numFdBits = 0;
    fd_mask bit, *readMaskPtr = readMask;

    /*
     * Look for queued events first.
     */

    if (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {
	return 1;
    }

    /*
     * Compute the next block time and check to see if we have timed out. Note
     * that HP-UX defines tv_sec to be unsigned so we have to be careful in
     * our arithmetic.
     */

    if (timePtr) {
	Tcl_GetTime(&now);
	blockTime.tv_sec = timePtr->sec;
	blockTime.tv_usec = timePtr->usec - now.usec;
	if (blockTime.tv_usec < 0) {
	    now.sec += 1;
	    blockTime.tv_usec += 1000000;
	}
	if (blockTime.tv_sec < now.sec) {
	    blockTime.tv_sec = 0;
	    blockTime.tv_usec = 0;
	} else {
	    blockTime.tv_sec -= now.sec;
	}
	timeoutPtr = &blockTime;
    } else {
	timeoutPtr = NULL;
    }

    /*
     * Set up the select mask for all of the displays. If a display has data
     * pending, then we want to poll instead of blocking.
     */

    memset(readMask, 0, MASK_SIZE*sizeof(fd_mask));
    for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
	    dispPtr = dispPtr->nextPtr) {
	XFlush(dispPtr->display);
	if (QLength(dispPtr->display) > 0) {
	    blockTime.tv_sec = 0;
	    blockTime.tv_usec = 0;
	}
	fd = ConnectionNumber(dispPtr->display);
	index = fd/(NBBY*sizeof(fd_mask));
	bit = ((fd_mask)1) << (fd%(NBBY*sizeof(fd_mask)));
	readMask[index] |= bit;
	if (numFdBits <= fd) {
	    numFdBits = fd+1;
	}
    }

    numFound = select(numFdBits, (SELECT_MASK *) readMaskPtr, NULL, NULL,
	    timeoutPtr);
    if (numFound <= 0) {
	/*
	 * Some systems don't clear the masks after an error, so we have to do
	 * it here.
	 */

	memset(readMask, 0, MASK_SIZE*sizeof(fd_mask));
    }

    /*
     * Process any new events on the display connections.
     */

    for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
	    dispPtr = dispPtr->nextPtr) {
	fd = ConnectionNumber(dispPtr->display);
	index = fd/(NBBY*sizeof(fd_mask));
	bit = ((fd_mask)1) << (fd%(NBBY*sizeof(fd_mask)));
	if ((readMask[index] & bit) || (QLength(dispPtr->display) > 0)) {
	    DisplayFileProc((ClientData)dispPtr, TCL_READABLE);
	}
    }
    if (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {
	return 1;
    }

    /*
     * Check to see if we timed out.
     */

    if (timePtr) {
	Tcl_GetTime(&now);
	if ((now.sec > timePtr->sec) || ((now.sec == timePtr->sec)
		&& (now.usec > timePtr->usec))) {
	    return 0;
	}
    }

    /*
     * We had an event but we did not generate a Tcl event from it. Behave as
     * though we dealt with it. (JYL&SS)
     */

    return 1;
}
예제 #5
0
static void
TransferXEventsToTcl(
    Display *display)
{
    union {
	int type;
	XEvent x;
	TkKeyEvent k;
    } event;
    Window w;
    TkDisplay *dispPtr = NULL;

    /*
     * Transfer events from the X event queue to the Tk event queue after XIM
     * event filtering. KeyPress and KeyRelease events need special treatment
     * so that they get directed according to Tk's focus rules during XIM
     * handling. Theoretically they can go to the wrong place still (if
     * there's a focus change in the queue) but if we push the handling off
     * until Tk_HandleEvent then many input methods actually cease to work
     * correctly. Most of the time, Tk processes its event queue fast enough
     * for this to not be an issue anyway. [Bug 1924761]
     */

    while (QLength(display) > 0) {
	XNextEvent(display, &event.x);
	w = None;
	if (event.type == KeyPress || event.type == KeyRelease) {
	    for (dispPtr = TkGetDisplayList(); ; dispPtr = dispPtr->nextPtr) {
		if (dispPtr == NULL) {
		    break;
		} else if (dispPtr->display == event.x.xany.display) {
		    if (dispPtr->focusPtr != NULL) {
			w = dispPtr->focusPtr->window;
		    }
		    break;
		}
	    }
	}
	if (XFilterEvent(&event.x, w)) {
	    continue;
	}
	if (event.type == KeyPress || event.type == KeyRelease) {
	    event.k.charValuePtr = NULL;
	    event.k.charValueLen = 0;
	    event.k.keysym = NoSymbol;

	    /*
	     * Force the calling of the input method engine now. The results
	     * from it will be cached in the event so that they don't get lost
	     * (to a race condition with other XIM-handled key events) between
	     * entering the event queue and getting serviced. [Bug 1924761]
	     */

#ifdef TK_USE_INPUT_METHODS
	    if (event.type == KeyPress && dispPtr &&
		    (dispPtr->flags & TK_DISPLAY_USE_IM)) {
		if (dispPtr->focusPtr && dispPtr->focusPtr->inputContext) {
		    Tcl_DString ds;

		    Tcl_DStringInit(&ds);
		    (void) TkpGetString(dispPtr->focusPtr, &event.x, &ds);
		    Tcl_DStringFree(&ds);
		}
	    }
#endif
	}
	Tk_QueueWindowEvent(&event.x, TCL_QUEUE_TAIL);
    }
}
예제 #6
0
int
XMenuActivate(
    register Display *display,		/* Display to put menu on. */
    register XMenu *menu,		/* Menu to activate. */
    int *p_num,				/* Pane number selected. */
    int *s_num,				/* Selection number selected. */
    int x_pos,				/* X coordinate of menu position. */
    int y_pos,				/* Y coordinate of menu position. */
    unsigned int event_mask,		/* Mouse button event mask. */
    char **data,			/* Pointer to return data value. */
    void (*help_callback) (char const *, int, int)) /* Help callback.  */
{
    int status;				/* X routine call status. */
    int orig_x;				/* Upper left menu origin X coord. */
    int orig_y;				/* Upper left menu origin Y coord. */
    int ret_val;			/* Return value. */

    register XMPane *p_ptr;		/* Current XMPane. */
    register XMPane *event_xmp;		/* Event XMPane pointer. */
    register XMPane *cur_p;		/* Current pane. */
    register XMSelect *cur_s;		/* Current selection. */
    XMWindow *event_xmw;		/* Event XMWindow pointer. */
    XEvent event;			/* X input event. */
    XEvent peek_event;			/* X input peek ahead event. */

    Bool selection = False;		/* Selection has been made. */
    Bool forward = True;		/* Moving forward in the pane list. */

    Window root, child;
    int root_x, root_y, win_x, win_y;
    unsigned int mask;
    KeySym keysym;

    /*
     * Define and allocate a foreign event queue to hold events
     * that don't belong to XMenu.  These events are later restored
     * to the X event queue.
     */
    typedef struct _xmeventque {
	XEvent event;
	struct _xmeventque *next;
    } XMEventQue;

    XMEventQue *feq = NULL;    		/* Foreign event queue. */
    XMEventQue *feq_tmp;		/* Foreign event queue temporary. */

    /*
     * If there are no panes in the menu then return failure
     * because the menu is not initialized.
     */
    if (menu->p_count == 0) {
	_XMErrorCode = XME_NOT_INIT;
	return(XM_FAILURE);
    }

    /*
     * Find the desired current pane.
     */
    cur_p = _XMGetPanePtr(menu, *p_num);
    if (cur_p == NULL) {
	return(XM_FAILURE);
    }
    cur_p->activated = cur_p->active;

    /*
     * Find the desired current selection.
     * If the current selection index is out of range a null current selection
     * will be assumed and the cursor will be placed in the current pane
     * header.
     */
    cur_s = _XMGetSelectionPtr(cur_p, *s_num);

    /*
     * Compute origin of menu so that cursor is in
     * Correct pane and selection.
     */
    _XMTransToOrigin(display,
		     menu,
		     cur_p, cur_s,
		     x_pos, y_pos,
		     &orig_x, &orig_y);
    menu->x_pos = orig_x;	/* Store X and Y coords of menu. */
    menu->y_pos = orig_y;

    if (XMenuRecompute(display, menu) == XM_FAILURE) {
	return(XM_FAILURE);
    }

    /*
     * Flush the window creation queue.
     * This batches all window creates since lazy evaluation
     * is more efficient than individual evaluation.
     * This routine also does an XFlush().
     */
    if (_XMWinQueFlush(display, menu, cur_p, cur_s) == _FAILURE) {
	return(XM_FAILURE);
    }

    /*
     * Make sure windows are in correct order (in case we were passed
     * an already created menu in incorrect order.)
     */
    for(p_ptr = menu->p_list->next; p_ptr != cur_p; p_ptr = p_ptr->next)
	XRaiseWindow(display, p_ptr->window);
    for(p_ptr = menu->p_list->prev; p_ptr != cur_p->prev; p_ptr = p_ptr->prev)
	XRaiseWindow(display, p_ptr->window);

    /*
     * Make sure all selection windows are mapped.
     */
    for (
	p_ptr = menu->p_list->next;
	p_ptr != menu->p_list;
	p_ptr = p_ptr->next
    ){
	XMapSubwindows(display, p_ptr->window);
    }

    /*
     * Synchronize the X buffers and the event queue.
     * From here on, all events in the queue that don't belong to
     * XMenu are sent back to the application via an application
     * provided event handler or discarded if the application has
     * not provided an event handler.
     */
    XSync(display, 0);

    /*
     * Grab the mouse for menu input.
     */

    status = XGrabPointer(
			  display,
			  menu->parent,
			  True,
			  event_mask,
			  GrabModeAsync,
			  GrabModeAsync,
			  None,
			  menu->mouse_cursor,
			  CurrentTime
			  );
    if (status == Success && x_menu_grab_keyboard)
      {
        status = XGrabKeyboard (display,
                                menu->parent,
                                False,
                                GrabModeAsync,
                                GrabModeAsync,
                                CurrentTime);
        if (status != Success)
          XUngrabPointer(display, CurrentTime);
      }

    if (status == _X_FAILURE) {
	_XMErrorCode = XME_GRAB_MOUSE;
	return(XM_FAILURE);
    }

    /*
     * Map the menu panes.
     */
    XMapWindow(display, cur_p->window);
    for (p_ptr = menu->p_list->next;
	 p_ptr != cur_p;
	 p_ptr = p_ptr->next)
      XMapWindow(display, p_ptr->window);
    for (p_ptr = cur_p->next;
	 p_ptr != menu->p_list;
	 p_ptr = p_ptr->next)
      XMapWindow(display, p_ptr->window);

    XRaiseWindow(display, cur_p->window);	/* Make sure current */
						/* pane is on top. */

    cur_s = NULL;			/* Clear current selection. */

    /*
     * Begin event processing loop.
     */
    while (1) {
        if (wait_func) (*wait_func) (wait_data);
	XNextEvent(display, &event);	/* Get next event. */
	switch (event.type) {		/* Dispatch on the event type. */
    case Expose:
	    event_xmp = (XMPane *)XLookUpAssoc(display,
					       menu->assoc_tab,
					       event.xexpose.window);
	    if (event_xmp == NULL) {
		/*
		 * If AEQ mode is enabled then queue the event.
		 */
		if (menu->aeq) {
		    feq_tmp = (XMEventQue *)malloc(sizeof(XMEventQue));
		    if (feq_tmp == NULL) {
			_XMErrorCode = XME_CALLOC;
			return(XM_FAILURE);
		    }
		    feq_tmp->event = event;
		    feq_tmp->next = feq;
		    feq = feq_tmp;
		}
		else if (_XMEventHandler) (*_XMEventHandler)(&event);
		break;
	    }
	    if (event_xmp->activated) {
		XSetWindowBackground(display,
				     event_xmp->window,
				     menu->bkgnd_color);
	    }
	    else {
		XSetWindowBackgroundPixmap(display,
					   event_xmp->window,
					   menu->inact_pixmap);
	    }
	    _XMRefreshPane(display, menu, event_xmp);
	    break;
    case EnterNotify:
	    /*
	     * First wait a small period of time, and see
	     * if another EnterNotify event follows hard on the
	     * heels of this one. i.e., the user is simply
	     * "passing through". If so, ignore this one.
	     */

	    event_xmw = (XMWindow *)XLookUpAssoc(display,
						 menu->assoc_tab,
						 event.xcrossing.window);
	    if (event_xmw == NULL) break;
	    if (event_xmw->type == SELECTION) {
		/*
		 * We have entered a selection.
		 */
		/* if (XPending(display) == 0) usleep(150000); */
		if (XPending(display) != 0) {
		    XPeekEvent(display, &peek_event);
		    if(peek_event.type == LeaveNotify) {
			break;
		    }
		}
		cur_s = (XMSelect *)event_xmw;
		help_callback (cur_s->help_string,
			       cur_p->serial, cur_s->serial);

		/*
		 * If the pane we are in is active and the
		 * selection entered is active then activate
		 * the selection.
		 */
		if (cur_p->active && cur_s->active > 0) {
		    cur_s->activated = 1;
		    _XMRefreshSelection(display, menu, cur_s);
		}
	    }
	    else {
		/*
		 * We have entered a pane.
		 */
		/* if (XPending(display) == 0) usleep(150000); */
		if (XPending(display) != 0) {
		    XPeekEvent(display, &peek_event);
		    if (peek_event.type == EnterNotify) break;
		}
		XQueryPointer(display,
			      menu->parent,
			      &root, &child,
			      &root_x, &root_y,
			      &win_x, &win_y,
			      &mask);
		event_xmp = (XMPane *)XLookUpAssoc(display,
						   menu->assoc_tab,
						   child);
		if (event_xmp == NULL) break;
		if (event_xmp == cur_p) break;
		if (event_xmp->serial > cur_p->serial) forward = True;
		else forward = False;
		p_ptr = cur_p;
		while (p_ptr != event_xmp) {
		    if (forward) p_ptr = p_ptr->next;
		    else p_ptr = p_ptr->prev;
		    XRaiseWindow(display, p_ptr->window);
		}
		if (cur_p->activated) {
		    cur_p->activated = False;
		    XSetWindowBackgroundPixmap(display,
					       cur_p->window,
					       menu->inact_pixmap);
		    _XMRefreshPane(display, menu, cur_p);
		}
		if (event_xmp->active) event_xmp->activated = True;
#if 1
		/*
		 * i suspect the we don't get an EXPOSE event when backing
		 * store is enabled; the menu windows content is probably
		 * not drawn in when it should be in that case.
		 * in that case, this is probably an ugly fix!
		 * i hope someone more familiar with this code would
		 * take it from here.  -- [email protected].
		 */
		XSetWindowBackground(display,
				     event_xmp->window,
				     menu->bkgnd_color);
		_XMRefreshPane(display, menu, event_xmp);
#endif
		cur_p = event_xmp;
	    }
	    break;
    case LeaveNotify:
	    event_xmw = (XMWindow *)XLookUpAssoc(
						 display,
						 menu->assoc_tab,
						 event.xcrossing.window
						 );
	    if (event_xmw == NULL) break;
	    if(cur_s == NULL) break;

	    /*
	     * If the current selection was activated then
	     * deactivate it.
	     */
	    if (cur_s->activated) {
		cur_s->activated = False;
		_XMRefreshSelection(display, menu, cur_s);
	    }
	    cur_s = NULL;
	    break;

    case ButtonPress:
    case ButtonRelease:
		*p_num = cur_p->serial;
		/*
		 * Check to see if there is a current selection.
		 */
		if (cur_s != NULL) {
		    /*
		     * Set the selection number to the current selection.
		     */
		    *s_num = cur_s->serial;
		    /*
		     * If the current selection was activated then
		     * we have a valid selection otherwise we have
		     * an inactive selection.
		     */
		    if (cur_s->activated) {
			*data = cur_s->data;
			ret_val = XM_SUCCESS;
		    }
		    else {
			ret_val = XM_IA_SELECT;
		    }
		}
		else {
		    /*
		     * No selection was current.
		     */
		    ret_val = XM_NO_SELECT;
		}
		selection = True;
		break;
        case KeyPress:
        case KeyRelease:
                keysym = XLookupKeysym (&event.xkey, 0);

                /* Pop down on C-g and Escape.  */
                if ((keysym == XK_g && (event.xkey.state & ControlMask) != 0)
                    || keysym == XK_Escape) /* Any escape, ignore modifiers.  */
                  {
                    ret_val = XM_NO_SELECT;
                    selection = True;
                  }
               break;
	    default:
		/*
		 * If AEQ mode is enabled then queue the event.
		 */
		if (menu->aeq) {
		    feq_tmp = (XMEventQue *)malloc(sizeof(XMEventQue));
		    if (feq_tmp == NULL) {
			_XMErrorCode = XME_CALLOC;
			return(XM_FAILURE);
		    }
		    feq_tmp->event = event;
		    feq_tmp->next = feq;
		    feq = feq_tmp;
		}
		else if (_XMEventHandler) (*_XMEventHandler)(&event);
	}
	/*
	 * If a selection has been made, break out of the event loop.
	 */
	if (selection == True) break;
    }

    /*
     * Unmap the menu.
     */
    for ( p_ptr = menu->p_list->next;
	 p_ptr != menu->p_list;
	 p_ptr = p_ptr->next)
      {
	  XUnmapWindow(display, p_ptr->window);
      }

    /*
     * Ungrab the mouse.
     */
    XUngrabPointer(display, CurrentTime);
    XUngrabKeyboard(display, CurrentTime);

    /*
     * Restore bits under where the menu was if we managed
     * to save them and free the pixmap.
     */

    /*
     * If there is a current selection deactivate it.
     */
    if (cur_s != NULL) cur_s->activated = 0;

    /*
     * Deactivate the current pane.
     */
    cur_p->activated = 0;
    XSetWindowBackgroundPixmap(display, cur_p->window, menu->inact_pixmap);

    /*
     * Synchronize the X buffers and the X event queue.
     */
    XSync(display, 0);

    /*
     * Dispatch any events remaining on the queue.
     */
    while (QLength(display)) {
	/*
	 * Fetch the next event.
	 */
	XNextEvent(display, &event);

	/*
	 * Discard any events left on the queue that belong to XMenu.
	 * All others are held and then returned to the event queue.
	 */
	switch (event.type) {
	    case Expose:
	    case EnterNotify:
	    case LeaveNotify:
	    case ButtonPress:
	    case ButtonRelease:
		/*
		 * Does this event belong to one of XMenu's windows?
		 * If so, discard it and process the next event.
		 * If not fall through and treat it as a foreign event.
		 */
		event_xmp = (XMPane *)XLookUpAssoc(
						   display,
						   menu->assoc_tab,
						   event.xbutton.window
						   );
		if (event_xmp != NULL) continue;
	    default:
		/*
		 * This is a foreign event.
		 * Queue it for later return to the X event queue.
		 */
		feq_tmp = (XMEventQue *)malloc(sizeof(XMEventQue));
		if (feq_tmp == NULL) {
		    _XMErrorCode = XME_CALLOC;
		    return(XM_FAILURE);
		}
		feq_tmp->event = event;
		feq_tmp->next = feq;
		feq = feq_tmp;
	    }
    }
    /*
     * Return any foreign events that were queued to the X event queue.
     */
    while (feq != NULL) {
	feq_tmp = feq;
	XPutBackEvent(display, &feq_tmp->event);
	feq = feq_tmp->next;
	free((char *)feq_tmp);
    }

    wait_func = 0;

    /*
     * Return successfully.
     */
    _XMErrorCode = XME_NO_ERROR;
    return(ret_val);

}
예제 #7
0
static void draw_scope(double *values)
{
    static int32 call_cnt;
    int offset, expose;
    XEvent e;
    char pixels[SCOPE_HEIGHT*32];
    double work[SCOPE_HEIGHT];
    int nze;
    char *mname;
    KeySym k;

    make_logspectrogram(values, work);
    set_draw_pixel(work, pixels);

    expose = 0;
    nze = 0;
    while(QLength(disp) || XPending(disp))
    {
	XNextEvent(disp, &e);
	switch(e.type)
	{
	  case Expose:
	    expose++;
	    break;
	  case KeyPress:
	    k = xlookup_key(&e.xkey);
	    switch(k)
	    {
#ifdef XK_Down
	      case XK_Up:
#endif /* XK_Up */
#ifdef XK_KP_Up
	      case XK_KP_Up:
#endif /* XK_KP_Up */
		nze++;
		break;

#ifdef XK_Down
	      case XK_Down:
#endif /* XK_Down */
#ifdef XK_KP_Down
	      case XK_KP_Down:
#endif /* XK_KP_Down */
		nze--;
		break;

#ifdef XK_Left
	      case XK_Left:
#endif /* XK_Left */
#ifdef XK_KP_Left
	      case XK_KP_Left:
#endif /* XK_KP_Left */
		soundspec_update_interval =
		    (int32)(soundspec_update_interval*1.1);
		break;

#ifdef XK_Right
	      case XK_Right:
#endif /* XK_Right */
#ifdef XK_KP_Right
	      case XK_KP_Right:
#endif /* XK_KP_Right */
		soundspec_update_interval =
		    (int32)(soundspec_update_interval/1.1);
		if(soundspec_update_interval < 0.01 * play_mode->rate)
		    soundspec_update_interval =
			(int32)(0.01 * play_mode->rate);
		break;
	    }
	    break;

	  case ClientMessage:
	    if(wm_delete_window == e.xclient.data.l[0])
	    {
		mname = XGetAtomName(disp, e.xclient.message_type);
		if(mname != NULL && strcmp(mname, "WM_PROTOCOLS") == 0)
		{
		    /* Delete message from WM */
		    ctl->cmsg(CMSG_INFO, VERB_VERBOSE,
			      "Sound Spectrogram Window is closed");
		    close_soundspec();
		    XCloseDisplay(disp);
		    disp = NULL;
		    return;
		}
	    }
	    break;
	}
    }

    offset = call_cnt % SCROLL_THRESHOLD;
    if(offset == 0)
    {
	XCopyArea(disp, offscr, offscr, gc,
		  SCROLL_THRESHOLD, 0,
		  SCOPE_WIDTH - SCROLL_THRESHOLD,
		  SCOPE_HEIGHT,
		  0, 0);
	XSetForeground(disp, gc, BlackPixel(disp, DefaultScreen(disp)));
	XFillRectangle(disp, offscr, gc,
		       SCOPE_WIDTH - SCROLL_THRESHOLD, 0,
		       SCROLL_THRESHOLD, SCOPE_HEIGHT);
	XCopyArea(disp, offscr, win, gc,
		  0, 0, SCOPE_WIDTH, SCOPE_HEIGHT, 0, 0);
    }

    img->data = (char *)pixels;
    XPutImage(disp, offscr, gc, img, 0, 0,
	      SCOPE_WIDTH - SCROLL_THRESHOLD + offset, 0,
	      1, SCOPE_HEIGHT);
    if(!expose)
	XCopyArea(disp, offscr, win, gc,
		  SCOPE_WIDTH - SCROLL_THRESHOLD + offset, 0,
		  1, SCOPE_HEIGHT, SCOPE_WIDTH - SCROLL_THRESHOLD + offset, 0);
    else
    {
	XCopyArea(disp, offscr, win, gc,
		  0, 0, SCOPE_WIDTH, SCOPE_HEIGHT, 0, 0);
    }

    XSync(disp, False);
    if(nze)
	initialize_exp_hz_table(soundspec_zoom - 4 * nze);
    call_cnt++;
}
예제 #8
0
bool Workspace::x11Event( XEvent *event )
{
	//bool dumpWindows = false;
	//bool reportNextUpdate = false;

    static int debugs = 0;
    qDebug() << ++debugs << __PRETTY_FUNCTION__ << "got event" << eventName(event->type);

	switch ( event->type ) {
		case CreateNotify:
			createNotifyEvent( &event->xcreatewindow );
			//std::cout << "window " << std::hex << event->xcreatewindow.window << " created\n";
			//dumpWindows = true;
			break;

		case DestroyNotify:
			remove( event->xdestroywindow.window );
			//std::cout << "window " << std::hex << event->xdestroywindow.window << " destroyed\n";
			//dumpWindows = true;
			break;

		case ConfigureNotify:
			configureNotifyEvent( &event->xconfigure );
			//std::cout << "window " << std::hex << event->xconfigure.window << " configured\n";
			break;

		case MapNotify:
			if ( Client *client = find( event->xmap.window ) )
				client->show();
			//dumpWindows = true;
			//std::cout << "window " << std::hex << event->xmap.window << " mapped\n";
			break;

		case UnmapNotify:
			if ( Client *client = find( event->xunmap.window ) )
				client->hide();
			//dumpWindows = true;
			//std::cout << "window " << std::hex << event->xunmap.window << " unmapped\n";
			break;

		case ReparentNotify:
			reparentNotifyEvent( &event->xreparent );
			//dumpWindows = true;
			break;

		case CirculateNotify:
			circulateNotifyEvent( &event->xcirculate );
			//std::cout << "circulate event\n";
			break;

		case Expose:
			exposeEvent( &event->xexpose );
			break;

		case PropertyNotify:
			propertyNotifyEvent( &event->xproperty );
			break;

		default:
			if ( event->type == Extensions::damageEvent(XDamageNotify) )
				damageNotifyEvent( reinterpret_cast< XDamageNotifyEvent * >( event ) );
			
			else if ( event->type == Extensions::shapeEvent(ShapeNotify ))
				shapeNotifyEvent( reinterpret_cast< XShapeEvent * >( event ) );
	}

	/*
	if ( dumpWindows ) {
		std::cout << "===Clients===\n";
		ClientList::ConstIterator end = mList.constEnd();
		for (ClientList::ConstIterator it = mList.constBegin(); it != end; ++it) {
			Client *client = *it;

			//if (!client->isVisible() || client->width() <= 10 || client->height() <= 10)
			//	continue;

			Window target = XmuClientWindow( dpy, client->winId() );

			XTextProperty tp;
			XGetWMName( dpy, target, &tp );
			std::cout << std::hex << client->winId() << " "
					<< (client->isVisible() ? "(mapped)" : "(not mapped)")
					<< " " << std::dec << client->width() << "x" << client->height() << ": ";

			for (uint i = 0; i < tp.nitems; i++)
				std::cout << (char)tp.value[i];
			std::cout << std::endl;
		}
		//std::cout << "=============\n";
		std::cout << std::endl;
	}
	*/

	// Update the root window if there's damage and there are no more events pending
	if ( mDamage && QLength( dpy ) == 0 ) {
		if ( mWaitForClients && !allVisibleClientsPainted() )
		{
			//std::cout << "delaying update.\n.";
		} else {
			mWaitForClients = false;
			repaint();
		}

		// Helps to accumulate more events
		XSync( dpy, false );
	}

	return false;
}
예제 #9
0
/*
 * Given an XEvent, process it if it pertains to a ColorBar, else do
 * nothing with it.
 * Input:  event - the X event
 * Output:  whichcb - which colorbar this event pertained to.
 * Return: 1 - if color table was changed.
 *         2 - if reset key was pressed
 *         3 - if <shift>+reset key was pressed
 *         0 - if no change
 */
static int colorbar_process( LUI_COLORBAR *cb, XEvent *event )
{
   static int p1 = 0, p2 = 0, p3 = 0, p4 = 0; /* red, green, blue, alpha */
   static int pentry;
   int i, modify, entry, result;
   static int move_marker;

   result = modify = 0;

   if (event->type==KeyPress) {
      char keybuf[50];
      KeySym key;
      XComposeStatus compose;
      int count;
      count = XLookupString( &event->xkey, keybuf, 50, &key, &compose );
      if (count==1) {
         if (keybuf[0]=='r') {
            /* Reset RGB */
            cb->params[DRAWFLAG] = 0.0;
            result = LUI_RGB_RESET;
         }
         else if (keybuf[0]=='R') {
            /* Reset alpha */
            result = LUI_ALPHA_RESET;
            cb->params[DRAWFLAG] = 0.0;
         }
         else if (keybuf[0]=='c' || keybuf[0]=='C') {
            /* Copy current colors to clipboard */
            copy_colors( cb );
         }
         else if (keybuf[0]=='p' || keybuf[0]=='P') {
            /* Paste clipboard colors to current color widget */
            paste_colors( cb );
            LUI_ColorBarRedraw( cb );
            result = LUI_RGB_CHANGE | LUI_ALPHA_CHANGE;
            cb->params[DRAWFLAG] = 0.0;
            result = LUI_RGB_CHANGE | LUI_ALPHA_CHANGE;
         }

/* WLH 7-18-96 */
         else if (keybuf[0]=='s' || keybuf[0]=='S') {
            /* save colors to a file */
            save_colors( cb );
         }
         else if (keybuf[0]=='l' || keybuf[0]=='L') {
            /* load colors from a file */
            load_colors( cb );
            LUI_ColorBarRedraw( cb );
            return 1;
         }

         else {
            /* if unused key, toggle help display */
            cb->helpflag = !cb->helpflag;
            LUI_ColorBarRedraw( cb );
         }
      }
      else if (key == XK_Left) {
         /* rotate left */
         cb->params[BIAS] -= 0.03/cb->params[CURVE];
         result = LUI_RGB_SHAPE;
         cb->params[DRAWFLAG] = 0.0;
      }
      else if (key == XK_Right) {
         /* rotate right */
         cb->params[BIAS] += 0.03/cb->params[CURVE];
         result = LUI_RGB_SHAPE;
         cb->params[DRAWFLAG] = 0.0;
      }
      else if (key == XK_Up) {
         /* expand color map */
         if (event->xkey.state & ANY_MODIFIER) {
            cb->params[ALPHAPOW] -= 0.1;
            if (cb->params[ALPHAPOW]<0.0)
              cb->params[ALPHAPOW] = 0.0;
            result = LUI_ALPHA_SHAPE;
            cb->params[DRAWFLAG] = 0.0;
         }
         else {
            cb->params[CURVE] -= 0.1;
            result = LUI_RGB_SHAPE;
            cb->params[DRAWFLAG] = 0.0;
         }
      }
      else if (key == XK_Down) {
         /* compress color map */
         if (event->xkey.state & ANY_MODIFIER) {
            cb->params[ALPHAPOW] += 0.1;
            result = LUI_ALPHA_SHAPE;
            cb->params[DRAWFLAG] = 0.0;
         }
         else {
            cb->params[CURVE] += 0.1;
            result = LUI_RGB_SHAPE;
            cb->params[DRAWFLAG] = 0.0;
         }
      }
   }
   else if (event->type==Expose && event->xexpose.count==0) {
      LUI_ColorBarRedraw( cb );
      result = 0;
   }
   else if (event->type==ConfigureNotify) {
/* MJK 4.15.99 */
      LUI_ColorBarSetSize( cb, event->xconfigure.width, event->xconfigure.height );
      result = 0;
   }
   else if (event->type==ButtonPress ) {
      if (event->xbutton.y<cb->wedge_y) {
         /* change color function */
         move_marker = 0;
      }
      else {
         /* change marker position */
         move_marker = 1;
      }
      /* determine which curve to modify */
      if (event->xbutton.state&ANY_MODIFIER) {
         p4 = 1;
      }
      else {
         if (event->xbutton.button==Button1)  p1 = 1;
         if (event->xbutton.button==Button2)  p2 = 1;
         if (event->xbutton.button==Button3)  p3 = 1;
      }
      pentry = x_to_index( cb, event->xbutton.x );
      modify = 1;
   }
   else if (event->type==ButtonRelease) {
      if (p1 || p2 || p3) {
         result = LUI_RGB_CHANGE;
      }
      else {
         result = LUI_ALPHA_CHANGE;
      }
      if (event->xbutton.button==Button1)  p1 = 0;
      if (event->xbutton.button==Button2)  p2 = 0;
      if (event->xbutton.button==Button3)  p3 = 0;
      p4 = 0;
   }
   else if (event->type==MotionNotify) {
      /* Flush extra MotionNotify events */
      while (QLength(LUI_Display)>0) {
         XEvent next;
         XPeekEvent(LUI_Display, &next);
         if (next.type!=MotionNotify)
            break;
         XNextEvent(LUI_Display, event);
      }
      modify = 1;
   }


   /* Modify one or more of the color curves */

   if (modify && (p1 || p2 || p3 || p4)) {
      /* calculate which entry in color table to change */
      entry = x_to_index( cb, event->xbutton.x );
      /* update */
      if (move_marker) {
         /* changing marker position */
         cb->markerpos = entry;
         redraw_marker( cb );
      }
      else {
         /* changing color graph */
         int a, b, value;

         value = y_to_intensity( cb, event->xbutton.y );

         if (pentry<=entry) {
            a = pentry;
            b = entry;
         }
         else {
            a = entry;
            b = pentry;
         }

         /* update entries from 'pentry' to 'entry' */
         for (i=a; i<=b; i++) {
            int red, green, blue, alpha;
            red = UNPACK_RED(cb->table[i]);
            green = UNPACK_GREEN(cb->table[i]);
            blue = UNPACK_BLUE(cb->table[i]);
            alpha = UNPACK_ALPHA(cb->table[i]);
            if (p1) {
               /* modify red */
               red = value;
            }
            if (p2) {
               /* modify green */
               green = value;
            }
            if (p3) {
               /* modify blue */
               blue = value;
            }
            if (p4) {
               /* modify alpha */
               alpha = value;
            }
            /* change the color table entry */
            cb->table[i] = PACK_COLOR(red,green,blue,alpha);
         } /* for */

         /* redraw the color curves */
         if (pentry<entry)
           redraw_range( cb, pentry-1, entry+1 );
         else
           redraw_range( cb, entry-1, pentry+1 );

         pentry = entry;

         if (p4) {
            /* update min,max alpha values */
            cb->minalpha = 256;
            cb->maxalpha = 0;
            for (i=0;i<cb->table_size;i++) {
               int a = UNPACK_ALPHA( cb->table[i] );
               if (a<cb->minalpha)  cb->minalpha = a;
               if (a>cb->maxalpha)  cb->maxalpha = a;
            }
         }

         if (p4) {
			  result = LUI_ALPHA_MODIFY;
			  /*
            result = LUI_ALPHA_CHANGE;
			  */
         }
         else {
            result = LUI_RGB_MODIFY;
				/*
            result = LUI_RGB_CHANGE;
				*/
         }
         cb->params[DRAWFLAG] = 1.0;
      }
   } /*modify*/


   if (result!=0 && cb->callback) {
      (*cb->callback)(cb, result);
   }

   return result;
}
예제 #10
0
파일: Macros.c 프로젝트: mirror/libX11
int XQLength(Display *dpy) { return (QLength(dpy)); }
예제 #11
0
void x11_event_thread(void *args)
{
	int x;
	int high_fd;
	fd_set fdset;
	XEvent ev;
	static struct timeval tv;

	SetThreadName("X11 Events");
	if(video_init()) {
		sem_post(&init_complete);
		return;
	}
	x11_initialized=1;
	sem_post(&init_complete);

	if(local_pipe[0] > xfd)
		high_fd=local_pipe[0];
	else
		high_fd=xfd;

	for (;;) {
		tv.tv_sec=0;
		tv.tv_usec=54925; /* was 54925 (was also 10) */ 

		/*
		 * Handle any events just sitting around...
		 */
		while (QLength(dpy) > 0) {
			x11.XNextEvent(dpy, &ev);
			x11_event(&ev);
		}

		FD_ZERO(&fdset);
		FD_SET(xfd, &fdset);
		FD_SET(local_pipe[0], &fdset);

		x = select(high_fd+1, &fdset, 0, 0, &tv);

		switch (x) {
			case -1:
				/*
				* Errno might be wrong, so we just select again.
				* This could cause a problem is something really
				* was wrong with select....
				*/

				/* perror("select"); */
				break;
			case 0:
				/* Timeout */
				break;
			default:
				if (FD_ISSET(xfd, &fdset)) {
					x11.XNextEvent(dpy, &ev);
					x11_event(&ev);
				}
				while(FD_ISSET(local_pipe[0], &fdset)) {
					struct x11_local_event lev;

					read(local_pipe[0], &lev, sizeof(lev));
					switch(lev.type) {
						case X11_LOCAL_SETMODE:
							init_mode(lev.data.mode);
							break;
						case X11_LOCAL_SETNAME:
							x11.XSetIconName(dpy, win, lev.data.name);
							x11.XFlush(dpy);
							break;
						case X11_LOCAL_SETTITLE:
							x11.XStoreName(dpy, win, lev.data.title);
							x11.XFlush(dpy);
							break;
						case X11_LOCAL_COPY:
							x11.XSetSelectionOwner(dpy, CONSOLE_CLIPBOARD, win, CurrentTime);
							break;
						case X11_LOCAL_PASTE: 
							{
								Window sowner=None;

								sowner=x11.XGetSelectionOwner(dpy, CONSOLE_CLIPBOARD);
								if(sowner==win) {
									/* Get your own primary selection */
									if(copybuf==NULL)
										pastebuf=NULL;
									else
										pastebuf=strdup(copybuf);
									/* Set paste buffer */
									sem_post(&pastebuf_set);
									sem_wait(&pastebuf_used);
									FREE_AND_NULL(pastebuf);
								}
								else if(sowner!=None) {
									x11.XConvertSelection(dpy, CONSOLE_CLIPBOARD, XA_STRING, XA_STRING, win, CurrentTime);
								}
								else {
									/* Set paste buffer */
									pastebuf=NULL;
									sem_post(&pastebuf_set);
									sem_wait(&pastebuf_used);
								}
							}
							break;
						case X11_LOCAL_DRAWRECT:
							local_draw_rect(&lev.data.rect);
							break;
						case X11_LOCAL_FLUSH:
							x11.XFlush(dpy);
							break;
						case X11_LOCAL_BEEP:
							x11.XBell(dpy, 100);
							break;
					}
					tv.tv_sec=0;
					tv.tv_usec=0;

					FD_ZERO(&fdset);
					FD_SET(local_pipe[0], &fdset);

					if(select(local_pipe[0]+1, &fdset, 0, 0, &tv)!=1)
						FD_ZERO(&fdset);
				}
		}
	}
}
void
XWindowsEventQueueBuffer::waitForEvent(double dtimeout)
{
	Thread::testCancel();

	// clear out the pipe in preparation for waiting.

	char buf[16];
	ssize_t read_response = read(m_pipefd[0], buf, 15);
	
	// with linux automake, warnings are treated as errors by default
	if (read_response < 0)
	{
		// todo: handle read response
	}

	{
		Lock lock(&m_mutex);
		// we're now waiting for events
		m_waiting = true;

		// push out pending events
		flush();
	}
	// calling flush may have queued up a new event.
	if (!XWindowsEventQueueBuffer::isEmpty()) {
		Thread::testCancel();
		return;
	}

	// use poll() to wait for a message from the X server or for timeout.
	// this is a good deal more efficient than polling and sleeping.
#if HAVE_POLL
	struct pollfd pfds[2];
	pfds[0].fd     = ConnectionNumber(m_display);
	pfds[0].events = POLLIN;
	pfds[1].fd     = m_pipefd[0];
	pfds[1].events = POLLIN;
	int timeout    = (dtimeout < 0.0) ? -1 :
						static_cast<int>(1000.0 * dtimeout);
	int remaining  =  timeout;
	int retval     =  0;
#else
	struct timeval timeout;
	struct timeval* timeoutPtr;
	if (dtimeout < 0.0) {
		timeoutPtr = NULL;
	}
	else {
		timeout.tv_sec  = static_cast<int>(dtimeout);
		timeout.tv_usec = static_cast<int>(1.0e+6 *
								(dtimeout - timeout.tv_sec));
		timeoutPtr      = &timeout;
	}

	// initialize file descriptor sets
	fd_set rfds;
	FD_ZERO(&rfds);
	FD_SET(ConnectionNumber(m_display), &rfds);
	FD_SET(m_pipefd[0], &rfds);
 	int nfds;
 	if (ConnectionNumber(m_display) > m_pipefd[0]) {
 		nfds = ConnectionNumber(m_display) + 1;
 	}
 	else {
 		nfds = m_pipefd[0] + 1;
 	}
#endif
	// It's possible that the X server has queued events locally
	// in xlib's event buffer and not pushed on to the fd. Hence we
	// can't simply monitor the fd as we may never be woken up.
	// ie addEvent calls flush, XFlush may not send via the fd hence
	// there is an event waiting to be sent but we must exit the poll
	// before it can.
	// Instead we poll for a brief period of time (so if events
	// queued locally in the xlib buffer can be processed)
	// and continue doing this until timeout is reached.
	// The human eye can notice 60hz (ansi) which is 16ms, however
	// we want to give the cpu a chance s owe up this to 25ms
#define TIMEOUT_DELAY 25

	while (((dtimeout < 0.0) || (remaining > 0)) && QLength(m_display)==0 && retval==0){
#if HAVE_POLL
	retval = poll(pfds, 2, TIMEOUT_DELAY); //16ms = 60hz, but we make it > to play nicely with the cpu
 	if (pfds[1].revents & POLLIN) {
 		ssize_t read_response = read(m_pipefd[0], buf, 15);
		
		// with linux automake, warnings are treated as errors by default
		if (read_response < 0)
		{
			// todo: handle read response
		}

 	}
#else
	retval = select(nfds,
						SELECT_TYPE_ARG234 &rfds,
						SELECT_TYPE_ARG234 NULL,
						SELECT_TYPE_ARG234 NULL,
						SELECT_TYPE_ARG5   TIMEOUT_DELAY);
	if (FD_SET(m_pipefd[0], &rfds)) {
		read(m_pipefd[0], buf, 15);
	}
#endif
	    remaining-=TIMEOUT_DELAY;
	}

	{
		// we're no longer waiting for events
		Lock lock(&m_mutex);
		m_waiting = false;
	}

	Thread::testCancel();
}