Пример #1
0
int sendSpecEvent(Display *dpy, KeySym keysym, XEvent event) {
	XKeyEvent xkey = event.xkey;

	Window inFocus;
	int rev;
	XGetInputFocus(dpy, &inFocus, &rev);

	XKeyEvent kp;
	kp.window = inFocus;

	// trying to get MOD4 to work
	kp.root = event.xany.window;
	kp.subwindow = 0;
	kp.x = xkey.x;
	kp.y = xkey.y;
	kp.x_root = xkey.x_root;
	kp.y_root = xkey.y_root;

	kp.state = xkey.state; // key or button mask
	kp.keycode = XKeysymToKeycode(dpy, keysym);
	kp.type = xkey.type;

	#ifdef DEBUG
		printf("\nstate: %x\n", kp.state);
		printf("in focus: %x\n", (unsigned int) inFocus);
		printf("from xk_event (xkey_subwin): %x\n", (unsigned int) event.xkey.subwindow);
		printf("from xk_event (xkey_root): %x\n", (unsigned int) event.xkey.root);
		printf("from xk_event (xkey_win): %x\n", (unsigned int) event.xkey.window);
		printf("from xa_event (xany_win): %x\n\n", (unsigned int) event.xany.window);
	#endif

	XSendEvent(dpy, kp.window, False, 0, (XEvent *)(&kp));
	XFlush(dpy);

	return 1;
}
Пример #2
0
struct menu *
menu_filter(struct screen_ctx *sc, struct menu_q *menuq, const char *prompt,
    const char *initial, int flags,
    void (*match)(struct menu_q *, struct menu_q *, char *),
    void (*print)(struct menu *, int))
{
	struct menu_ctx		 mc;
	struct menu_q		 resultq;
	struct menu		*mi = NULL;
	XEvent			 e;
	Window			 focuswin;
	int			 focusrevert, xsave, ysave, xcur, ycur;

	TAILQ_INIT(&resultq);

	xu_ptr_getpos(sc->rootwin, &xsave, &ysave);

	(void)memset(&mc, 0, sizeof(mc));
	mc.sc = sc;
	mc.flags = flags;
	mc.match = match;
	mc.print = print;
	mc.entry = mc.prev = -1;
	mc.geom.x = xsave;
	mc.geom.y = ysave;

	if (mc.flags & CWM_MENU_LIST)
		mc.list = 1;

	(void)strlcpy(mc.promptstr, prompt, sizeof(mc.promptstr));
	if (initial != NULL)
		(void)strlcpy(mc.searchstr, initial, sizeof(mc.searchstr));
	else
		mc.searchstr[0] = '\0';

	mc.win = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0, 1, 1,
	    Conf.bwidth,
	    sc->xftcolor[CWM_COLOR_MENU_FG].pixel,
	    sc->xftcolor[CWM_COLOR_MENU_BG].pixel);
	mc.xftdraw = XftDrawCreate(X_Dpy, mc.win,
	    sc->visual, sc->colormap);

	XSelectInput(X_Dpy, mc.win, MENUMASK);
	XMapRaised(X_Dpy, mc.win);

	if (XGrabPointer(X_Dpy, mc.win, False, MENUGRABMASK,
	    GrabModeAsync, GrabModeAsync, None, Conf.cursor[CF_QUESTION],
	    CurrentTime) != GrabSuccess) {
		XftDrawDestroy(mc.xftdraw);
		XDestroyWindow(X_Dpy, mc.win);
	}

	XGetInputFocus(X_Dpy, &focuswin, &focusrevert);
	XSetInputFocus(X_Dpy, mc.win, RevertToPointerRoot, CurrentTime);

	/* make sure keybindings don't remove keys from the menu stream */
	XGrabKeyboard(X_Dpy, mc.win, True,
	    GrabModeAsync, GrabModeAsync, CurrentTime);

	for (;;) {
		mc.changed = 0;

		XWindowEvent(X_Dpy, mc.win, MENUMASK, &e);

		switch (e.type) {
		case KeyPress:
			if ((mi = menu_handle_key(&e, &mc, menuq, &resultq))
			    != NULL)
				goto out;
			/* FALLTHROUGH */
		case Expose:
			menu_draw(&mc, menuq, &resultq);
			break;
		case MotionNotify:
			menu_handle_move(&mc, &resultq,
			    e.xbutton.x, e.xbutton.y);
			break;
		case ButtonRelease:
			if ((mi = menu_handle_release(&mc, &resultq,
			    e.xbutton.x, e.xbutton.y)) != NULL)
				goto out;
			break;
		default:
			break;
		}
	}
out:
	if ((mc.flags & CWM_MENU_DUMMY) == 0 && mi->dummy) {
	       	/* no mouse based match */
		free(mi);
		mi = NULL;
	}

	XftDrawDestroy(mc.xftdraw);
	XDestroyWindow(X_Dpy, mc.win);

	XSetInputFocus(X_Dpy, focuswin, focusrevert, CurrentTime);
	/* restore if user didn't move */
	xu_ptr_getpos(sc->rootwin, &xcur, &ycur);
	if (xcur == mc.geom.x && ycur == mc.geom.y)
		xu_ptr_setpos(sc->rootwin, xsave, ysave);

	XUngrabPointer(X_Dpy, CurrentTime);
	XUngrabKeyboard(X_Dpy, CurrentTime);

	return(mi);
}
Пример #3
0
w3mimg_op *
w3mimg_x11open()
{
    w3mimg_op *wop = NULL;
    struct x11_info *xi = NULL;
    char *id;
    int revert, i;
    unsigned int nchildren;
    XWindowAttributes attr;
    Window root, *children;

    wop = (w3mimg_op *) malloc(sizeof(w3mimg_op));
    if (wop == NULL)
	return NULL;
    memset(wop, 0, sizeof(w3mimg_op));

    xi = (struct x11_info *)malloc(sizeof(struct x11_info));
    if (xi == NULL)
	goto error;
    memset(xi, 0, sizeof(struct x11_info));

    xi->display = XOpenDisplay(NULL);
    if (xi->display == NULL) {
	goto error;
    }
    if ((id = getenv("WINDOWID")) != NULL)
	xi->window = (Window) atoi(id);
    else
	XGetInputFocus(xi->display, &xi->window, &revert);
    if (!xi->window)
	exit(1);

    XGetWindowAttributes(xi->display, xi->window, &attr);
    wop->width = attr.width;
    wop->height = attr.height;

    while (1) {
	Window p_window;

	XQueryTree(xi->display, xi->window, &root, &xi->parent,
		   &children, &nchildren);
	p_window = xi->window;
	for (i = 0; i < nchildren; i++) {
	    XGetWindowAttributes(xi->display, children[i], &attr);
	    if (attr.width > wop->width * 0.7 &&
		attr.height > wop->height * 0.7) {
		/* maybe text window */
		wop->width = attr.width;
		wop->height = attr.height;
		xi->window = children[i];
	    }
	}
	if (p_window == xi->window)
	    break;
    }
    wop->offset_x = OFFSET_X;
    for (i = 0; i < nchildren; i++) {
	XGetWindowAttributes(xi->display, children[i], &attr);
	if (attr.x <= 0 && attr.width < 30 && attr.height > wop->height * 0.7) {
	    /* scrollbar of xterm/kterm ? */
	    wop->offset_x += attr.x + attr.width + attr.border_width * 2;
	    break;
	}
    }
    wop->offset_y = OFFSET_Y;

    wop->priv = xi;

    wop->init = x11_init;
    wop->finish = x11_finish;
    wop->active = x11_active;
    wop->set_background = x11_set_background;
    wop->sync = x11_sync;
    wop->close = x11_close;
    wop->clear = x11_clear;

    wop->load_image = x11_load_image;
    wop->show_image = x11_show_image;
    wop->free_image = x11_free_image;
    wop->get_image_size = x11_get_image_size;

    return wop;
  error:
    if (xi)
	free(xi);
    free(wop);
    return NULL;
}
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;
	
	//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:
#ifndef __LP64__
    // 32-Bit Carbon version:
	GetGlobalMouse(&mouseXY);
	PsychCopyOutDoubleArg(1, kPsychArgOptional, (double)mouseXY.h);
	PsychCopyOutDoubleArg(2, kPsychArgOptional, (double)mouseXY.v);
#else
    // 64-Bit HIToolbox version (OSX 10.5 and later):
    HIPoint outPoint;
    HIGetMousePosition(kHICoordSpaceScreenPixel, NULL, &outPoint);
	PsychCopyOutDoubleArg(1, kPsychArgOptional, (double) outPoint.x);
	PsychCopyOutDoubleArg(2, kPsychArgOptional, (double) outPoint.y);
#endif
	// Return optional keyboard input focus status:
	if (numButtons > 0) {
		// Window provided?
        // We only have the function GetUserFocusWindow on 32-Bit Carbon.
        // We have a drop-in replacement in OSX/PsychCocoaGlue.c for 64-Bit Cocoa.
		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) (GetUserFocusWindow() == windowRecord->targetSpecific.windowHandle) ? 1 : 0);
		} else
        {
			// No. Just always return "has focus":
			PsychCopyOutDoubleArg(4, kPsychArgOptional, (double) 1);
		}
	}

	// Return optional valuator values: Unimplemented on OS/X. Just return an empty matrix.
	// The buttonArray is just a dummy assignment without any meaning.
	PsychCopyOutDoubleMatArg(5, kPsychArgOptional, (int) 1, (int) 0, (int) 1, buttonArray);
	PsychCopyOutDoubleMatArg(6, kPsychArgOptional, (int) 1, (int) 0, (int) 1, buttonArray);
#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;
	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;
	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;
			mywin = windowRecord->targetSpecific.xwindowHandle;

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

		} else {
			mywin = RootWindow(dpy, PsychGetXScreenIdForScreen(screenNumber));
		}
	}

	// 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;

	  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.
		indevs = XIQueryDevice(dpy, indevs[mouseIndex].deviceid, &numButtons);
		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) {
						char* atomlabel =  XGetAtomName(dpy, axis->label);
						PsychSetStructArrayStringElement("label", axis->number, atomlabel, valuatorStruct);
						XFree(atomlabel);
					} 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:
			XIQueryPointer(dpy, indevs->deviceid, RootWindow(dpy, PsychGetXScreenIdForScreen(screenNumber)), &rootwin, &childwin, &mxd, &myd, &dxd, &dyd,
				       &buttons_return, &modifiers_return, &group_return);
		}

		// 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:
		XQueryPointer(dpy, RootWindow(dpy, PsychGetXScreenIdForScreen(screenNumber)), &rootwin, &childwin, &mx, &my, &dx, &dy, &mask_return);
	  
		// 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:
	  XGetInputFocus(dpy, &rootwin, &i);
	  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:

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

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

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

	      // 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);

	    for(i=0; i<256; i++) {
	      // Map keyboard scan code to KeySym:
	      keystring = XKeysymToString(XKeycodeToKeysym(dpy, i, 0));
	      if (keystring) {
		// Character found: Return its ASCII name string:
		PsychSetCellVectorStringElement(i, keystring, kbNames);
	      }
	      else {
		// No character for this keycode:
		PsychSetCellVectorStringElement(i, "", kbNames);
	      }
	    }
	  }
	  else if (numButtons == -4) {
	    // GetChar() emulation.

/* 	    do { */
/* 	      // Fetch next keypress event from queue, block if none is available... */
/* 	      keystring = NULL; */
/* 	      XNextEvent(dpy, &event_return); */
/* 	      // Check for valid keypress event and extract character: */
/* 	      if (event_return.type == KeyPress) { */
/* 		keypressevent = (XKeyPressedEvent) event_return; */
/* 		keystring = NULL; */
/* 		keystring = XKeysymToString(XKeycodeToKeysym(dpy, keypressevent.keycode, 0)); */
/* 	      } */
/* 	      // Repeat until a valid char is returned. */
/* 	    } while (keystring == NULL); */

/* 	    // Copy out character: */
/* 	    PsychCopyOutCharArg(1, kPsychArgOptional, (char) keystring); */
/* 	    // Copy out time: */
/* 	    PsychCopyOutDoubleArg(2, kPsychArgOptional, (double) keypressevent.time); */
	  }
	  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);	
}
Пример #5
0
static void I_VerifyPointerGrabState(void)
{
#ifndef AGGR_FOCUS
  boolean focused; // Are we the focused window?

  {
    Window fwin = None;
    int revert_to = 0;

    XGetInputFocus(X_display, &fwin, &revert_to);

    // WARNING: non-portable?
    focused = (fwin == X_mainWindow) ? true : false;
  }
#endif

  if (!grabMouse) return;

  // CPhipps - do not grab the mouse if paused
  // or not playing a level or the window is obscured
  // or during demo playback
  // DO grab in menus, because needed for key bindings screen
  if (paused || (gamestate != GS_LEVEL) || 
      (vis_flag != VisibilityUnobscured)
#ifndef AGGR_FOCUS
      || !focused
#endif
      || demoplayback) {

    if (grabbed) {
      // Release the mouse
      XUngrabPointer(X_display, CurrentTime);

      // Post a Doom event saying there is no movement and no buttons
      event.type = ev_mouse;
      event.data1 = event.data2 = event.data3 = 0;
    }

    grabbed = false;

  } else {

#ifdef AGGR_FOCUS
    XSetInputFocus(X_display, X_mainWindow, RevertToParent, CurrentTime);
#endif

    // grabs the pointer so it is restricted to this window
    if (!grabbed && (vis_flag == VisibilityUnobscured)) {
      XGrabPointer(X_display, X_mainWindow, True,
#ifndef POLL_POINTER
	   ButtonPressMask|ButtonReleaseMask|PointerMotionMask,
#else
		   0,
#endif
		   GrabModeAsync, GrabModeAsync,
		   X_mainWindow, None, CurrentTime);
      I_QueryPointer(&newmouse, NULL);
    }
    
    grabbed = true;
    /* Warp the pointer back to the middle of the window
     * or it could end up stuck on an edge 
     * Only warping if needed */
    if (abs(newmouse.x - X_width/2) > (X_width/2 - 32) || 
	    abs(newmouse.y - X_height/2) > (X_height/2 - 20)) 
    {
      /*mead allow larger deltas by preserving pre-warp portion.*/
      lastmouse.x = (X_width/2 -  (newmouse.x - lastmouse.x));
      lastmouse.y = (X_height/2 - (newmouse.y - lastmouse.y));

      XWarpPointer( X_display, None, X_mainWindow,
		    0, 0, 0, 0, X_width/2, X_height/2);
    } else {
      lastmouse = newmouse;
    }
  } 
}
Пример #6
0
static int	
DriverPrivateEvents(XEvent *report)
{
	UINT   wstate;
	HWND   hWnd,hWndFrame;
	WINDOWPOS wp;
	int count;
	int msgposted = 0;
	DWORD dwClientWin;
	RECT       rcWnd;
        PRIVATEDISPLAY    *dp;
	static Window win;
	Window win_focus;
	DWORD dwStyle;
	int revert_return;
	char *msgstr = 0;

        dp = GETDP();

	switch  (report->type) {
	case SelectionNotify:
		msgstr = "SelectionNotify";
		dp->ServerTime = report->xselection.time;
		break;
	case SelectionClear:
		msgstr = "SelectionClear";
		dp->ServerTime = report->xselectionclear.time;
		break;
	case SelectionRequest:
		msgstr = "SelectionRequest";
		dp->ServerTime = report->xselectionrequest.time;
		break;

	case PropertyNotify:
		msgstr = "PropertyNotify";
		dp->ServerTime = report->xproperty.time;

	/*
  	 *   fall through to common code, handle X ICCCM
 	 *   PropertyNotify will be related to clipboard and DDE
	 *   ClientMessage will be either
 	 *	wm_protocol	for user/window manager interactions
	 *	ipc_protocol	for DDE and low-level interactions
  	 */
	case ClientMessage:

		msgstr = "ClientMessage";
		if(InternalICCCM(report->type,dp,report))
			msgposted--;

		break;

	case Expose:
	{
	    XRectangle rcexpose;
	    Region RgnExpose = 0;
	    RECT rcExpose;
	    HWND hWndFrame   = 0;

	    msgstr = "Expose";
	    count = 0;

	    do {

		if (count == 0) {
		    if (XFindContext(dp->display,report->xexpose.window,
				dp->client_hwnd,(caddr_t *)&dwClientWin))
			continue;

		    hWndFrame = (HWND)HIWORD(dwClientWin);
		    count = report->xexpose.count;
		    if (count == 0) {
			rcExpose.left = report->xexpose.x;
			rcExpose.top = report->xexpose.y;
			rcExpose.right = report->xexpose.x+
					report->xexpose.width;
			rcExpose.bottom = report->xexpose.y+
					report->xexpose.height;
			lpLibCallback(TWINLIBCALLBACK_EXPOSE,(LPARAM)hWndFrame,
				SIMPLEREGION, (LPVOID)&rcExpose);
			msgposted--;
			continue;
		    }
		    else
			RgnExpose = XCreateRegion();
		}

		rcexpose.x = report->xexpose.x;
		rcexpose.y = report->xexpose.y;
		rcexpose.width = report->xexpose.width;
		rcexpose.height = report->xexpose.height;
		XUnionRectWithRegion(&rcexpose,RgnExpose,RgnExpose);

		if (report->xexpose.count == 0) {
		    lpLibCallback(TWINLIBCALLBACK_EXPOSE,(LPARAM)hWndFrame,
				COMPLEXREGION,(LPVOID)RgnExpose);
		    msgposted--;
		    XDestroyRegion(RgnExpose);
		    count = 0;
		}
	    } while (XCheckTypedEvent(dp->display,Expose,report));
	    break;
	}
	case ReparentNotify:
		msgstr = "ReparentNotify";
 		if (XFindContext(dp->display,report->xreparent.window,
 				dp->client_hwnd,(caddr_t *)&dwClientWin))
 			break;

		/* We have to repeat XResizeWindow for the sake of */
		/* OpenWindows, which loses resizing requests	 */
 		hWnd = LOWORD(dwClientWin);
 		GetPhysicalRect(hWnd,&rcWnd);

 		XResizeWindow(dp->display, report->xreparent.window,
			rcWnd.right-rcWnd.left,
			rcWnd.bottom-rcWnd.top);
		break;

	case ConfigureNotify:
		msgstr = "ConfigureNotify";
		if (XFindContext(dp->display,report->xconfigure.window,
				dp->client_hwnd,(caddr_t *)&dwClientWin))
			break;

		/* Window managers send synthetic ConfigureNotify events */
		/* if the window was moved but not resized (July 27, 1988 */
		/* ICCCM draft). Some window managers (OpenWin) offset the */
		/* origin by some fixed value, so take size portion and go */
		/* get origin from Xlib					 */
		wstate = SWP_NOACTIVATE|SWP_DRIVER|SWP_NOZORDER;
		{
			int xRoot,yRoot;
			Window child_return;

			XTranslateCoordinates(dp->display,
				report->xconfigure.window,
				RootWindow(dp->display,dp->screen),
				0,0,
				&xRoot,&yRoot,
				&child_return);

			report->xconfigure.x = xRoot;
			report->xconfigure.y = yRoot;
		}

		if (!report->xconfigure.width ||
		    !report->xconfigure.height)
		    wstate |= SWP_NOSIZE;

		wp.hwnd = (HWND)HIWORD(dwClientWin);
		wp.hwndInsertAfter = (HWND)0;
		wp.x = report->xconfigure.x;
		wp.y = report->xconfigure.y;
		wp.cx = report->xconfigure.width;
		wp.cy = report->xconfigure.height;
		wp.flags = wstate;
		lpLibCallback(TWINLIBCALLBACK_CONFIGURE,(LPARAM)wp.hwnd,
				0, (LPVOID)&wp);
		break;

	case ButtonPress:
		msgstr = "ButtonPress";
	    	msgposted =  DrvWindowsEvents(0L,0L,(LPVOID)report);
	    	break;
	case ButtonRelease:
		msgstr = "ButtonRelease";
	    	msgposted =  DrvWindowsEvents(0L,0L,(LPVOID)report);
	    	break;
	case MotionNotify:
		msgstr = "MotionNotify";
	    	msgposted =  DrvWindowsEvents(0L,0L,(LPVOID)report);
	    	break;

	case KeyPress:
		msgstr = "KeyPress";
	    	msgposted =  DrvHandleKeyboardEvents(0L,0L,(LPVOID)report);
	    	break;
	case KeyRelease:
		msgstr = "KeyRelease";
	    	msgposted =  DrvHandleKeyboardEvents(0L,0L,(LPVOID)report);
	    	break;

	case EnterNotify:
		msgstr = "EnterNotify";
	    	if (XFindContext(dp->display,report->xcrossing.window,
			dp->client_hwnd,(caddr_t *)&dwClientWin))
			break;
	    	XFindContext(dp->display,report->xcrossing.window,
			dp->window_style,(caddr_t *)&dwStyle);
	    	if ((dwStyle & WS_CAPTION) != WS_CAPTION) {
			XGetInputFocus(dp->display,&win,&revert_return);
			if (win != report->xcrossing.window) {
		    	XSetInputFocus(dp->display,report->xcrossing.window,
				revert_return,CurrentTime);
			}
	    	}
	    	break;

	case LeaveNotify:
		msgstr = "LeaveNotify";
	    	if (XFindContext(dp->display,report->xcrossing.window,
			dp->client_hwnd,(caddr_t *)&dwClientWin))
			break;
	    	XFindContext(dp->display,report->xcrossing.window,
			dp->window_style,(caddr_t *)&dwStyle);
	    	if ((dwStyle & WS_CAPTION) != WS_CAPTION) {
			XGetInputFocus(dp->display,&win_focus,&revert_return);
			if (win && (win != report->xcrossing.window)) {
		    		if (win != RootWindow(dp->display,dp->screen)) {
					XSetInputFocus(dp->display,win,
						revert_return,CurrentTime);
		    		}
		    		else {
					XSetInputFocus(dp->display,PointerRoot,
					0,CurrentTime);
		    		}
			}
			win = 0;
	    	}
	    	break;

	case FocusIn:
		msgstr = "FocusIn";
	case FocusOut:
		if(msgstr == 0)
			msgstr = "FocusOut";

		if (XFindContext(dp->display,report->xfocus.window,
			dp->client_hwnd,(caddr_t *)&dwClientWin))
		    break;
		hWndFrame = HIWORD(dwClientWin);
		lpLibCallback(TWINLIBCALLBACK_FOCUS,(LPARAM)hWndFrame,
				IFC_DRIVERFOCUS,
				(LPVOID)(report->type == FocusIn));
		msgposted--;
		break;

	case KeymapNotify:
		msgstr = "KeymapNotify";
		/* this could/should be used to update us on the current 
  		 * state of the keyboard.  Can it be different from what
		 * we know about it?  Yes, we could have keydown somewhere
		 * and keyup in our space...
		 */
		break;

	case VisibilityNotify:
		msgstr = "VisibilityNotify";
		/*
		 * The following function call prints the entire tree of
		 * windows known to X11.  It is commented out because it
		 * is far too wordy in most debugging situations.
		 */
		DrvPrintTree(dp, XRootWindow(dp->display, dp->screen));

		if (XFindContext(dp->display,
			report->xvisibility.window,
			dp->client_hwnd,
			(caddr_t *)&dwClientWin))
		    break;

		hWnd = (HWND)LOWORD(dwClientWin);
		switch (report->xvisibility.state) {
			case VisibilityUnobscured:
			case VisibilityPartiallyObscured:
				SetWF(hWnd,WFVISIBILITY);
				break;
			case VisibilityFullyObscured:
				ClearWF(hWnd,WFVISIBILITY);
				break;
		}
		msgposted--;
		break;

	case CreateNotify:
		msgstr = "CreateNotify";
		break;
	case DestroyNotify:
		msgstr = "DestroyNotify";
		break;

	case MappingNotify:
		msgstr = "MappingNotify";
		XRefreshKeyboardMapping((XMappingEvent *)report);
		break;

	case MapNotify:
		msgstr = "MapNotify";
#ifdef	DEBUG
		if (XFindContext(dp->display,report->xmap.window,
			dp->client_hwnd,(caddr_t *)&dwClientWin))
		    break;
		hWnd = HIWORD(dwClientWin);
#endif
		break;

	case UnmapNotify:
		msgstr = "UnmapNotify";
		if (XFindContext(dp->display,report->xunmap.window,
			dp->client_hwnd,(caddr_t *)&dwClientWin))
			break;
		hWnd = HIWORD(dwClientWin);
		ClearWF(hWnd, WFMAPPED);
		break;

	case CirculateNotify:
		msgstr = "CirculateNotify";
		break;

	case CirculateRequest:
		msgstr = "CirculateRequest";
		break;

	case NoExpose:
		msgstr = "NoExpose";
		break;

	default:
		msgstr = "UNKNOWN";
		break;

	} /* end switch */

	return msgposted;
}
Пример #7
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();
}
Пример #8
0
bool window_focused_x11(Display *display,Window win) {
  int revert_to_return;
  Window focus_return;
  XGetInputFocus(display,&focus_return,&revert_to_return);
  return win==focus_return;
}
Пример #9
0
void getFocusedWindow(Display *dsp,Window *w){
    int revert;
    XGetInputFocus(dsp,w,&revert);
}
Пример #10
0
static void
grabfocus(void)
{
	struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000  };
	Window focuswin;
	int i, revertwin;

	for (i = 0; i < 100; ++i) {
		XGetInputFocus(dpy, &focuswin, &revertwin);
		if (focuswin == win)
			return;
		XSetInputFocus(dpy, win, RevertToParent, CurrentTime);
		nanosleep(&ts, NULL);
	}
	die("cannot grab focus");
}

static void
grabkeyboard(void)
{
	struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000  };
	int i;

	if (embed)
		return;
	/* try to grab keyboard, we may have to wait for another process to ungrab */
	for (i = 0; i < 1000; i++) {
		if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync,
		                  GrabModeAsync, CurrentTime) == GrabSuccess)
			return;
		nanosleep(&ts, NULL);
	}
	die("cannot grab keyboard");
}

static void
match(void)
{
	static char **tokv = NULL;
	static int tokn = 0;

	char buf[sizeof text], *s;
	int i, tokc = 0;
	size_t len, textsize;
	struct item *item, *lprefix, *lsubstr, *prefixend, *substrend;

	strcpy(buf, text);
	/* separate input text into tokens to be matched individually */
	for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " "))
		if (++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv)))
			die("cannot realloc %u bytes:", tokn * sizeof *tokv);
	len = tokc ? strlen(tokv[0]) : 0;

	matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL;
	textsize = strlen(text);
	for (item = items; item && item->text; item++) {
		for (i = 0; i < tokc; i++)
			if (!fstrstr(item->text, tokv[i]))
				break;
		if (i != tokc) /* not all tokens match */
			continue;
		/* exact matches go first, then prefixes, then substrings */
		if (!tokc || !fstrncmp(text, item->text, textsize))
			appenditem(item, &matches, &matchend);
		else if (!fstrncmp(tokv[0], item->text, len))
			appenditem(item, &lprefix, &prefixend);
		else
			appenditem(item, &lsubstr, &substrend);
	}
	if (lprefix) {
		if (matches) {
			matchend->right = lprefix;
			lprefix->left = matchend;
		} else
			matches = lprefix;
		matchend = prefixend;
	}
	if (lsubstr) {
		if (matches) {
			matchend->right = lsubstr;
			lsubstr->left = matchend;
		} else
			matches = lsubstr;
		matchend = substrend;
	}
	curr = sel = matches;
	calcoffsets();
}

static void
insert(const char *str, ssize_t n)
{
	if (strlen(text) + n > sizeof text - 1)
		return;
	/* move existing text out of the way, insert new text, and update cursor */
	memmove(&text[cursor + n], &text[cursor], sizeof text - cursor - MAX(n, 0));
	if (n > 0)
		memcpy(&text[cursor], str, n);
	cursor += n;
	match();
}

static size_t
nextrune(int inc)
{
	ssize_t n;

	/* return location of next utf8 rune in the given direction (+1 or -1) */
	for (n = cursor + inc; n + inc >= 0 && (text[n] & 0xc0) == 0x80; n += inc)
		;
	return n;
}

static void
loadhistory(void)
{
	FILE *fp = NULL;
	size_t sz;

	if (!histfile)
		return;
	if (!(fp = fopen(histfile, "r")))
		return;
	fseek(fp, 0, SEEK_END);
	sz = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	if (sz) {
		histsz = sz + 1 + BUFSIZ;
		if (!(histbuf = malloc(histsz))) {
			fprintf(stderr, "warning: cannot malloc %lu "\
				"bytes", histsz);
		} else {
			histptr = histbuf + fread(histbuf, 1, sz, fp);
			if (histptr <= histbuf) { /* fread error */
				free(histbuf);
				histbuf = NULL;
				return;
			}
			if (histptr[-1] != '\n')
				*histptr++ = '\n';
			histptr[BUFSIZ - 1] = '\0';
			*histptr = '\0';
			histsz = histptr - histbuf + BUFSIZ;
		}
	}
	fclose(fp);
}
Пример #11
0
static int get_focus(struct _xfocus *p, int *forced_mode, int *focus_status)
{
	*forced_mode = FORCE_MODE_NORMAL;
	*focus_status = FOCUS_NONE;

	Window new_window;
	while (TRUE)
	{
		int revert_to;
		XGetInputFocus(main_window->display, &new_window, &revert_to);

		// Catch not empty and not system window 
		if (new_window != None && new_window > 1000)
			break;

		log_message(DEBUG, "New window empty");
		usleep(500);
	}
	
	char *new_app_name = get_wm_class_name(new_window);
	if (new_app_name != NULL)
	{
		if (xconfig->excluded_apps->exist(xconfig->excluded_apps, new_app_name, BY_PLAIN))
			*focus_status = FOCUS_EXCLUDED;

		if (xconfig->auto_apps->exist(xconfig->auto_apps, new_app_name, BY_PLAIN))
			*forced_mode = FORCE_MODE_AUTO;
		else if (xconfig->manual_apps->exist(xconfig->manual_apps, new_app_name, BY_PLAIN))
			*forced_mode = FORCE_MODE_MANUAL;
	}
	
	Window old_window = p->owner_window;
	if (new_window == old_window)
	{
		if (new_app_name != NULL)
			free(new_app_name);
		return FOCUS_UNCHANGED;
	}

	// Up to heighted window
	p->parent_window = new_window;
	while (TRUE)
	{
		unsigned int children_count;
		Window root_window, parent_window;
		Window *children_return;

		int is_same_screen = XQueryTree(main_window->display, p->parent_window, &root_window, &parent_window, &children_return, &children_count);
		if (!is_same_screen || parent_window == None || parent_window == root_window)
			break;
		
		p->parent_window = parent_window;
		XFree(children_return);
	}	
	
	// Replace unfocused window to focused window
	p->owner_window = new_window;

	log_message(DEBUG, "Process new window (ID %d) with name '%s' (status %s, mode %s)", new_window, new_app_name, verbose_focus_status[*focus_status], verbose_forced_mode[*forced_mode]);
	
	if (new_app_name != NULL)
		free(new_app_name);
	return FOCUS_CHANGED;
}
Пример #12
0
void EventCallback(XPointer p, XRecordInterceptData *idata) {

  if (XRecordFromServer == idata->category) {

    GUIRecord *grecord = (GUIRecord *) p;
    Display *disp = grecord->disp;
    Display *display = grecord->disp;

    //Display *disp = (Display *)p;

    xEvent *xev = (xEvent *)idata->data;
    int type = xev->u.u.type;
    int keyPress = 0;



    timeval now;
    gettimeofday(&now, NULL);
    long secDiff  = (now.tv_sec - grecord->evt.now.tv_sec);
    long usecDiff = ((now.tv_usec - grecord->evt.now.tv_usec) / 1000);
    long delay    = ((secDiff * 1000) + usecDiff);

    grecord->evt.delay = delay;
    grecord->evt.now   = now;
    //printf("DEBUG: delay = %ld\n",delay);


    debug()<<"event: "<<type<<std::endl;
    switch (type) {
      case ButtonPress: {
  	int button = xev->u.u.detail;      //   1=left, 2=middle, 3=right, 4=up, 5=down
          //printf("DEBUG: onMouseDown %d @ (%d,%d)\n", button, grecord->evt.x, grecord->evt.y);

           int x = xev->u.keyButtonPointer.rootX, y = xev->u.keyButtonPointer.rootY;
           grecord->evt.x = x;  grecord->evt.y = y;
           grecord->onMouseDown(button, x, y);

           //-- Window focus_return;
           //-- int revert_to_return;
           //-- XGetInputFocus(disp, &focus_return, &revert_to_return);
           //-- std::cout<<"Focus Window Press:"<<focus_return<<' '<<revert_to_return<<std::endl;

           /* // Below values Has no much meaning
           Window event_w = xev->u.keyButtonPointer.event;
           Window event_r = xev->u.keyButtonPointer.root;
           Window event_c = xev->u.keyButtonPointer.child;
           int event_x =  xev->u.keyButtonPointer.eventX;
           int event_y =  xev->u.keyButtonPointer.eventY;
           int root_x =  xev->u.keyButtonPointer.rootX;
           int root_y =  xev->u.keyButtonPointer.rootY;
           std::cout<<"mouse press: "<<(event_w)<<'/'<<event_r<<'/'<<event_c<<' '<<event_x<<' '<<event_y<<' '<<root_x<<' '<<root_y<<' '<<None<<std::endl;
           / */
        } break;
      case ButtonRelease: {
  	int button = xev->u.u.detail;
           //printf("DEBUG: onMouseUp %d @ (%d,%d)\n", button, grecord->evt.x, grecord->evt.y);
           int x = xev->u.keyButtonPointer.rootX, y = xev->u.keyButtonPointer.rootY;
           grecord->evt.x = x;  grecord->evt.y = y;
           grecord->onMouseUp(button, x, y);
        }
        break;
      case KeyPress: {
  	KeyCode kc = xev->u.u.detail;
  	//-- KeySym ks  = XKeycodeToKeysym(disp, kc, 0);
        //-- const char *kchar = XKeysymToString(ks);
        //-- printf("onKeyPress %d %s\n", kc, kchar);
        grecord->keystroke(kc, true);
        }
        break;
      case KeyRelease: {
  	KeyCode kc = xev->u.u.detail;

  	KeySym ks = XKeycodeToKeysym(disp, kc, 0);
  	//KeySym ks2 = XKeycodeToKeysym(disp, kc, 1);
        //printf("DEBUG: keysym %d %d\n",ks,ks2);
        const char *kchar = XKeysymToString(ks);
        //printf("DEBUG: onKeyUp %d %s\n", kc, kchar);
        if(strcmp(kchar, "Escape")==0){
          grecord->stop();
        }
        //std::cout<<"keyup "<<kchar<<std::endl;
        grecord->keystroke(kc,false);
       }
        break;
       case MotionNotify: {
           int x = xev->u.keyButtonPointer.rootX;
           int y = xev->u.keyButtonPointer.rootY;
           //grecord->evt.d += abs(x - grecord->evt.x) + abs(y - grecord->evt.y);
           grecord->evt.d += abs(x - grecord->evt.x) + abs(y - grecord->evt.y);
           grecord->evt.x = x;
           grecord->evt.y = y;
           grecord->onMouseMove(x,y);
         }
         break;
       case EnterNotify:
         printf("onEnter\n");
         break;
       case LeaveNotify:
         printf("onLeave\n");
         break;
       case FocusIn: {
           Window focus_win = xev->u.focus.window;
           grecord->flushMouse();
           Window focus_return; int revert_to_return;
           XGetInputFocus(display, &focus_return, &revert_to_return);
           if(focus_win == focus_return){
             grecord->evt.w = focus_win;
             int wx, wy;
             print_window_attrs(display, focus_win, wx, wy);
             int xdot_x = wx-7, xdot_y = wy-24;
             std::cout<<"xdotool getwindowfocus getwindowgeometry windowmove --sync "<<xdot_x<<' '<<xdot_y<<" getwindowgeometry"<<std::endl;
             // TODO: add size support
             // xdotool getwindowfocus getwindowgeometry windowmove 292 94 getwindowgeometry

             //xdo_window_move(display, focus_win, wx, wy);

             //print_window_attrs(display, focus_win, wx, wy);

             //--XGetGeometry(display, root_return, &root_return, &x_return, &y_return, &width_return, 
             //--         &height_return, &border_width_return, &depth_return);
             //--debug()<<"win root "<<x_return<<' '<<y_return<<' '<<width_return<<' '<<height_return<<std::endl;
/*
    XWindowAttributes attr;
    XGetWindowAttributes(display, focus_win, &attr);
    XTranslateCoordinates(xdo->xdpy, focus_win, attr.root, attr.x, attr.y, &root_x, &root_y, &unused_child);
    debug()<<"root "<<win_x<<','<<win_y<<' '<<root_x<<','<<root_y<<std::endl;
*/


           }
           //TODO: handle more on window stack change
         } break;
       case FocusOut: {
           grecord->flushMouse();
           Window focus_win = xev->u.focus.window;
           if(grecord->evt.w == focus_win){
             char *wname;
             XFetchName(display, focus_win, &wname);
             debug()<<"FocusOut Window: "<<focus_win<<' '<<wname<<std::endl;
             grecord->evt.w = 0;
           }
         } break;
       case KeymapNotify:
       case Expose: case GraphicsExpose: case NoExpose:
         break;
       case CreateNotify:
       case DestroyNotify:
         break;
       case MapNotify:
         debug()<<"MapNotify Window"<<std::endl;
         break;
       case UnmapNotify:
         debug()<<"UnmapNotify Window"<<std::endl;
         break;
       case ConfigureNotify: {
           int w_window = xev->u.configureRequest.window;
           int w_x = xev->u.configureRequest.x;
           int w_y = xev->u.configureRequest.y;
           int w_w = xev->u.configureRequest.width;
           int w_h = xev->u.configureRequest.height;
           debug()<<"Config Window: "<<w_window<<" @ ("<<w_x<<','<<w_y<<") "<<w_w<<'x'<<w_h<<std::endl;
         } break;
       case PropertyNotify:{
        // it's possible Copy action
         } break;
       case SelectionRequest: {
          // INFO: use SelectionRequest when Paste
         } break;
       default:
         //std::cout<<"event type: "<<type<<std::endl;
         break;
    }
    ////
    //HandleEvent(re);
    ////
  }

  if (idata != NULL)  XRecordFreeData(idata);
}
Пример #13
0
/* generic multi-head x */
int _al_xsys_mheadx_get_default_adapter(ALLEGRO_SYSTEM_XGLX *s)
{
    int i;

    ALLEGRO_DEBUG("mhead get default adapter\n");

    if (ScreenCount(s->x11display) == 1)
        return 0;

    _al_mutex_lock(&s->lock);

    Window focus;
    int revert_to = 0;
    XWindowAttributes attr;
    Screen *focus_screen;

    if (!XGetInputFocus(s->x11display, &focus, &revert_to)) {
        ALLEGRO_ERROR("XGetInputFocus failed!");
        _al_mutex_unlock(&s->lock);
        return 0;
    }

    if (focus == None) {
        ALLEGRO_ERROR("XGetInputFocus returned None!\n");
        _al_mutex_unlock(&s->lock);
        return 0;
    }
    else if (focus == PointerRoot) {
        ALLEGRO_DEBUG("XGetInputFocus returned PointerRoot.\n");
        /* XXX TEST THIS >:( */
        Window root, child;
        int root_x, root_y;
        int win_x, win_y;
        unsigned int mask;

        if (XQueryPointer(s->x11display, focus, &root, &child, &root_x, &root_y, &win_x, &win_y, &mask) == False) {
            ALLEGRO_ERROR("XQueryPointer failed :(");
            _al_mutex_unlock(&s->lock);
            return 0;
        }

        focus = root;
    }
    else {
        ALLEGRO_DEBUG("XGetInputFocus returned %i!\n", (int)focus);
    }

    XGetWindowAttributes(s->x11display, focus, &attr);
    focus_screen = attr.screen;

    int ret = 0;
    for (i = 0; i < ScreenCount(s->x11display); i++) {
        if (ScreenOfDisplay(s->x11display, i) == focus_screen) {
            _al_mutex_unlock(&s->lock);
            ret = i;
            break;
        }
    }

    _al_mutex_unlock(&s->lock);
    return ret;
}
Пример #14
0
void Blackbox::process_event(XEvent *e) {
  switch (e->type) {
  case MapRequest: {
#ifdef    DEBUG
    fprintf(stderr, "Blackbox::process_event(): MapRequest for 0x%lx\n",
            e->xmaprequest.window);
#endif // DEBUG

    BlackboxWindow *win = findWindow(e->xmaprequest.window);

    if (win) {
      if ((!activeScreen() || activeScreen() == win->screen()) &&
          (win->isTransient() || _resource.focusNewWindows()))
        win->activate();
    } else {
      BScreen *screen = findScreen(e->xmaprequest.parent);

      if (! screen) {
        /*
          we got a map request for a window who's parent isn't root. this
          can happen in only one circumstance:

          a client window unmapped a managed window, and then remapped it
          somewhere between unmapping the client window and reparenting it
          to root.

          regardless of how it happens, we need to find the screen that
          the window is on
        */
        XWindowAttributes wattrib;
        if (! XGetWindowAttributes(XDisplay(), e->xmaprequest.window,
                                   &wattrib)) {
          // failed to get the window attributes, perhaps the window has
          // now been destroyed?
          break;
        }

        screen = findScreen(wattrib.root);
        assert(screen != 0); // this should never happen
      }
      screen->addWindow(e->xmaprequest.window);
    }

    break;
  }

  case ConfigureRequest: {
    BlackboxWindow *win = findWindow(e->xconfigurerequest.window);
    if (win) {
      // a window wants to resize
      win->configureRequestEvent(&e->xconfigurerequest);
      break;
    }

    Slit *slit =
      dynamic_cast<Slit *>(findEventHandler(e->xconfigurerequest.parent));
    if (slit) {
      // something in the slit wants to resize
      slit->configureRequestEvent(&e->xconfigurerequest);
      break;
    }

    /*
      handle configure requests for windows that have no EventHandlers
      by simply configuring them as requested.

      note: the event->window parameter points to the window being
      configured, and event->parent points to the window that received
      the event (in this case, the root window, since
      SubstructureRedirect has been selected).
    */
    XWindowChanges xwc;
    xwc.x = e->xconfigurerequest.x;
    xwc.y = e->xconfigurerequest.y;
    xwc.width = e->xconfigurerequest.width;
    xwc.height = e->xconfigurerequest.height;
    xwc.border_width = e->xconfigurerequest.border_width;
    xwc.sibling = e->xconfigurerequest.above;
    xwc.stack_mode = e->xconfigurerequest.detail;
    XConfigureWindow(XDisplay(),
                     e->xconfigurerequest.window,
                     e->xconfigurerequest.value_mask,
                     &xwc);
    break;
  }

  case FocusIn: {
#ifdef FOCUS_DEBUG
    printf("FocusIn : window %8lx mode %s detail %s\n",
           e->xfocus.window, Mode[e->xfocus.mode], Detail[e->xfocus.detail]);
#endif

    if (e->xfocus.mode == NotifyGrab
        || (e->xfocus.detail != NotifyNonlinearVirtual
            && e->xfocus.detail != NotifyVirtual)) {
      /*
        don't process FocusIns when:
        1. they are the result of a grab
        2. the new focus window isn't an ancestor or inferior of the
        old focus window (NotifyNonlinearVirtual and NotifyVirtual)
      */
      break;
    }

    BlackboxWindow *win = findWindow(e->xfocus.window);
    if (!win || win->isFocused())
      break;

#ifdef FOCUS_DEBUG
    printf("          win %p got focus\n", win);
#endif
    win->setFocused(true);
    setFocusedWindow(win);

    /*
      set the event window to None.  when the FocusOut event handler calls
      this function recursively, it uses this as an indication that focus
      has moved to a known window.
    */
    e->xfocus.window = None;

    break;
  }

  case FocusOut: {
#ifdef FOCUS_DEBUG
    printf("FocusOut: window %8lx mode %s detail %s\n",
           e->xfocus.window, Mode[e->xfocus.mode], Detail[e->xfocus.detail]);
#endif

    if (e->xfocus.mode == NotifyGrab
        || (e->xfocus.detail != NotifyNonlinearVirtual
            && e->xfocus.detail != NotifyVirtual)) {
      /*
        don't process FocusOuts when:
        1. they are the result of a grab
        2. the new focus window isn't an ancestor or inferior of the
        old focus window (NotifyNonlinearVirtual and NotifyNonlinearVirtual)
      */
      break;
    }

    BlackboxWindow *win = findWindow(e->xfocus.window);
    if (!win || !win->isFocused())
      break;

    bool lost_focus = true; // did the window really lose focus?
    bool no_focus = true;   // did another window get focus?

    XSync(XDisplay(), False);
    XEvent event;
    if (XCheckIfEvent(XDisplay(), &event, scanForFocusIn, NULL)) {
      process_event(&event);

      if (event.xfocus.window == None)
        no_focus = false;
    } else {
      XWindowAttributes attr;
      Window w;
      int unused;
      XGetInputFocus(XDisplay(), &w, &unused);
      if (w != None
          && XGetWindowAttributes(XDisplay(), w, &attr)
          && attr.override_redirect) {
#ifdef FOCUS_DEBUG
        printf("          focused moved to an override_redirect window\n");
#endif
        lost_focus = (e->xfocus.mode == NotifyNormal);
      }
    }

    if (lost_focus) {
#ifdef FOCUS_DEBUG
      printf("          win %p lost focus\n", win);
#endif
      win->setFocused(false);

      if (no_focus) {
#ifdef FOCUS_DEBUG
        printf("          no window has focus\n");
#endif
        setFocusedWindow(0);
      }
    }

    break;
  }

  default:
    // Send the event through the default EventHandlers.
    bt::Application::process_event(e);
    break;
  } // switch
}
Пример #15
0
bool xifocus_update(struct _xifocus *p)
{
	struct _xobj *owner = p->owner;

	Window old_window = owner->xWindow;

	char *old_app_name = NULL;
	if (old_window != None)
		old_app_name = owner->get_wmclass_name(owner);

	int revert_to;
	Window new_window;

	XGetInputFocus(owner->xDisplay, &new_window, &revert_to);
	if (new_window == None) // If no window focused
	{
		p->ptr_count = 0;
		return FALSE;
	}

	p->changed = FALSE;
	if (new_window != old_window)
	{
		p->changed = TRUE;
		owner->xWindow = new_window;

		char *new_app_name = owner->get_wmclass_name(owner);

		if (!new_app_name || !old_app_name || strcmp(new_app_name, old_app_name) != 0)
			log_message(DEBUG, "New processed window with name '%s' (%d)", new_app_name, new_window);
		if (new_app_name)
			free(new_app_name);
	}

	if (old_app_name)
		free(old_app_name);

	p->ptr_count = 0;

	if (revert_to != RevertToPointerRoot)
		return TRUE;

	while (1)
	{
		int dummy;
		unsigned int dummyU;
		Window root_window;

		bool is_same_screen = XQueryPointer(owner->xDisplay, new_window, &root_window, &new_window, &dummy, &dummy, &dummy, &dummy, &dummyU);
		if (!is_same_screen || new_window == None)
			return TRUE;

		p->ptr_count++;
		if (p->ptr_count >= p->ptr_size)
		{
			p->ptr_size = p->ptr_count;
			p->ptr = (struct _xobj **) xnrealloc(p->ptr, p->ptr_size * sizeof(struct _xobj *));
			p->ptr[p->ptr_count - 1] = xobj_init();
		}

		struct _xobj *new_obj = p->ptr[p->ptr_count - 1];
		new_obj->xDisplay = owner->xDisplay;
		new_obj->xWindow = new_window;
	}
}
Пример #16
0
main()
{
      Window w2;

      Display *dpy = XOpenDisplay(NIL);
      assert(dpy);
      Screen *scr = DefaultScreenOfDisplay(dpy);

      // CreateWindow

      Window w = XCreateWindow(dpy, RootWindowOfScreen(scr), 10, 100, 200, 300, 0, CopyFromParent,
			       CopyFromParent, CopyFromParent,
			       0, NIL);

      XDestroyWindow(dpy, w);

      // CreateWindow with arguments

      XSetWindowAttributes swa;
      swa.background_pixel = WhitePixelOfScreen(scr);
      swa.bit_gravity = NorthWestGravity;
      swa.border_pixel = BlackPixelOfScreen(scr);
      swa.colormap = DefaultColormapOfScreen(scr);
      swa.cursor = None;
      swa.win_gravity = NorthGravity;

      w = XCreateWindow(dpy, RootWindowOfScreen(scr), 10, 100, 200, 300, 0, CopyFromParent,
			CopyFromParent, CopyFromParent,
			CWBackPixel | CWBitGravity | CWBorderPixel | CWColormap | CWCursor | CWWinGravity, 
			&swa);
      
      // CreateWindow with other arguments

      XDestroyWindow(dpy, w);

      Pixmap pixmap = XCreatePixmap(dpy, RootWindowOfScreen(scr), 45, 25, DefaultDepthOfScreen(scr));
      assert(pixmap);

      swa.background_pixmap = pixmap;
      swa.border_pixmap = pixmap;

      w = XCreateWindow(dpy, RootWindowOfScreen(scr), 10, 100, 200, 300, 0, CopyFromParent,
			CopyFromParent, CopyFromParent,
			CWBackPixmap | CWBorderPixmap,
			&swa);
      
      // ChangeWindowAttributes

      swa.backing_planes = 0x1;
      swa.backing_pixel = WhitePixelOfScreen(scr);
      swa.save_under = True;
      swa.event_mask = KeyPressMask | KeyReleaseMask;
      swa.do_not_propagate_mask = ButtonPressMask | Button4MotionMask;
      swa.override_redirect = False;
      XChangeWindowAttributes(dpy, w, CWBackingPlanes | CWBackingPixel | CWSaveUnder | CWEventMask
			      | CWDontPropagate | CWOverrideRedirect, &swa);

      // GetWindowAttributes

      XWindowAttributes wa;
      Status success = XGetWindowAttributes(dpy, w, &wa);

      // DestroyWindow (done)

      // DestroySubwindows

      w2 = XCreateWindow(dpy, w, 20, 30, 40, 50, 3, CopyFromParent, CopyFromParent, CopyFromParent, 0, NIL);
      XDestroySubwindows(dpy, w);

      // ChangeSaveSet

//        Display *dpy2 = XOpenDisplay(NIL);
//        assert(dpy2);
//        XAddToSaveSet(dpy2, w);
//        XCloseDisplay(dpy2);

      // ReparentWindow

      w2 = XCreateWindow(dpy, RootWindowOfScreen(scr), 20, 30, 40, 50, 3, 
			 CopyFromParent, CopyFromParent, CopyFromParent, 0, NIL);
      XReparentWindow(dpy, w2, w, 10, 5);

      // MapWindow

      XMapWindow(dpy, w);

      // MapSubwindows
      
      XMapSubwindows(dpy, w);

      // UnmapWindow
      
      XUnmapWindow(dpy, w);

      // UnmapSubwindows

      XMapWindow(dpy, w);
      XUnmapSubwindows(dpy, w2);
      XMapSubwindows(dpy, w);

      // ConfigureWindow

      Window w3 = XCreateWindow(dpy, w, 10, 50, 100, 10, 2,
			 CopyFromParent, CopyFromParent, CopyFromParent, 0, NIL);

      XMapWindow(dpy, w3);

      XWindowChanges wc;
      wc.x = -5;
      wc.y = -10;
      wc.width = 50;
      wc.height = 40;
      wc.border_width = 7;
      wc.sibling = w2;
      wc.stack_mode = Opposite;
      XConfigureWindow(dpy, w3, 
		       CWX | CWY | CWWidth | CWHeight | CWBorderWidth | CWSibling | CWStackMode, 
		       &wc);

      // CirculateWindow

      XCirculateSubwindows(dpy, w, RaiseLowest);

      // GetGeometry

      Window root;
      int x, y;
      unsigned width, height, border_width, depth;
      XGetGeometry(dpy, w, &root, &x, &y, &width, &height, &border_width, &depth);

      // QueryTree

      Window parent;
      Window *children;
      unsigned nchildren;
      success = XQueryTree(dpy, w, &root, &parent, &children, &nchildren);
      XFree(children);

      // InternAtom

      Atom a = XInternAtom(dpy, "WM_PROTOCOLS", True);

      // GetAtomName

      char *string = XGetAtomName(dpy, XA_PRIMARY);
      XFree(string);

      // ChangeProperty

      XStoreName(dpy, w, "test window");

      // DeleteProperty

      XDeleteProperty(dpy, w, XA_WM_NAME);

      // GetProperty
      // TODO

      // ListProperties

      int num_prop;
      Atom *list = XListProperties(dpy, w, &num_prop);
      XFree(list);

      // SetSelectionOwner

      XSetSelectionOwner(dpy, XA_PRIMARY, w, 12000);
      XSetSelectionOwner(dpy, XA_SECONDARY, w, CurrentTime);

      // GetSelectionOwner

      Window wx = XGetSelectionOwner(dpy, XA_PRIMARY);

      // ConvertSelection

      XConvertSelection(dpy, XA_SECONDARY, XA_CURSOR, XA_POINT, w, CurrentTime);

      // SendEvent

      // GrabPointer

      std::cerr << "Grabbing" << std::endl;
      int res = XGrabPointer(dpy, w, False, Button5MotionMask | PointerMotionHintMask,
			     GrabModeSync, GrabModeAsync, w, None, CurrentTime);
      XSync(dpy, False);
//      sleep(5);

      // UngrabPointer

      std::cerr << "Ungrabbing" << std::endl;
      XUngrabPointer(dpy, CurrentTime);

      // GrabButton

      XGrabButton(dpy, 3, ShiftMask | ControlMask, w, False, PointerMotionHintMask | Button2MotionMask, 
		  GrabModeAsync, GrabModeSync, None, None);
		  
      XGrabButton(dpy, 2, AnyModifier, w, False, PointerMotionHintMask | Button2MotionMask, 
		  GrabModeAsync, GrabModeSync, None, None);
		  
      // UngrabButton

      XUngrabButton(dpy, 2, LockMask, w);

      // ChangeActivePointerGrab

      XChangeActivePointerGrab(dpy, ButtonPressMask, None, CurrentTime);

      // GrabKeyboard

      XGrabKeyboard(dpy, w, True, GrabModeSync, GrabModeSync, 12000);

      // UngrabKeyboard

      XUngrabKeyboard(dpy, 13000);

      // GrabKey

      XGrabKey(dpy, XKeysymToKeycode(dpy, XK_Tab), ShiftMask | Mod3Mask, w, True, GrabModeSync,
	       GrabModeSync);

      // UngrabKey

      XUngrabKey(dpy, AnyKey, AnyModifier, w);

      // AllowEvents

      XAllowEvents(dpy, AsyncPointer, 14000);

      // GrabServer

      XGrabServer(dpy);

      // UngrabServer

      XUngrabServer(dpy);

      // QueryPointer

      Window child;
      int root_x, root_y, win_x, win_y;
      unsigned mask;
      Bool bres = XQueryPointer(dpy, w, &root, &child, &root_x, &root_y, &win_x, &win_y, &mask);

      // GetMotionEvents

      int nevents;
      XGetMotionEvents(dpy, w, 15000, 16000, &nevents);

      // TranslateCoordinates

      int dest_x, dest_y;

      XTranslateCoordinates(dpy, w, w2, 10, 20, &dest_x, &dest_y, &child);

      // WarpPointer

      XWarpPointer(dpy, w, w2, 0, 0, 100, 100, 20, 30);

      // SetInputFocus

      XSetInputFocus(dpy,w, RevertToPointerRoot, 17000);
      XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, 17000);

      // GetInputFocus

      Window focus;
      int revert_to;
      XGetInputFocus(dpy, &focus, &revert_to);

      // QueryKeymap

      char keys_return[32];
      XQueryKeymap(dpy, keys_return);

      // OpenFont

      Font fid = XLoadFont(dpy, "cursor");

      // CloseFont

      XUnloadFont(dpy, fid);

      // QueryFont

      XFontStruct *fs = XLoadQueryFont(dpy, "cursor");
      assert(fs);

      // QueryTextExtents

      int direction, font_ascent, font_descent;
      XCharStruct overall;
      XQueryTextExtents(dpy, fs -> fid, "toto", 4, &direction, &font_ascent, &font_descent, &overall);
      XQueryTextExtents(dpy, fs -> fid, "odd__length", 11, &direction, &font_ascent, &font_descent, &overall);

      XChar2b c2bs;
      c2bs.byte1 = '$';
      c2bs.byte2 = 'B';
      XQueryTextExtents16(dpy, fs -> fid, &c2bs, 1, &direction, &font_ascent, &font_descent, &overall);

      XQueryTextExtents(dpy, fs -> fid, longString, strlen(longString), &direction, &font_ascent, 
			&font_descent, &overall);

      // ListFonts

      int actual_count;
      char **fontList = XListFonts(dpy, "*", 100, &actual_count);
      XFree((char *)fontList);

      // ListFontsWithInfo

      int count;
      XFontStruct *info;
      char **names = XListFontsWithInfo(dpy, "*", 100, &count, &info);
      XFreeFontInfo(names, info, count);

      // SetFontPath
      // GetFontPath

      int npaths;
      char **charList = XGetFontPath(dpy, &npaths);

      char **charList2 = new char *[npaths + 1];
      memcpy(charList2, charList, npaths * sizeof(char *));
      charList2[npaths] = charList2[0];

      XSetFontPath(dpy, charList2, npaths + 1);
      XSetFontPath(dpy, charList, npaths); // Reset to some reasonnable value

      XFreeFontPath(charList);
      delete [] charList2;

      // CreatePixmap

      Pixmap pix2 = XCreatePixmap(dpy, w, 100, 200, DefaultDepthOfScreen(scr));

      // FreePixmap

      XFreePixmap(dpy, pix2);

      // CreateGC

      Pixmap bitmap = XCreateBitmapFromData(dpy, RootWindowOfScreen(scr), 
					    "\000\000\001\000\000\001\000\000\001\377\377\377", 3, 4);

      XGCValues gcv;
      gcv.function = GXand;
      gcv.plane_mask = 0x1;
      gcv.foreground = WhitePixelOfScreen(scr);
      gcv.background = BlackPixelOfScreen(scr);
      gcv.line_width = 2;
      gcv.line_style = LineDoubleDash;
      gcv.cap_style = CapProjecting;
      gcv.join_style = JoinRound;
      gcv.fill_style = FillStippled;
      gcv.fill_rule = EvenOddRule;
      gcv.arc_mode = ArcPieSlice;
      gcv.tile = pixmap;
      gcv.stipple = bitmap;
      gcv.ts_x_origin = 3;
      gcv.ts_y_origin = 4;
      gcv.font = fs -> fid;
      gcv.subwindow_mode = ClipByChildren;
      gcv.graphics_exposures = True;
      gcv.clip_x_origin = 5;
      gcv.clip_y_origin = 6;
      gcv.clip_mask = bitmap;
      gcv.dash_offset = 1;
      gcv.dashes = 0xc2;
      
      GC gc = XCreateGC(dpy, w, 
			  GCFunction | GCPlaneMask | GCForeground | GCBackground | GCLineWidth
			| GCLineStyle | GCCapStyle | GCJoinStyle | GCFillStyle | GCFillRule | GCTile
			| GCStipple | GCTileStipXOrigin | GCTileStipYOrigin | GCFont | GCSubwindowMode
			| GCGraphicsExposures | GCClipXOrigin | GCClipYOrigin | GCClipMask | GCDashOffset
			| GCDashList | GCArcMode,
			&gcv);

      // ChangeGC

      gcv.function = GXandReverse;

      // Only a few of these should appear, since the values are cached on the client side by the Xlib.

      XChangeGC(dpy, gc, GCFunction | GCLineStyle | GCStipple | GCGraphicsExposures | GCDashList, &gcv);

      // CopyGC
      
      GC gc2 = XCreateGC(dpy, w, 0, NIL);
      XCopyGC(dpy, gc, GCFunction | GCLineStyle | GCStipple | GCGraphicsExposures | GCDashList, gc2);

      // SetDashes

      XSetDashes(dpy, gc, 3, "\001\377\001", 3);

      // SetClipRectangles

      XRectangle rectangles[] = { { 10, 20, 30, 40 }, { 100, 200, 5, 3 }, { -5, 1, 12, 24 } };
      XSetClipRectangles(dpy, gc, 12, 9, rectangles, SIZEOF(rectangles), Unsorted);

      // FreeGC

	    // done already

      // ClearArea

      XClearArea(dpy, w, 30, 10, 10, 100, False);

      // CopyArea

      XCopyArea(dpy, w, pixmap, gc, 0, 0, 100, 100, 10, 10);

      // CopyPlane

      // This won't work if the Screen doesn't have at least 3 planes
      XCopyPlane(dpy, pixmap, w, gc, 20, 10, 40, 30, 0, 0, 0x4);

      // PolyPoint

      XDrawPoint(dpy, w, gc, 1, 2);

      XPoint points[] = { { 3, 4 }, { 5, 6 } };
      XDrawPoints(dpy, w, gc, points, SIZEOF(points), CoordModeOrigin);

      // PolyLine

      XDrawLines(dpy, w, gc, points, SIZEOF(points), CoordModePrevious);

      // PolySegment

      XSegment segments[] = { { 7, 8, 9, 10 }, { 11, 12, 13, 14 }, { 15, 16, 17, 18 } };
      XDrawSegments(dpy, w, gc, segments, SIZEOF(segments));

      // PolyRectangle

      XDrawRectangles(dpy, w, gc, rectangles, SIZEOF(rectangles));

      // PolyArc

      XArc arcs[] = { { 10, 20, 30, 40, 50, 60 }, { -70, 80, 90, 100, 110, 120 }, 
		      { 10, 20, 30, 40, 50, -30 } };

      XDrawArcs(dpy, w, gc, arcs, SIZEOF(arcs));

      // FillPoly

      XFillPolygon(dpy, w, gc, points, SIZEOF(points), Convex, CoordModePrevious);

      // PolyFillRectangle
      
      XFillRectangles(dpy, w, gc, rectangles, SIZEOF(rectangles));

      // PolyFillArc
      
      XFillArcs(dpy, w, gc, arcs, SIZEOF(arcs));

      // PutImage
      // GetImage

      XImage *image = XGetImage(dpy, w, 10, 20, 40, 30, AllPlanes, ZPixmap);
      XPutImage(dpy, w, gc, image, 0, 0, 50, 60, 40, 30);
      XSync(dpy, False); // Make the next request starts at the beginning of a packet

      // PolyText8
      XTextItem textItems[3];
      textItems[0].chars = "toto";
      textItems[0].nchars = strlen(textItems[0].chars);
      textItems[0].delta = -3;
      textItems[0].font = fs->fid;
      textItems[1].chars = "titi";
      textItems[1].nchars = strlen(textItems[1].chars);
      textItems[1].delta = 3;
      textItems[1].font = None;
      textItems[2].chars = "tutu";
      textItems[2].nchars = strlen(textItems[2].chars);
      textItems[2].delta = 0;
      textItems[2].font = fs->fid;

      XDrawText(dpy, w, gc, 10, 10, textItems, 3);


      XTextItem textItems2[3];
      textItems2[0].chars = "totox";
      textItems2[0].nchars = strlen(textItems2[0].chars);
      textItems2[0].delta = -3;
      textItems2[0].font = fs->fid;
      textItems2[1].chars = "titi";
      textItems2[1].nchars = strlen(textItems2[1].chars);
      textItems2[1].delta = 3;
      textItems2[1].font = None;
      textItems2[2].chars = "tutu";
      textItems2[2].nchars = strlen(textItems2[2].chars);
      textItems2[2].delta = 0;
      textItems2[2].font = fs->fid;

      XDrawText(dpy, w, gc, 10, 10, textItems2, 3);

      // PolyText16

      XChar2b c2b2[] = { 0, 't', 0, 'x' };

      XTextItem16 items16[] = { { &c2bs, 1, -5, None }, { NULL, 0, 0, None }, { c2b2, 2, 0, fs -> fid } };
      XDrawText16(dpy, w, gc, 10, 0, items16, SIZEOF(items16));

      // ImageText8

      XDrawImageString(dpy, w, gc, 10, 10, "toto", 4);

      // ImageText16

      XDrawImageString16(dpy, w, gc, 10, 10, &c2bs, 1);
      XDrawImageString16(dpy, w, gc, 10, 20, c2b2, 2);

      // CreateColormap
      // Don't forget to tell the kids how it was when we had only 8 bits per pixel.

      Colormap colormap = XCreateColormap(dpy, w, DefaultVisualOfScreen(scr), None);

      // FreeColormap

      XFreeColormap(dpy, colormap);
      colormap = XCreateColormap(dpy, w, DefaultVisualOfScreen(scr), None);

      // CopyColormapAndFree

      Colormap colormap2 = XCopyColormapAndFree(dpy, colormap);

      // InstallColormap

      XInstallColormap(dpy, colormap2);

      // UninstallColormap

      XUninstallColormap(dpy, colormap2);

      // ListInstalledColormaps

      int num;
      Colormap *colormapList = XListInstalledColormaps(dpy, w, &num);

      // AllocColor

      XColor screen;
      screen.red = 0;
      screen.green = 32767;
      screen.blue = 65535;
      screen.flags = DoRed | DoGreen | DoBlue;
      success = XAllocColor(dpy, colormap, &screen);

      // AllocNamedColor

      XColor screen2, exact;
      success = XAllocNamedColor(dpy, colormap, "Wheat", &screen2, &exact);

      // AllocColorCells

      unsigned long plane_masks, pixels;
      success = XAllocColorCells(dpy, colormap, False, &plane_masks, 1, &pixels, 1);

      // AllocColorPlanes

      unsigned long rmask, gmask, bmask;
      success = XAllocColorPlanes(dpy, colormap, False, &pixels, 1, 0, 0, 0, &rmask, &gmask, &bmask);

      // FreeColors

      unsigned long pixels2[2] = { screen.pixel, screen2.pixel };
      XFreeColors(dpy, colormap, pixels2, 2, 0);

      // StoreColors

      success = XAllocColorCells(dpy, colormap, False, NIL, 0, pixels2, 2);

      // On many contemporary (that is, year 2000) video cards, you can't allocate read / write cells
      // I want my requests to be sent, however.
      if (!success) {
	    XSetErrorHandler(errorHandler);
      }

      XColor colors[2];
      colors[0] = screen;  colors[0].pixel = pixels2[0];
      colors[1] = screen2; colors[1].pixel = pixels2[1];
      XStoreColors(dpy, colormap, colors, 2);

      // StoreNamedColor

      XStoreNamedColor(dpy, colormap, "Wheat", colors[0].pixel, DoBlue);

      XSync(dpy, False);
      XSetErrorHandler(NIL); // Restore the default handler

      // QueryColors

      screen2.pixel = WhitePixelOfScreen(scr);
      XQueryColor(dpy, colormap, &screen2);

      // LookupColor

      success = XLookupColor(dpy, colormap, "DarkCyan", &exact, &screen);

      // CreateCursor

      Cursor cursor = XCreatePixmapCursor(dpy, pixmap, None, &exact, colors, 10, 10);

      // CreateGlyphCursor
      
      Cursor cursor2 = XCreateGlyphCursor(dpy, fs -> fid, fs -> fid, 'X', 0, &exact, colors);

      // FreeCursor
      
      XFreeCursor(dpy, cursor2);

      // RecolorCursor

      XRecolorCursor(dpy, cursor, colors, &exact);

      // QueryBestSize

      success = XQueryBestSize(dpy, CursorShape, RootWindowOfScreen(scr), 100, 20, &width, &height);

      // QueryExtension

      int major_opcode, first_event, first_error;
      XQueryExtension(dpy, "toto", &major_opcode, &first_event, &first_error);

      // ListExtensions

      int nextensions;
      char **extensionList = XListExtensions(dpy, &nextensions);
      for(char **p = extensionList; nextensions; nextensions--, p++) std::cout << *p << std::endl;
      XFree(extensionList);

      // ChangeKeyboardMapping
      // GetKeyboardMapping

      int min_keycodes, max_keycodes;
      XDisplayKeycodes(dpy, &min_keycodes, &max_keycodes);

      int keysyms_per_keycode;
      KeySym *keysyms = XGetKeyboardMapping(dpy, min_keycodes, max_keycodes - min_keycodes + 1,
					    &keysyms_per_keycode);
      XChangeKeyboardMapping(dpy, min_keycodes, keysyms_per_keycode, keysyms, 
			     max_keycodes - min_keycodes + 1);

      // ChangeKeyboardControl
      // GetKeyboardControl

      XKeyboardState keyboardState;
      XGetKeyboardControl(dpy, &keyboardState);

      XKeyboardControl keyboardValues;
      keyboardValues.key_click_percent = keyboardState.key_click_percent;
      keyboardValues.bell_percent = keyboardState.bell_percent;
      keyboardValues.bell_pitch = keyboardState.bell_pitch;
      keyboardValues.bell_duration = keyboardState.bell_duration;
      keyboardValues.led = 1;
      keyboardValues.led_mode = LedModeOn;
      keyboardValues.key = min_keycodes;
      keyboardValues.auto_repeat_mode = AutoRepeatModeDefault;
      XChangeKeyboardControl(dpy, 
			       KBKeyClickPercent | KBBellPercent | KBBellPitch | KBBellDuration
			     | KBLed | KBLedMode | KBKey | KBAutoRepeatMode,
			     &keyboardValues);

      // Bell

      XBell(dpy, 90);

      // ChangePointerControl
      // GetPointerControl

      int accel_numerator, accel_denominator, threshold;
      XGetPointerControl(dpy, &accel_numerator, &accel_denominator, &threshold);

      XChangePointerControl(dpy, True, True, accel_numerator, accel_denominator, threshold);

      // SetScreenSaver
      // GetScreenSaver

      int timeout, interval, prefer_blanking, allow_exposures;
      XGetScreenSaver(dpy, &timeout, &interval, &prefer_blanking, &allow_exposures);
      XSetScreenSaver(dpy, timeout, interval, prefer_blanking, allow_exposures);

      // ChangeHosts
      // ListHosts

      int nhosts;
      Bool state;
      XHostAddress *hostList = XListHosts(dpy, &nhosts, &state);

      XHostAddress host;
      host.family = FamilyInternet;
      host.length = 4;
      host.address = "\001\002\003\004";
      XAddHost(dpy, &host);

      // SetAccessControl

      XSetAccessControl(dpy, EnableAccess);

      // SetCloseDownMode

      XSetCloseDownMode(dpy, RetainTemporary);

      // KillClient

      XKillClient(dpy, AllTemporary);

      // RotateProperties

      Atom properties[] = { XInternAtom(dpy, "CUT_BUFFER0", False), 
			    XInternAtom(dpy, "CUT_BUFFER1", False),
			    XInternAtom(dpy, "CUT_BUFFER2", False) };
      XRotateWindowProperties(dpy, RootWindowOfScreen(scr), properties, SIZEOF(properties), -1);

      // ForceScreenSaver

      XForceScreenSaver(dpy, ScreenSaverReset);

      // SetPointerMapping
      // GetPointerMapping

      unsigned char map[64];
      int map_length = XGetPointerMapping(dpy, map, 64);
      XSetPointerMapping(dpy, map, map_length);

      // SetModifierMapping
      // GetModifierMapping

      XModifierKeymap *modmap = XGetModifierMapping(dpy);
      XSetModifierMapping(dpy, modmap);

      // NoOperation

      XNoOp(dpy);

      for(;;) {
	    XEvent e;
	    XNextEvent(dpy, &e);
	    std::cout << "Got an event of type " << e.type << std::endl;
      }
}
Пример #17
0
bool emX11WindowPort::Cycle()
{
	XWindowAttributes attr;
	XSizeHints xsh;
	emString str;
	emCursor cur;
	::Window win;
	::Cursor xcur;
	emX11WindowPort * wp;
	double vrx,vry,vrw,vrh,fx,fy,fw,fh;
	int i,x,y,w,h;
	Status xs;

	if (
		FullscreenUpdateTimer &&
		IsSignaled(FullscreenUpdateTimer->GetSignal())
	) {
		Screen.GetVisibleRect(&vrx,&vry,&vrw,&vrh);
		if (
			fabs(PaneX-vrx)>0.51 || fabs(PaneY-vry)>0.51 ||
			fabs(PaneW-vrw)>0.51 || fabs(PaneH-vrh)>0.51
		) {
			PosForced=true;
			PosPending=true;
			SizeForced=true;
			SizePending=true;
			SetViewGeometry(vrx,vry,vrw,vrh,Screen.PixelTallness);
		}

		// Workaround for lots of focus problems with several window managers:
		if (Screen.GrabbingWinPort==this) {
			XMutex.Lock();
			XGetInputFocus(Disp,&win,&i);
			XMutex.Unlock();
			wp=NULL;
			for (i=Screen.WinPorts.GetCount()-1; i>=0; i--) {
				if (Screen.WinPorts[i]->Win==win) {
					wp=Screen.WinPorts[i];
					break;
				}
			}
			if (wp==this) {
				if (!Focused) {
					Focused=true;
					SetViewFocused(true);
					emWarning("emX11WindowPort: Focus workaround 1 applied.");
				}
			}
			else {
				while (wp) {
					if (wp==this) break;
					wp=wp->Owner;
				}
				if (!wp) {
					XMutex.Lock();
					xs=XGetWindowAttributes(Disp,Win,&attr);
					XMutex.Unlock();
					if (xs && attr.map_state==IsViewable) {
						XMutex.Lock();
						XSetInputFocus(Disp,Win,RevertToNone,CurrentTime);
						XMutex.Unlock();
						emWarning("emX11WindowPort: Focus workaround 2 applied.");
					}
				}
			}
		}
	}

	if (
		!PostConstructed && !PosForced && Owner &&
		(GetWindowFlags()&emWindow::WF_FULLSCREEN)==0
	) {
		Screen.GetVisibleRect(&vrx,&vry,&vrw,&vrh);
		fx=Owner->GetViewX()-Owner->BorderL;
		fy=Owner->GetViewY()-Owner->BorderT;
		fw=Owner->GetViewWidth()+Owner->BorderL+Owner->BorderR;
		fh=Owner->GetViewHeight()+Owner->BorderT+Owner->BorderB;
		fx+=fw*0.5;
		fy+=fh*0.5;
		fw=GetViewWidth()+BorderL+BorderR;
		fh=GetViewHeight()+BorderT+BorderB;
		fx-=fw*0.5+emGetDblRandom(-0.03,0.03)*vrw;
		fy-=fh*0.5+emGetDblRandom(-0.03,0.03)*vrh;
		if (fx>vrx+vrw-fw) fx=vrx+vrw-fw;
		if (fy>vry+vrh-fh) fy=vry+vrh-fh;
		if (fx<vrx) fx=vrx;
		if (fy<vry) fy=vry;
		SetViewGeometry(
			fx+BorderL,fy+BorderT,
			GetViewWidth(),GetViewHeight(),
			Screen.PixelTallness
		);
		PosPending=true;
		PosForced=true;
	}

	if (PosPending || SizePending) {
		x=((int)GetViewX())-BorderL;
		y=((int)GetViewY())-BorderT;
		w=(int)GetViewWidth();
		h=(int)GetViewHeight();
		memset(&xsh,0,sizeof(xsh));
		xsh.flags     =PMinSize;
		xsh.min_width =MinPaneW;
		xsh.min_height=MinPaneH;
		if (PosForced) {
			xsh.flags|=PPosition|USPosition;
			xsh.x=x;
			xsh.y=y;
		}
		if (SizeForced) {
			xsh.flags|=PSize|USSize;
			xsh.width=w;
			xsh.height=h;
		}
		XMutex.Lock();
		XSetWMNormalHints(Disp,Win,&xsh);
		if (PosPending && SizePending) {
			XMoveResizeWindow(Disp,Win,x,y,w,h);
		}
		else if (PosPending) {
			XMoveWindow(Disp,Win,x,y);
		}
		else {
			XResizeWindow(Disp,Win,w,h);
		}
		XMutex.Unlock();
		PosPending=false;
		SizePending=false;
	}

	if (TitlePending) {
		str=GetWindowTitle();
		if (Title!=str) {
			Title=str;
			XMutex.Lock();
			XmbSetWMProperties(Disp,Win,Title.Get(),NULL,NULL,0,NULL,NULL,NULL);
			XMutex.Unlock();
		}
		TitlePending=false;
	}

	if (IconPending) {
		SetIconProperty(GetWindowIcon());
		IconPending=false;
	}

	if (CursorPending) {
		cur=GetViewCursor();
		if (Cursor!=cur) {
			Cursor=cur;
			xcur=Screen.GetXCursor(cur);
			XMutex.Lock();
			XDefineCursor(Disp,Win,xcur);
			XMutex.Unlock();
		}
		CursorPending=false;
	}

	if (!PostConstructed) {
		PostConstruct();
		PostConstructed=true;
	}

	if (!InvalidRects.IsEmpty() && Mapped) {
		UpdatePainting();
		if (!LaunchFeedbackSent) {
			LaunchFeedbackSent=true;
			SendLaunchFeedback();
		}
	}

	return false;
}
Пример #18
0
static Window find_window(Window top, char* name)
{
	char* wname;
	char* iname;
	XClassHint xch;
	Window* children;
	Window foo;
	int revert_to_return;
	unsigned int nc;

	if (!strcmp(active_window_name, name)) {
		XGetInputFocus(dpy, &foo, &revert_to_return);
		return foo;
	} else if (!strcmp(root_window_name, name)) {
		return root;
	}
	/* First the base case */
	if (XFetchName(dpy, top, &wname)) {
		if (!strncmp(wname, name, strlen(name))) {
			XFree(wname);
			log_debug("found it by wname 0x%x\n", top);
			return top;     /* found it! */
		}
		;
		XFree(wname);
	}
	;

	if (XGetIconName(dpy, top, &iname)) {
		if (!strncmp(iname, name, strlen(name))) {
			XFree(iname);
			log_debug("found it by iname 0x%x\n", top);
			return top;     /* found it! */
		}
		;
		XFree(iname);
	}
	;

	if (XGetClassHint(dpy, top, &xch)) {
		if (!strcmp(xch.res_class, name)) {
			XFree(xch.res_name);
			XFree(xch.res_class);
			log_debug("res_class '%s' res_name '%s' 0x%x\n",
				  xch.res_class, xch.res_name, top);
			return top;     /* found it! */
		}
		;
		if (!strcmp(xch.res_name, name)) {
			XFree(xch.res_name);
			XFree(xch.res_class);
			log_debug("res_class '%s' res_name '%s' 0x%x\n",
				  xch.res_class, xch.res_name, top);
			return top;     /* found it! */
		}
		;
		XFree(xch.res_name);
		XFree(xch.res_class);
	}
	;

	if (!XQueryTree(dpy, top, &foo, &foo, &children, &nc) || children == NULL)
		return 0;       /* no more windows here */
	;

	/* check all the sub windows */
	for (; nc > 0; nc--) {
		top = find_window(children[nc - 1], name);
		if (top)
			break;  /* we found it somewhere */
	}
	;
	if (children != NULL)
		XFree(children);
	return top;
}
Пример #19
0
static int get_focus(struct _focus *p, int *forced_mode, int *focus_status, int *autocompletion_mode)
{
	*forced_mode	= FORCE_MODE_NORMAL;
	*focus_status	= FOCUS_NONE;
	*autocompletion_mode	= AUTOCOMPLETION_INCLUDED;

	char *new_app_name = NULL;
		
	// Clear masking on unfocused window
	p->update_grab_events(p, LISTEN_DONTGRAB_INPUT);
	p->update_events(p, LISTEN_DONTGRAB_INPUT);

	Window new_window;
	int show_message = TRUE;
	while (TRUE)
	{
		// Wait for new window was focused.
		usleep(500000);
		
		// This code commented be cause function XGrabKey for _NET_ACTIVE_WINDOW 
		// dont process modifier keys (see utils.h)
		/*if (main_window->_NET_SUPPORTED)
		{
			Atom type;
			int size;
			long nitems;

			Atom request = XInternAtom(main_window->display, "_NET_ACTIVE_WINDOW", False);
			Window root = XDefaultRootWindow(main_window->display);
			unsigned char *data = get_win_prop(root, request, &nitems, &type, &size);

			if (nitems > 0) 
				new_window = *((Window*)data);
			else 
				new_window = None;

			free(data);
		}
		else
		{*/
			int revert_to;
			XGetInputFocus(main_window->display, &new_window, &revert_to);
		//}

		// Catch not empty and not system window
		if (new_window != None && new_window > 1000)
		{
			new_app_name = get_wm_class_name(new_window);
			if (new_app_name != NULL)
				break;
		}
		
		if (show_message)
		{
			log_message(DEBUG, _("New window empty"));
			show_message = FALSE;
		}
		usleep(100000);
	}

	//char *new_app_name = get_wm_class_name(new_window);
	//if (new_app_name != NULL)
	//{
		if (xconfig->excluded_apps->exist(xconfig->excluded_apps, new_app_name, BY_PLAIN))
			*focus_status = FOCUS_EXCLUDED;
		
		if (xconfig->auto_apps->exist(xconfig->auto_apps, new_app_name, BY_PLAIN))
			*forced_mode = FORCE_MODE_AUTO;
		else if (xconfig->manual_apps->exist(xconfig->manual_apps, new_app_name, BY_PLAIN))
			*forced_mode = FORCE_MODE_MANUAL;

		if (xconfig->autocompletion_excluded_apps->exist(xconfig->autocompletion_excluded_apps, new_app_name, BY_PLAIN))
			*autocompletion_mode	= AUTOCOMPLETION_EXCLUDED;
	//}
	//else
	//	*focus_status = FOCUS_EXCLUDED;

	Window old_window = p->owner_window;
	if (new_window == old_window)
	{
		if (new_app_name != NULL)
			free(new_app_name);
		if (xconfig->troubleshoot_full_screen)
		{
			Window root_return;
			int x_return, y_return, root_x_return, root_y_return;
			unsigned int width_return, height_return, root_width_return, root_height_return;
			unsigned int border_width_return;
			unsigned int depth_return;
			XGetGeometry(main_window->display, p->parent_window, &root_return, &x_return, &y_return, &width_return, 
							&height_return, &border_width_return, &depth_return);
			XGetGeometry(main_window->display, root_return, &root_return, &root_x_return, &root_y_return, &root_width_return, 
							&root_height_return, &border_width_return, &depth_return);
			if ((x_return == 0) && (y_return == 0) && 
			    (width_return == root_width_return) && (height_return == root_height_return))
				*forced_mode = FORCE_MODE_MANUAL;
		}
		return FOCUS_UNCHANGED;
	}

	log_message(DEBUG, _("Focused window %d"), new_window);

	// Up to heighted window
	p->parent_window = new_window;
	while (TRUE)
	{
		unsigned int children_count;
		Window root_window, parent_window;
		Window *children_return = NULL;

		int is_same_screen = XQueryTree(main_window->display, p->parent_window, &root_window, &parent_window, &children_return, &children_count);
		if (children_return != NULL)
			XFree(children_return);
		if (!is_same_screen || parent_window == None || parent_window == root_window)
			break;

		p->parent_window = parent_window;
	}

	// Replace unfocused window to focused window
	p->owner_window = new_window;

	if (xconfig->troubleshoot_full_screen)
	{
		Window root_return;
		int x_return, y_return, root_x_return, root_y_return;
		unsigned int width_return, height_return, root_width_return, root_height_return;
		unsigned int border_width_return;
		unsigned int depth_return;
		XGetGeometry(main_window->display, p->parent_window, &root_return, &x_return, &y_return, &width_return, 
						&height_return, &border_width_return, &depth_return);
		XGetGeometry(main_window->display, root_return, &root_return, &root_x_return, &root_y_return, &root_width_return, 
						&root_height_return, &border_width_return, &depth_return);
		if ((x_return == 0) && (y_return == 0) && 
			(width_return == root_width_return) && (height_return == root_height_return))
			*forced_mode = FORCE_MODE_MANUAL;
	}
	
	log_message(DEBUG, _("Process new window (ID %d) with name '%s' (status %s, mode %s)"), new_window, new_app_name, _(verbose_focus_status[*focus_status]), _(verbose_forced_mode[*forced_mode]));
	
	if (new_app_name != NULL)
		free(new_app_name);
	return FOCUS_CHANGED;
}
Пример #20
0
int main(int argc, char* argv[])
{
	char keyname[128];
	int pointer_button, pointer_x, pointer_y;
	char windowname[64];
	struct lirc_config* config;
	char* config_file = NULL;
	int c;
	unsigned int WindowID;

	while ((c = getopt_long(argc, argv, "dhV", long_options, NULL)) != EOF) {
		switch (c) {
		case 'd':
			bDaemon = 1;
			continue;
		case 'h':
			printf("Usage: %s [option]... [config file]\n"
			       "       -d --daemon     fork and run in background\n"
			       "       -h --help       display usage summary\n"
			       "       -V --version    display version\n", prog);
			return EXIT_SUCCESS;
		case 'V':
			printf("%s %s\n", prog, VERSION);
			return EXIT_SUCCESS;
		case '?':
			fprintf(stderr, "unrecognized option: -%c\n", optopt);
			fprintf(stderr, "Try `%s --help' for more information.\n", prog);
			return EXIT_FAILURE;
		}
	}

	if (argc == optind + 1) {
		config_file = argv[optind];
	} else if (argc > optind + 1) {
		fprintf(stderr, "%s: incorrect number of arguments.\n", prog);
		fprintf(stderr, "Try `%s --help' for more information.\n", prog);
		return EXIT_FAILURE;
	}

	dpy = XOpenDisplay(NULL);
	if (dpy == NULL) {
		fprintf(stderr, "Can't open DISPLAY.\n");
		exit(1);
	}
	root = RootWindow(dpy, DefaultScreen(dpy));

	// windows may get closed at wrong time. Override default error handler...
	XSetErrorHandler(errorHandler);

	if (lirc_init("irxevent", 1) == -1)
		exit(EXIT_FAILURE);

	if (lirc_readconfig(config_file, &config, check) == 0) {
		char* ir;
		char* c;
		int ret;

		if (bDaemon) {
			if (daemon(1, 0) < 0) {
				perror("Failed to run as daemon");
				exit(EXIT_FAILURE);
			}
		}

		while (lirc_nextcode(&ir) == 0) {
			if (ir == NULL)
				continue;
			while ((ret = lirc_code2char(config, ir, &c)) == 0 && c != NULL) {
				log_debug("Received code: %s Sending:\n", ir);
				bInError = 0;   // reset error state, want to see error msg

				*windowname = 0;
				if (2 == sscanf(c, "Key %s Focus WindowID %i", keyname, &WindowID) ||
				    4 == sscanf(c, "Button %d %d %d Focus WindowID %i", &pointer_button, &pointer_x,
						&pointer_y, &WindowID)
				    || 4 == sscanf(c, "xy_Key %d %d %s Focus WindowID %i", &pointer_x, &pointer_y,
						   keyname, &WindowID)
				    || 2 == sscanf(c, "Key %s Focus %s", keyname, windowname)
				    || 4 == sscanf(c, "Button %d %d %d Focus %s", &pointer_button, &pointer_x,
						   &pointer_y, windowname)
				    || 4 == sscanf(c, "xy_Key %d %d %s Focus %s", &pointer_x, &pointer_y, keyname,
						   windowname)) {
					log_debug("Focus\n");
					/* focussed ? */
					if (*windowname) {
						WindowID = find_window_focused(root, windowname);
						if (!WindowID) {
							log_debug("target window '%s' doesn't have focus\n",
								  windowname);
							continue;
						}
						log_debug("focused:  %s\n", windowname);
					} else {
						Window cur;
						int tmp;

						XGetInputFocus(dpy, &cur, &tmp);
						if (WindowID != cur) {
							log_debug("target window '0x%x' doesn't have focus\n",
								  WindowID);
							continue;
						}
						log_debug("focused:  0x%x\n", WindowID);
					}
				} else if (2 == sscanf(c, "Key %s WindowID %i", keyname, &WindowID) ||
					   4 == sscanf(c, "Button %d %d %d WindowID %i", &pointer_button, &pointer_x,
						       &pointer_y, &WindowID)
					   || 4 == sscanf(c, "xy_Key %d %d %s WindowID %i", &pointer_x, &pointer_y,
							  keyname, &WindowID)) {
					log_debug("WindowID:  0x%x\n", WindowID);
					/* WindowID passed */
				} else if (2 == sscanf(c, "Key %s %s", keyname, windowname) ||
					   4 == sscanf(c, "Button %d %d %d %s", &pointer_button, &pointer_x, &pointer_y,
						       windowname)
					   || 4 == sscanf(c, "xy_Key %d %d %s %s\n", &pointer_x, &pointer_y, keyname,
							  windowname)) {
					log_debug("name: %s\n", windowname);
					WindowID = find_window(root, windowname);
					if (WindowID == 0) {
						log_debug("target window '%s' not found\n", windowname);
						continue;
					}
				}

				switch (c[0]) {
				case 'K':       // Key
					log_debug("keyname: %s \t WindowID: 0x%x\n", keyname, WindowID);
					log_debug("%s\n", c);
					sendkey(keyname, 1, 1, (Window)WindowID, 0);
					break;

				case 'B':       // Button
				case 'x':       // xy_Key
					subw = find_sub_window(root, windowname, &pointer_x, &pointer_y);
					if (subw) {
						if (WindowID == subw)
							subw = 0;
						log_debug("%s\n", c);
						switch (c[0]) {
						case 'B':
							/* FIXME: pointer_button potentially uninititalzed. */
							sendbutton(pointer_button, pointer_x, pointer_y, WindowID,
								   subw);
							break;
						case 'x':
							sendkey(keyname, pointer_x, pointer_y, WindowID, subw);
							break;
						}
					}
					break;
				}
			}
			free(ir);
			if (ret == -1)
				break;
		}
		lirc_freeconfig(config);
	}

	lirc_deinit();

	exit(0);
}
Пример #21
0
int
main(int argc, char *argv[])
{
	KeySym key;
	XEvent event;
	int hidden = 1;
	int fullscreen = 0;
	int i, tmp;
	int old_height = 0;
	Window tmpwin, last_focused, current_focused;
	XWindowAttributes wa;

	/* strip the path from argv[0] if there is one */
	progname = strrchr(argv[0], '/');
	if (!progname)
		progname = argv[0];
	else
		progname++;

	for (i = 1; i < argc; i++) {
		if (!strcmp(argv[i], "-h")) {
			printf("%s:\n"
				   "-e: program to execute\n"
				   "you can configure me via xresources:\n"
				   "%s*foo:value\n"
				   "foo can be any standard xterm/urxvt/st xresource or:\n"
				   "resource               default value\n\n"
				   "term:                  xterm\n"
				   "restart:               0\n"
				   "xOffset:               0\n"
				   "yOffset:               0\n"
				   "xrandrSupport:         0\n"
				   "screenWidth:           Display width\n"
				   "consoleHeight:         10\n"
				   "aniDelay:              40\n"
				   "stepSize;              1\n"
				   "toggleKey:             ControlAlt+y\n"
				   "keySmaller:            Control+KP_Subtract\n"
				   "keyBigger:             Control+KP_Add\n" "keyFull:               Alt+F11\n", progname, progname);
			exit(0);
		}
	}

	if (!(dpy = XOpenDisplay(NULL))) {
		fprintf(stderr, " can not open dpy %s", XDisplayName(NULL));
	}
	screen = DefaultScreen(dpy);
	root = RootWindow(dpy, screen);
	XSetErrorHandler(handle_xerror);
	cursor = XCreateFontCursor(dpy, XC_double_arrow);
	get_defaults();
	init_win();
	init_command(argc, argv);
	init_xterm(1);
	while (1) {
		XNextEvent(dpy, &event);
		switch (event.type) {
		case FocusOut:
			/* Always keep input focus when visible */
			if (!hidden)
				XSetInputFocus(dpy, termwin, RevertToPointerRoot, CurrentTime);
			break;
		case EnterNotify:
			XSetInputFocus(dpy, termwin, RevertToPointerRoot, CurrentTime);
			XSync(dpy, False);
			break;
		case LeaveNotify:
			if (last_focused && event.xcrossing.detail != NotifyInferior) {
				XSetInputFocus(dpy, last_focused, RevertToPointerRoot, CurrentTime);
				XSync(dpy, False);
			}
			break;
		case KeyPress:
			key = XKeycodeToKeysym(dpy, event.xkey.keycode, 0);
			if (key == opt_key) {
				if (!hidden) {
					XGetInputFocus(dpy, &current_focused, &revert_to);
					if (last_focused && current_focused == termwin)
						XSetInputFocus(dpy, last_focused, RevertToPointerRoot, CurrentTime);
					/* else
					   XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); */
					if (opt_step && !fullscreen)
						roll(UP);
					XUnmapWindow(dpy, win);
					hidden = 1;
					XSync(dpy, False);
				}
				else {
					XGetInputFocus(dpy, &last_focused, &revert_to);
					last_focused = get_toplevel_parent(last_focused);

					if (opt_step && !fullscreen) {
						XGrabServer(dpy);
						roll(DOWN);
						XUngrabServer(dpy);
					}
					else if (opt_xrandr)
						update_geom(last_focused);
					XMoveWindow(dpy, win, opt_x, opt_y);
					XMapWindow(dpy, win);
					XRaiseWindow(dpy, win);
					XSetInputFocus(dpy, termwin, RevertToPointerRoot, CurrentTime);
					hidden = 0;
					XSync(dpy, False);
					XSetInputFocus(dpy, termwin, RevertToPointerRoot, CurrentTime);
					XSync(dpy, False);
				}
				break;
			}
			if (!hidden) {
				if (key == opt_key_full) {
					if (!fullscreen) {
						old_height = height;
						height = get_optimal_height(get_display_height());
						fullscreen = 1;
					}
					else {
						height = old_height;
						fullscreen = 0;
					}
				}

				/* update height inc just in case something changed for the
				 * terminal, i.e. font size */
				resize_inc = get_height_inc();
				if (key == opt_key_bigger)
					height += resize_inc;
				if (key == opt_key_smaller)
					height -= resize_inc;
				if (height < resize_inc)
					height = resize_inc;
				height = get_optimal_height(height);
				resize_term(opt_width, height);
				XSetInputFocus(dpy, termwin, RevertToPointerRoot, CurrentTime);
				XSync(dpy, False);
			}
			break;
		case ButtonPress:
			resize();
			XSync(dpy, False);
			break;
		case UnmapNotify:
			if (event.xunmap.window == termwin) {
				if (opt_restart) {
					if (opt_restart_hidden) {
						roll(UP);
						hidden = 1;
					}
					init_xterm(0);
					XSync(dpy, False);
					if (opt_restart_hidden && last_focused)
						XSetInputFocus(dpy, last_focused, RevertToPointerRoot, CurrentTime);
					else
						XSetInputFocus(dpy, termwin, RevertToPointerRoot, CurrentTime);
				}
				else {
					if (last_focused)
						XSetInputFocus(dpy, last_focused, RevertToPointerRoot, CurrentTime);
					XSync(dpy, False);
					exit(0);
				}
			}
			break;
		}
	}
	return 0;
}
Пример #22
0
void keylogger(void **hdlarr) {
    
    BUFFER *b;
    b = initBuffer();
    Display *display;

    char keyboardState[32];
    char keyboardStateOld[32] = {0};

    char bit, bitOld;
    int  iCheck;

    char keyboardStatesym, *keyboardStateString;
 
    time_t timeout = 0;

    int keyCode;
    int needToFree = 0;

    Window focusWin = NULL, oldfocusWin = NULL;
    int iReverToReturn = NULL;

    display = XOpenDisplay(NULL);

    if (display == NULL) {
        printf("Error: XOpenDisplay\n");
        exit(1);
    }

    int logging = 0;

    while(1) { 

        usleep(SLEEP);

        if ((logging == 1) && (time(NULL) > timeout)) {
            logging = 0;
            moduleFeed(hdlarr, b->buffer);
            emptyData(b);
        }
            
        XQueryKeymap(display, keyboardState);
        
        if (memcmp(keyboardState, keyboardStateOld, 32) != NULL) {
            
            /*
            XImage* pic;
            pic = XGetImage(display, RootWindow(display, DefaultScreen(display)), 10, 10, 201, 201, AllPlanes, ZPixmap);   
            */

            int i = 0, j = 0;

            for(i = 0; i < sizeof( keyboardState ); i++) {
                bit = keyboardState[i];
                bitOld = keyboardStateOld[i];
                iCheck = 1;

                for ( j = 0 ; j < 8 ; j++ ) {
                    if ((bit & iCheck) && !(bitOld & iCheck)) {
                        keyCode = i * 8 + j;

                        keyboardStatesym = XkbKeycodeToKeysym(display, keyCode, 0, 0);
                        keyboardStateString = XKeysymToString(keyboardStatesym);

                        if (keyboardStateString == NULL) { 
                            switch (keyCode) {
                                case 22:
                                    keyboardStateString = "backspace";
                                    break;
                                case 36:
                                    keyboardStateString = "enter";
                                    break;
                                default:
                                    keyboardStateString = "unknown";
                            }
                        }

                        if (strlen(keyboardStateString) > 1) {
                            addParentheses(&keyboardStateString);
                            needToFree = 1;
                        }

                         // Get current active window
                        oldfocusWin = focusWin;
                        XGetInputFocus(display, &focusWin, &iReverToReturn);

                        if (!background) {
                            printf("WindowID %x Key: %s Code: %i\n", focusWin, keyboardStateString, keyCode);
                        }

                        if (focusWin != oldfocusWin) {
                            moduleFeed(hdlarr, b->buffer);
                            emptyData(b);
                        }


                        addData(b, keyboardStateString);
                        //printf("Contents of buffer: %s", b->buffer);

                        timeout = time(NULL) + INTERVALOFINACTIVITY;
                        logging = 1;

                        if (needToFree) {
                            free(keyboardStateString);
                            needToFree = 0;
                        }

                    }
                    iCheck = iCheck << 1 ;
                }
            }
        }
        memcpy(keyboardStateOld, keyboardState, 32);
    }
    XCloseDisplay(display);
}
Пример #23
0
void
setup(void) {
	int x, y, screen = DefaultScreen(dc->dpy);
	Window root = RootWindow(dc->dpy, screen);
	XSetWindowAttributes swa;
	XIM xim;
#ifdef XINERAMA
	int n;
	XineramaScreenInfo *info;
#endif

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

	/* calculate menu geometry */
	bh = (line_height > dc->font.height + 2) ? line_height : dc->font.height + 2;
	lines = MAX(lines, 0);
	mh = (lines + 1) * bh;
#ifdef XINERAMA
	if((info = XineramaQueryScreens(dc->dpy, &n))) {
		int a, j, di, i = 0, area = 0;
		unsigned int du;
		Window w, pw, dw, *dws;
		XWindowAttributes wa;

		XGetInputFocus(dc->dpy, &w, &di);
		if(w != root && w != PointerRoot && w != None) {
			/* find top-level window containing current input focus */
			do {
				if(XQueryTree(dc->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(dc->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(!area && XQueryPointer(dc->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 ? yoffset : info[i].height - mh - yoffset);
		mw = info[i].width;
		XFree(info);
	}
	else
#endif
	{
		x = 0;
		y = topbar ? 0 : DisplayHeight(dc->dpy, screen) - mh - yoffset;
		mw = DisplayWidth(dc->dpy, screen);
	}

	x += xoffset;
	mw = width ? width : mw;
	promptw = (prompt && *prompt) ? textw(dc, prompt) : 0;
	inputw = MIN(inputw, mw/3);
	match();

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

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

	XMapRaised(dc->dpy, win);
	resizedc(dc, mw, mh);
	drawmenu();
}
Пример #24
0
Файл: menu.c Проект: S010/cwm
struct menu *
menu_filter(struct screen_ctx *sc, struct menu_q *menuq, char *prompt,
    char *initial, int dummy,
    void (*match)(struct menu_q *, struct menu_q *, char *),
    void (*print)(struct menu *, int))
{
	struct menu_ctx		 mc;
	struct menu_q		 resultq;
	struct menu		*mi = NULL;
	XEvent			 e;
	Window			 focuswin;
	int			 evmask, focusrevert;
	int			 xsave, ysave, xcur, ycur;

	TAILQ_INIT(&resultq);

	bzero(&mc, sizeof(mc));

	xu_ptr_getpos(sc->rootwin, &mc.x, &mc.y);

	xsave = mc.x;
	ysave = mc.y;

	if (prompt == NULL) {
		evmask = MENUMASK;
		mc.promptstr[0] = '\0';
		mc.list = 1;
	} else {
		evmask = MENUMASK | KEYMASK; /* only accept keys if prompt */
		(void)snprintf(mc.promptstr, sizeof(mc.promptstr), "%s%s",
		    prompt, PROMPT_SCHAR);
		(void)snprintf(mc.dispstr, sizeof(mc.dispstr), "%s%s%s",
		    mc.promptstr, mc.searchstr, PROMPT_ECHAR);
		mc.width = font_width(sc, mc.dispstr, strlen(mc.dispstr));
		mc.hasprompt = 1;
	}

	if (initial != NULL)
		(void)strlcpy(mc.searchstr, initial, sizeof(mc.searchstr));
	else
		mc.searchstr[0] = '\0';

	mc.match = match;
	mc.print = print;
	mc.entry = mc.prev = -1;

	XMoveResizeWindow(X_Dpy, sc->menuwin, mc.x, mc.y, mc.width,
	    font_height(sc));
	XSelectInput(X_Dpy, sc->menuwin, evmask);
	XMapRaised(X_Dpy, sc->menuwin);

	if (xu_ptr_grab(sc->menuwin, MENUGRABMASK, Cursor_question) < 0) {
		XUnmapWindow(X_Dpy, sc->menuwin);
		return (NULL);
	}

	XGetInputFocus(X_Dpy, &focuswin, &focusrevert);
	XSetInputFocus(X_Dpy, sc->menuwin, RevertToPointerRoot, CurrentTime);

	/* make sure keybindings don't remove keys from the menu stream */
	XGrabKeyboard(X_Dpy, sc->menuwin, True,
	    GrabModeAsync, GrabModeAsync, CurrentTime);

	menu_draw(sc, &mc, menuq, &resultq);

	for (;;) {
		mc.changed = 0;

		XWindowEvent(X_Dpy, sc->menuwin, evmask, &e);

		switch (e.type) {
		case KeyPress:
			if ((mi = menu_handle_key(&e, &mc, menuq, &resultq))
			    != NULL)
				goto out;
			/* FALLTHROUGH */
		case Expose:
			menu_draw(sc, &mc, menuq, &resultq);
			break;
		case MotionNotify:
			menu_handle_move(&e, &mc, &resultq, sc);
			break;
		case ButtonRelease:
			if ((mi = menu_handle_release(&e, &mc, sc, &resultq))
			    != NULL)
				goto out;
			break;
		default:
			break;
		}
	}
out:
	if (dummy == 0 && mi->dummy) { /* no mouse based match */
		xfree(mi);
		mi = NULL;
	}

	XSetInputFocus(X_Dpy, focuswin, focusrevert, CurrentTime);
	/* restore if user didn't move */
	xu_ptr_getpos(sc->rootwin, &xcur, &ycur);
	if (xcur == mc.x && ycur == mc.y)
		xu_ptr_setpos(sc->rootwin, xsave, ysave);
	xu_ptr_ungrab();

	XUnmapWindow(X_Dpy, sc->menuwin);
	XUngrabKeyboard(X_Dpy, CurrentTime);

	return (mi);
}
Пример #25
0
char *
get_more_input (char *prompt, char *preinput, int history_id,
                completion_fn compl_fn)
{
  /* Emacs 21 uses a 513 byte string to store the keysym name. */
  char keysym_buf[513];
  rp_screen *s = current_screen ();
  KeySym ch;
  unsigned int modifier;
  rp_input_line *line;
  char *final_input;
  edit_status status;
  Window focus;
  int revert, done = 0;

  history_reset();

  /* Create our line structure */
  line = input_line_new (prompt, preinput, history_id, compl_fn);

  /* We don't want to draw overtop of the program bar. */
  hide_bar (s);

  /* Switch to the default colormap. */
  if (current_window())
    XUninstallColormap (dpy, current_window()->colormap);
  XInstallColormap (dpy, s->def_cmap);

  XMapWindow (dpy, s->input_window);
  XRaiseWindow (dpy, s->input_window);
  XClearWindow (dpy, s->input_window);
  /* Switch focus to our input window to read the next key events. */
  XGetInputFocus (dpy, &focus, &revert);
  set_window_focus (s->input_window);
  XSync (dpy, False);

  update_input_window (s, line);

  while (!done)
    {
      read_key (&ch, &modifier, keysym_buf, sizeof (keysym_buf));
      modifier = x11_mask_to_rp_mask (modifier);
      PRINT_DEBUG (("ch = %ld, modifier = %d, keysym_buf = %s",
                    ch, modifier, keysym_buf));
      status = execute_edit_action (line, ch, modifier, keysym_buf);

      switch (status)
        {
        case EDIT_COMPLETE:
        case EDIT_DELETE:
        case EDIT_INSERT:
        case EDIT_MOVE:
          /* If the text changed (and we didn't just complete
             something) then set the virgin bit. */
          if (status != EDIT_COMPLETE)
            line->compl->virgin = 1;
          /* In all cases, we need to redisplay the input string. */
          update_input_window (s, line);
          break;
        case EDIT_NO_OP:
          ring_bell ();
          break;
        case EDIT_ABORT:
          final_input = NULL;
          done = 1;
          break;
        case EDIT_DONE:
          final_input = xstrdup (line->buffer);
          done = 1;
          break;
        default:
          PRINT_ERROR (("Unhandled status %d; this is a *BUG*\n", status));
          exit (EXIT_FAILURE);
        }
    }

  /* Clean up our line structure */
  input_line_free (line);

  /* Revert focus. */
  set_window_focus (focus);
  XUnmapWindow (dpy, s->input_window);

  /* Possibly restore colormap. */
  if (current_window())
    {
      XUninstallColormap (dpy, s->def_cmap);
      XInstallColormap (dpy, current_window()->colormap);
    }

  return final_input;
}
Пример #26
0
void greate_win_flag(xkb_info *k,gpointer data)
{
	//int timer;
	AConvert *aconv = (AConvert *)data;
	int revert_to;
	Window focuswin;
	XWindowAttributes win_attributes;
	Window junkwin;
	int rx, ry, pos_x,pos_y=0;
	
	if(aconv->sxkb->view_flag==0)
		return;

	XGetInputFocus(GDK_DISPLAY(), &focuswin, &revert_to);
	if (focuswin) 
	{
		XGetWindowAttributes(GDK_DISPLAY(), focuswin, &win_attributes);

		XTranslateCoordinates (GDK_DISPLAY(), focuswin, win_attributes.root, 
				-win_attributes.border_width,-win_attributes.border_width,
				&rx, &ry, &junkwin);
		
		pos_x=rx;//((win_attributes.width/2)+rx);
		pos_y=ry;//((win_attributes.height/2)+ry);
	}
	else
	{
		pos_x=0;//200;
		pos_y=0;//200;
	}

	if(!aconv->sxkb->flag_win)
	{
		aconv->sxkb->flag_win = gtk_window_new (GTK_WINDOW_POPUP);
		gtk_widget_set_size_request (GTK_WIDGET(aconv->sxkb->flag_win), 32, 24);
		gtk_widget_set_uposition(GTK_WIDGET(aconv->sxkb->flag_win),pos_x,pos_y);
		//gtk_window_set_position (GTK_WINDOW (sven->sxkb->flag_win), GTK_WIN_POS_CENTER);
		
		aconv->sxkb->flag_image = gtk_image_new(); 
		gtk_widget_show (aconv->sxkb->flag_image);
		gtk_container_add (GTK_CONTAINER (aconv->sxkb->flag_win), aconv->sxkb->flag_image);
		gtk_widget_show_all (aconv->sxkb->flag_win);
	}
	else
	{
		if (k->flag_img)
		{
			GdkPixbuf *pixbuf=gdk_pixbuf_scale_simple (k->flag_img,32,24,GDK_INTERP_BILINEAR);
			gtk_image_set_from_pixbuf(GTK_IMAGE(aconv->sxkb->flag_image),pixbuf);
			g_object_unref(pixbuf);
		
		}
		else
		{
			GdkPixbuf *pixbuf=create_pixbuf_flag("zz",32,24);
			gtk_image_set_from_pixbuf(GTK_IMAGE(aconv->sxkb->flag_image),pixbuf);
			g_object_unref(pixbuf);
		}
		
		gtk_widget_set_uposition(GTK_WIDGET(aconv->sxkb->flag_win),pos_x,pos_y);
		gtk_widget_show_all (aconv->sxkb->flag_win);
	}
	
	 if (aconv->sxkb->timeId != 0)
            g_source_remove(aconv->sxkb->timeId);
	    
	 aconv->sxkb->timeId = g_timeout_add (800,timer_hide_win, aconv);
}
Пример #27
0
/* Returns the active top-level window. A top-level window is one that has WM_CLASS set.
 * May also return None. */
Window getCurrentWindow() {

	/* First get the window that has the input focus */
	Window currentWindow;
	int revert;
	XGetInputFocus(display, &currentWindow, &revert);

	if (currentWindow == None) {
		//if(debugMode) printf("Leave getCurrentWindow\n");
		return currentWindow;
	}

	/* Now go through parent windows until we find one with WM_CLASS set. */


	XClassHint* classHint = XAllocClassHint();
	if(classHint == NULL) {
		if(debugMode) printf("Couldn't allocate class hint!!\n");
		return None;
	}

	int i = 0;
	while (1) {
		//if(debugMode) printf("in Loop\n");
		i++;
		if(i >= 5) {
			if(debugMode) printf("Too many iterations in getCurrentWindow\n");
			XFree(classHint);
			//if(debugMode) printf("Leave getCurrentWindow\n");
			return None;
		}
		if (currentWindow == root || currentWindow == None) {
			//if(debugMode) printf("Reached root!\n");
			/* No top-level window available. Should never happen. */
			XFree(classHint);
			//if(debugMode) printf("Leave getCurrentWindow\n");
			return currentWindow;
		}

		//if(debugMode) printf("Call XGetClassHint!\n");
		if (XGetClassHint(display, currentWindow, classHint) == 0) {
			//if(debugMode) printf("Has no Class!\n");
			/* Has no WM_CLASS, thus no top-level window */
			Window parent = getParentWindow(currentWindow);

			if(parent == None || currentWindow == parent) {
				/* something wrong */
				XFree(classHint);
				return currentWindow;
			}
			/* Continue with parent until we find WM_CLASS */
			currentWindow = parent;
		} else {
			//if(debugMode) printf("Clean up class name!\n");
			if(classHint->res_class != NULL) XFree(classHint->res_class);
			if(classHint->res_name != NULL) XFree(classHint->res_name);
			XFree(classHint);
			//if(debugMode) printf("Leave getCurrentWindow\n");
			return currentWindow;
		}
	}
}
Пример #28
0
void
CaptureAllWindows (ScreenInfo *scr)
{
    int           i;
	unsigned int  nchildren;
	Window        root, parent, *children;
    Window        focused = None ;
    int           revert_to = RevertToNone ;
    XWindowAttributes attr;

	if( scr == NULL )
		return ;
	focused = XGetInputFocus( dpy, &focused, &revert_to );

	if (!XQueryTree (dpy, scr->Root, &root, &parent, &children, &nchildren))
		return;

    /* weed out icon windows : */
	for (i = 0; i < nchildren; i++)
        if (children[i] )
		{
			XWMHints     *wmhintsp = NULL;
            if( (wmhintsp = XGetWMHints (dpy, children[i])) != NULL )
            {
                if( get_flags(wmhintsp->flags, IconWindowHint) )
                {
                    register int j ;
                    for (j = 0; j < nchildren; j++)
						if (children[j] == wmhintsp->icon_window)
						{
							children[j] = None;
							break;
						}
				}
				XFree ((char *)wmhintsp);
			}
		}

    /* map all the rest of the windows : */
    for (i = 0; i < nchildren; i++)
        if (children[i] )
        {
            long nitems = 0;
            CARD32 *state_prop = NULL ;
            int wm_state = DontCareState ;
            int k ;
            for( k = 0 ; k < 4 ; ++k )
                if( children[i] == Scr.PanFrame[k].win )
                {
                    children[i] = None ;
                    break;
                }

            if( children[i] == None )
                continue;

            if( children[i] == Scr.SizeWindow || children[i] == Scr.ServiceWin )
                continue;

            if( window2ASWindow (children[i])  )
                continue;
            /* weed out override redirect windows and unmapped windows : */
            if ( !XGetWindowAttributes (dpy, children[i], &attr) )
                continue;
            if( attr.override_redirect )
                continue;
            if( read_32bit_proplist (children[i], _XA_WM_STATE, 2, &state_prop, &nitems) )
			{
                wm_state = state_prop[0] ;
				free( state_prop );
			}
            if( (wm_state == IconicState) || (attr.map_state != IsUnmapped))
			{
				LOCAL_DEBUG_OUT( "adding window %lX", children[i] );	  
                AddWindow( children[i], False );
			}
		}

    if (children)
		XFree ((char *)children);

    if( focused != None && focused != PointerRoot )
    {
        ASWindow *t = window2ASWindow( focused );
        if( t )
            activate_aswindow( t, False, False );
    }
}