static Bool IsMouseActive (WindowPtr pWin) { struct _Window *pwin; struct _Property *prop; /* XXX We're getting inputInfo.poniter here, but this might be really wrong. * Which pointer's current window do we want? */ WindowPtr pRoot = GetCurrentRootWindow (inputInfo.pointer); if (!pWin) { ErrorF ("IsMouseActive - pWin was NULL use default value:%d\n", MOUSE_ACTIVATE_DEFAULT); return MOUSE_ACTIVATE_DEFAULT; } pwin = (struct _Window*) pWin; if (pwin->optional) prop = (struct _Property *) pwin->optional->userProps; else prop = NULL; while (prop) { if (prop->propertyName == AtmWindowsWMMouseActivate () && prop->type == XA_INTEGER && prop->format == 32) { return *(int*)prop->data; } else prop = prop->next; } if (pWin != pRoot) { return IsMouseActive (pRoot); } else { #if CYGMULTIWINDOW_DEBUG winDebug ("IsMouseActive - no prop use default value:%d\n", MOUSE_ACTIVATE_DEFAULT); #endif return MOUSE_ACTIVATE_DEFAULT; } }
static Bool IsMouseActive (WindowPtr pWin) { struct _Window *pwin; struct _Property *prop; WindowPtr pRoot = GetCurrentRootWindow (); if (!pWin) { ErrorF ("IsMouseActive - pWin was NULL use default value:%d\n", MOUSE_ACTIVATE_DEFAULT); return MOUSE_ACTIVATE_DEFAULT; } pwin = (struct _Window*) pWin; if (pwin->optional) prop = (struct _Property *) pwin->optional->userProps; else prop = NULL; while (prop) { if (prop->propertyName == AtmWindowsWMMouseActivate () && prop->type == XA_INTEGER && prop->format == 32) { return *(int*)prop->data; } else prop = prop->next; } if (pWin != pRoot) { return IsMouseActive (pRoot); } else { #if CYGMULTIWINDOW_DEBUG winDebug ("IsMouseActive - no prop use default value:%d\n", MOUSE_ACTIVATE_DEFAULT); #endif return MOUSE_ACTIVATE_DEFAULT; } }
static Bool IsRaiseOnClick (WindowPtr pWin) { struct _Window *pwin; struct _Property *prop; WindowPtr pRoot = GetCurrentRootWindow (); if (!pWin) { ErrorF ("IsRaiseOnClick - no prop use default value:%d\n", RAISE_ON_CLICK_DEFAULT); return RAISE_ON_CLICK_DEFAULT; } pwin = (struct _Window*) pWin; if (pwin->optional) prop = (struct _Property *) pwin->optional->userProps; else prop = NULL; while (prop) { if (prop->propertyName == AtmWindowsWmRaiseOnClick () && prop->type == XA_INTEGER && prop->format == 32) { return *(int*)prop->data; } else prop = prop->next; } if (pWin != pRoot) { return IsRaiseOnClick (pRoot); } else { #if CYGMULTIWINDOW_DEBUG winDebug ("IsRaiseOnClick - no prop use default value:%d\n", RAISE_ON_CLICK_DEFAULT); #endif return RAISE_ON_CLICK_DEFAULT; } }
/* * When the screen is reconfigured, move all pointers to the nearest * CRTC */ void RRPointerScreenConfigured(ScreenPtr pScreen) { WindowPtr pRoot; ScreenPtr pCurrentScreen; int x, y; DeviceIntPtr pDev; for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { if (IsPointerDevice(pDev)) { pRoot = GetCurrentRootWindow(pDev); pCurrentScreen = pRoot ? pRoot->drawable.pScreen : NULL; if (pScreen == pCurrentScreen) { GetSpritePosition(pDev, &x, &y); RRPointerToNearestCrtc(pDev, pScreen, x, y, NULL); } } } }
int ProcXIQueryPointer(ClientPtr client) { int rc; xXIQueryPointerReply rep; DeviceIntPtr pDev, kbd; WindowPtr pWin, t; SpritePtr pSprite; XkbStatePtr state; char *buttons = NULL; int buttons_size = 0; /* size of buttons array */ REQUEST(xXIQueryPointerReq); REQUEST_SIZE_MATCH(xXIQueryPointerReq); rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixReadAccess); if (rc != Success) { client->errorValue = stuff->deviceid; return rc; } if (pDev->valuator == NULL || IsKeyboardDevice(pDev) || (!IsMaster(pDev) && pDev->u.master)) /* no attached devices */ { client->errorValue = stuff->deviceid; return BadDevice; } rc = dixLookupWindow(&pWin, stuff->win, client, DixGetAttrAccess); if (rc != Success) { SendErrorToClient(client, IReqCode, X_XIQueryPointer, stuff->win, rc); return Success; } if (pDev->valuator->motionHintWindow) MaybeStopHint(pDev, client); if (IsMaster(pDev)) kbd = GetPairedDevice(pDev); else kbd = (pDev->key) ? pDev : NULL; pSprite = pDev->spriteInfo->sprite; memset(&rep, 0, sizeof(rep)); rep.repType = X_Reply; rep.RepType = X_XIQueryPointer; rep.length = 6; rep.sequenceNumber = client->sequence; rep.root = (GetCurrentRootWindow(pDev))->drawable.id; rep.root_x = FP1616(pSprite->hot.x, 0); rep.root_y = FP1616(pSprite->hot.y, 0); rep.child = None; if (kbd) { state = &kbd->key->xkbInfo->prev_state; rep.mods.base_mods = state->base_mods; rep.mods.latched_mods = state->latched_mods; rep.mods.locked_mods = state->locked_mods; rep.group.base_group = state->base_group; rep.group.latched_group = state->latched_group; rep.group.locked_group = state->locked_group; } if (pDev->button) { int i, down; rep.buttons_len = bytes_to_int32(bits_to_bytes(pDev->button->numButtons)); rep.length += rep.buttons_len; buttons_size = rep.buttons_len * 4; buttons = xcalloc(1, buttons_size); if (!buttons) return BadAlloc; down = pDev->button->buttonsDown; for (i = 0; i < pDev->button->numButtons && down; i++) { if (BitIsOn(pDev->button->down, i)) { SetBit(buttons, i); down--; } } } else rep.buttons_len = 0; if (pSprite->hot.pScreen == pWin->drawable.pScreen) { rep.same_screen = xTrue; rep.win_x = FP1616(pSprite->hot.x - pWin->drawable.x, 0); rep.win_y = FP1616(pSprite->hot.y - pWin->drawable.y, 0); for (t = pSprite->win; t; t = t->parent) if (t->parent == pWin) { rep.child = t->drawable.id; break; } } else { rep.same_screen = xFalse; rep.win_x = 0; rep.win_y = 0; } #ifdef PANORAMIX if(!noPanoramiXExtension) { rep.root_x += FP1616(panoramiXdataPtr[0].x, 0); rep.root_y += FP1616(panoramiXdataPtr[0].y, 0); if (stuff->win == rep.root) { rep.win_x += FP1616(panoramiXdataPtr[0].x, 0); rep.win_y += FP1616(panoramiXdataPtr[0].y, 0); } } #endif WriteReplyToClient(client, sizeof(xXIQueryPointerReply), &rep); if (buttons) WriteToClient(client, buttons_size, buttons); xfree(buttons); return Success; }
int ProcXIQueryPointer(ClientPtr client) { int rc; xXIQueryPointerReply rep; DeviceIntPtr pDev, kbd; WindowPtr pWin, t; SpritePtr pSprite; XkbStatePtr state; char *buttons = NULL; int buttons_size = 0; /* size of buttons array */ XIClientPtr xi_client; Bool have_xi22 = FALSE; REQUEST(xXIQueryPointerReq); REQUEST_SIZE_MATCH(xXIQueryPointerReq); /* Check if client is compliant with XInput 2.2 or later. Earlier clients * do not know about touches, so we must report emulated button presses. 2.2 * and later clients are aware of touches, so we don't include emulated * button presses in the reply. */ xi_client = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey); if (version_compare(xi_client->major_version, xi_client->minor_version, 2, 2) >= 0) have_xi22 = TRUE; rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixReadAccess); if (rc != Success) { client->errorValue = stuff->deviceid; return rc; } if (pDev->valuator == NULL || IsKeyboardDevice(pDev) || (!IsMaster(pDev) && !IsFloating(pDev))) { /* no attached devices */ client->errorValue = stuff->deviceid; return BadDevice; } rc = dixLookupWindow(&pWin, stuff->win, client, DixGetAttrAccess); if (rc != Success) { client->errorValue = stuff->win; return rc; } if (pDev->valuator->motionHintWindow) MaybeStopHint(pDev, client); if (IsMaster(pDev)) kbd = GetMaster(pDev, MASTER_KEYBOARD); else kbd = (pDev->key) ? pDev : NULL; pSprite = pDev->spriteInfo->sprite; rep = (xXIQueryPointerReply) { .repType = X_Reply, .RepType = X_XIQueryPointer, .sequenceNumber = client->sequence, .length = 6, .root = (GetCurrentRootWindow(pDev))->drawable.id, .root_x = double_to_fp1616(pSprite->hot.x), .root_y = double_to_fp1616(pSprite->hot.y), .child = None }; if (kbd) { state = &kbd->key->xkbInfo->state; rep.mods.base_mods = state->base_mods; rep.mods.latched_mods = state->latched_mods; rep.mods.locked_mods = state->locked_mods; rep.group.base_group = state->base_group; rep.group.latched_group = state->latched_group; rep.group.locked_group = state->locked_group; } if (pDev->button) { int i; rep.buttons_len = bytes_to_int32(bits_to_bytes(pDev->button->numButtons)); rep.length += rep.buttons_len; buttons = calloc(rep.buttons_len, 4); if (!buttons) return BadAlloc; buttons_size = rep.buttons_len * 4; for (i = 1; i < pDev->button->numButtons; i++) if (BitIsOn(pDev->button->down, i)) SetBit(buttons, pDev->button->map[i]); if (!have_xi22 && pDev->touch && pDev->touch->buttonsDown > 0) SetBit(buttons, pDev->button->map[1]); } else rep.buttons_len = 0; if (pSprite->hot.pScreen == pWin->drawable.pScreen) { rep.same_screen = xTrue; rep.win_x = double_to_fp1616(pSprite->hot.x - pWin->drawable.x); rep.win_y = double_to_fp1616(pSprite->hot.y - pWin->drawable.y); for (t = pSprite->win; t; t = t->parent) if (t->parent == pWin) { rep.child = t->drawable.id; break; } } else { rep.same_screen = xFalse; rep.win_x = 0; rep.win_y = 0; } #ifdef PANORAMIX if (!noPanoramiXExtension) { rep.root_x += double_to_fp1616(screenInfo.screens[0]->x); rep.root_y += double_to_fp1616(screenInfo.screens[0]->y); if (stuff->win == rep.root) { rep.win_x += double_to_fp1616(screenInfo.screens[0]->x); rep.win_y += double_to_fp1616(screenInfo.screens[0]->y); } } #endif WriteReplyToClient(client, sizeof(xXIQueryPointerReply), &rep); if (buttons) WriteToClient(client, buttons_size, buttons); free(buttons); return Success; } /*********************************************************************** * * This procedure writes the reply for the XIQueryPointer function, * if the client and server have a different byte ordering. * */ void SRepXIQueryPointer(ClientPtr client, int size, xXIQueryPointerReply * rep) { swaps(&rep->sequenceNumber); swapl(&rep->length); swapl(&rep->root); swapl(&rep->child); swapl(&rep->root_x); swapl(&rep->root_y); swapl(&rep->win_x); swapl(&rep->win_y); swaps(&rep->buttons_len); WriteToClient(client, size, rep); }
static int ProcXTestFakeInput(ClientPtr client) { REQUEST(xXTestFakeInputReq); int nev, n, type, rc; xEvent *ev; DeviceIntPtr dev = NULL; WindowPtr root; Bool extension = FALSE; deviceValuator *dv = NULL; int valuators[MAX_VALUATORS] = {0}; int numValuators = 0; int firstValuator = 0; int nevents = 0; int i; int base = 0; int flags = 0; int need_ptr_update = 1; nev = (stuff->length << 2) - sizeof(xReq); if ((nev % sizeof(xEvent)) || !nev) return BadLength; nev /= sizeof(xEvent); UpdateCurrentTime(); ev = (xEvent *)&((xReq *)stuff)[1]; type = ev->u.u.type & 0177; if (type >= EXTENSION_EVENT_BASE) { extension = TRUE; /* check device */ rc = dixLookupDevice(&dev, stuff->deviceid & 0177, client, DixWriteAccess); if (rc != Success) { client->errorValue = stuff->deviceid & 0177; return rc; } /* check type */ type -= DeviceValuator; switch (type) { case XI_DeviceKeyPress: case XI_DeviceKeyRelease: if (!dev->key) { client->errorValue = ev->u.u.type; return BadValue; } break; case XI_DeviceButtonPress: case XI_DeviceButtonRelease: if (!dev->button) { client->errorValue = ev->u.u.type; return BadValue; } break; case XI_DeviceMotionNotify: if (!dev->valuator) { client->errorValue = ev->u.u.type; return BadValue; } break; case XI_ProximityIn: case XI_ProximityOut: if (!dev->proximity) { client->errorValue = ev->u.u.type; return BadValue; } break; default: client->errorValue = ev->u.u.type; return BadValue; } /* check validity */ if (nev == 1 && type == XI_DeviceMotionNotify) return BadLength; /* DevMotion must be followed by DevValuator */ if (type == XI_DeviceMotionNotify) { firstValuator = ((deviceValuator *)(ev+1))->first_valuator; if (firstValuator > dev->valuator->numAxes) { client->errorValue = ev->u.u.type; return BadValue; } if (ev->u.u.detail == xFalse) flags |= POINTER_ABSOLUTE; } else { firstValuator = 0; flags |= POINTER_ABSOLUTE; } if (nev > 1 && !dev->valuator) { client->errorValue = dv->first_valuator; return BadValue; } /* check validity of valuator events */ base = firstValuator; for (n = 1; n < nev; n++) { dv = (deviceValuator *)(ev + n); if (dv->type != DeviceValuator) { client->errorValue = dv->type; return BadValue; } if (dv->first_valuator != base) { client->errorValue = dv->first_valuator; return BadValue; } switch(dv->num_valuators) { case 6: valuators[base + 5] = dv->valuator5; case 5: valuators[base + 4] = dv->valuator4; case 4: valuators[base + 3] = dv->valuator3; case 3: valuators[base + 2] = dv->valuator2; case 2: valuators[base + 1] = dv->valuator1; case 1: valuators[base] = dv->valuator0; break; default: client->errorValue = dv->num_valuators; return BadValue; } base += dv->num_valuators; numValuators += dv->num_valuators; if (firstValuator + numValuators > dev->valuator->numAxes) { client->errorValue = dv->num_valuators; return BadValue; } } type = type - XI_DeviceKeyPress + KeyPress; } else { if (nev != 1) return BadLength; switch (type) { case KeyPress: case KeyRelease: dev = PickKeyboard(client); break; case ButtonPress: case ButtonRelease: dev = PickPointer(client); break; case MotionNotify: dev = PickPointer(client); valuators[0] = ev->u.keyButtonPointer.rootX; valuators[1] = ev->u.keyButtonPointer.rootY; numValuators = 2; firstValuator = 0; if (ev->u.u.detail == xFalse) flags = POINTER_ABSOLUTE | POINTER_SCREEN; break; default: client->errorValue = ev->u.u.type; return BadValue; } dev = GetXTestDevice(dev); } /* If the event has a time set, wait for it to pass */ if (ev->u.keyButtonPointer.time) { TimeStamp activateTime; CARD32 ms; activateTime = currentTime; ms = activateTime.milliseconds + ev->u.keyButtonPointer.time; if (ms < activateTime.milliseconds) activateTime.months++; activateTime.milliseconds = ms; ev->u.keyButtonPointer.time = 0; /* see mbuf.c:QueueDisplayRequest (from the deprecated Multibuffer * extension) for code similar to this */ if (!ClientSleepUntil(client, &activateTime, NULL, NULL)) { return BadAlloc; } /* swap the request back so we can simply re-execute it */ if (client->swapped) { (void) XTestSwapFakeInput(client, (xReq *)stuff); swaps(&stuff->length, n); } ResetCurrentRequest (client); client->sequence--; return Success; } switch (type) { case KeyPress: case KeyRelease: if (!dev->key) return BadDevice; if (ev->u.u.detail < dev->key->xkbInfo->desc->min_key_code || ev->u.u.detail > dev->key->xkbInfo->desc->max_key_code) { client->errorValue = ev->u.u.detail; return BadValue; } need_ptr_update = 0; break; case MotionNotify: if (!dev->valuator) return BadDevice; /* broken lib, XI events have root uninitialized */ if (extension || ev->u.keyButtonPointer.root == None) root = GetCurrentRootWindow(dev); else { rc = dixLookupWindow(&root, ev->u.keyButtonPointer.root, client, DixGetAttrAccess); if (rc != Success) return rc; if (root->parent) { client->errorValue = ev->u.keyButtonPointer.root; return BadValue; } } if (ev->u.u.detail != xTrue && ev->u.u.detail != xFalse) { client->errorValue = ev->u.u.detail; return BadValue; } /* FIXME: Xinerama! */ break; case ButtonPress: case ButtonRelease: if (!dev->button) return BadDevice; if (!ev->u.u.detail || ev->u.u.detail > dev->button->numButtons) { client->errorValue = ev->u.u.detail; return BadValue; } break; } if (screenIsSaved == SCREEN_SAVER_ON) dixSaveScreens(serverClient, SCREEN_SAVER_OFF, ScreenSaverReset); switch(type) { case MotionNotify: nevents = GetPointerEvents(xtest_evlist, dev, type, 0, flags, firstValuator, numValuators, valuators); break; case ButtonPress: case ButtonRelease: nevents = GetPointerEvents(xtest_evlist, dev, type, ev->u.u.detail, flags, firstValuator, numValuators, valuators); break; case KeyPress: case KeyRelease: nevents = GetKeyboardEvents(xtest_evlist, dev, type, ev->u.u.detail); break; } for (i = 0; i < nevents; i++) mieqProcessDeviceEvent(dev, (InternalEvent*)(xtest_evlist+i)->event, NULL); if (need_ptr_update) miPointerUpdateSprite(dev); return Success; }