int ProcConvertSelection(ClientPtr client) { Bool paramsOkay; xEvent event; WindowPtr pWin; Selection *pSel; int rc; REQUEST(xConvertSelectionReq); REQUEST_SIZE_MATCH(xConvertSelectionReq); rc = dixLookupWindow(&pWin, stuff->requestor, client, DixSetAttrAccess); if (rc != Success) return rc; paramsOkay = ValidAtom(stuff->selection) && ValidAtom(stuff->target); paramsOkay &= (stuff->property == None) || ValidAtom(stuff->property); if (!paramsOkay) { client->errorValue = stuff->property; return BadAtom; } rc = dixLookupSelection(&pSel, stuff->selection, client, DixReadAccess); memset(&event, 0, sizeof(xEvent)); if (rc != Success && rc != BadMatch) return rc; else if (rc == Success && pSel->window != None) { event.u.u.type = SelectionRequest; event.u.selectionRequest.owner = pSel->window; event.u.selectionRequest.time = stuff->time; event.u.selectionRequest.requestor = stuff->requestor; event.u.selectionRequest.selection = stuff->selection; event.u.selectionRequest.target = stuff->target; event.u.selectionRequest.property = stuff->property; if (TryClientEvents(pSel->client, NULL, &event, 1, NoEventMask, NoEventMask /* CantBeFiltered */, NullGrab)) return client->noClientException; } event.u.u.type = SelectionNotify; event.u.selectionNotify.time = stuff->time; event.u.selectionNotify.requestor = stuff->requestor; event.u.selectionNotify.selection = stuff->selection; event.u.selectionNotify.target = stuff->target; event.u.selectionNotify.property = None; TryClientEvents(client, NULL, &event, 1, NoEventMask, NoEventMask /* CantBeFiltered */, NullGrab); return client->noClientException; }
void rfbSetXCutText(char *str, int len) { int i = 0; inSetXCutText = TRUE; ChangeWindowProperty(WindowTable[0], XA_CUT_BUFFER0, XA_STRING, 8, PropModeReplace, len, (pointer)str, TRUE); while ((i < NumCurrentSelections) && CurrentSelections[i].selection != XA_PRIMARY) i++; if (i < NumCurrentSelections) { xEvent event; if (CurrentSelections[i].client) { event.u.u.type = SelectionClear; event.u.selectionClear.time = GetTimeInMillis(); event.u.selectionClear.window = CurrentSelections[i].window; event.u.selectionClear.atom = CurrentSelections[i].selection; (void) TryClientEvents (CurrentSelections[i].client, &event, 1, NoEventMask, NoEventMask /* CantBeFiltered */, NullGrab); } CurrentSelections[i].window = None; CurrentSelections[i].pWin = NULL; CurrentSelections[i].client = NullClient; } inSetXCutText = FALSE; }
int XvdiSendPortNotify( XvPortPtr pPort, Atom attribute, INT32 value ){ xvEvent event; XvPortNotifyPtr pn; pn = pPort->pNotify; while (pn) { if (pn->client) { event.u.u.type = XvEventBase + XvPortNotify; event.u.u.sequenceNumber = pn->client->sequence; event.u.portNotify.time = currentTime.milliseconds; event.u.portNotify.port = pPort->id; event.u.portNotify.attribute = attribute; event.u.portNotify.value = value; TryClientEvents(pn->client, NULL, (xEventPtr)&event, 1, NoEventMask, NoEventMask, NullGrab); } pn = pn->next; } return Success; }
static int XvdiSendVideoNotify(XvPortPtr pPort, DrawablePtr pDraw, int reason) { xvEvent event; XvVideoNotifyPtr pn; dixLookupResourceByType((pointer *)&pn, pDraw->id, XvRTVideoNotifyList, serverClient, DixReadAccess); while (pn) { if (pn->client) { event.u.u.type = XvEventBase + XvVideoNotify; event.u.u.sequenceNumber = pn->client->sequence; event.u.videoNotify.time = currentTime.milliseconds; event.u.videoNotify.drawable = pDraw->id; event.u.videoNotify.port = pPort->id; event.u.videoNotify.reason = reason; TryClientEvents(pn->client, NULL, (xEventPtr)&event, 1, NoEventMask, NoEventMask, NullGrab); } pn = pn->next; } return Success; }
// Read Mac OS X pasteboard into X cut buffer // Called by ProcessInputEvents() in response to request from X server thread. void QuartzReadPasteboard(void) { char *oldText = QuartzReadCutBuffer(); char *text = QuartzReadCocoaPasteboard(); // Compare text with current cut buffer contents. // Change the buffer if both exist and are different // OR if there is new text but no old text. // Otherwise, don't clear the selection unnecessarily. if ((text && oldText && !strequal(text, oldText)) || (text && !oldText)) { int scrn, sel; for (scrn = 0; scrn < screenInfo.numScreens; scrn++) { ScreenPtr pScreen = screenInfo.screens[scrn]; // Set the cut buffers on each screen // fixme really on each screen? ChangeWindowProperty(WindowTable[pScreen->myNum], XA_CUT_BUFFER0, XA_STRING, 8, PropModeReplace, strlen(text), (pointer)text, TRUE); } // Undo any current X selection (similar to code in dispatch.c) // FIXME: what about secondary selection? // FIXME: only touch first XA_PRIMARY selection? sel = 0; while ((sel < NumCurrentSelections) && CurrentSelections[sel].selection != XA_PRIMARY) sel++; if (sel < NumCurrentSelections) { // Notify client if necessary if (CurrentSelections[sel].client) { xEvent event; event.u.u.type = SelectionClear; event.u.selectionClear.time = GetTimeInMillis(); event.u.selectionClear.window = CurrentSelections[sel].window; event.u.selectionClear.atom = CurrentSelections[sel].selection; TryClientEvents(CurrentSelections[sel].client, &event, 1, NoEventMask, NoEventMask /*CantBeFiltered*/, NullGrab); } // Erase it // FIXME: need to erase .selection too? dispatch.c doesn't CurrentSelections[sel].pWin = NullWindow; CurrentSelections[sel].window = None; CurrentSelections[sel].client = NullClient; } } if (text) free(text); if (oldText) free(oldText); }
void miSendGraphicsExpose(ClientPtr client, RegionPtr pRgn, XID drawable, int major, int minor) { if (pRgn && !RegionNil(pRgn)) { xEvent *pEvent; xEvent *pe; BoxPtr pBox; int i; int numRects; numRects = RegionNumRects(pRgn); pBox = RegionRects(pRgn); if (!(pEvent = calloc(numRects, sizeof(xEvent)))) return; pe = pEvent; for (i = 1; i <= numRects; i++, pe++, pBox++) { pe->u.u.type = GraphicsExpose; pe->u.graphicsExposure.drawable = drawable; pe->u.graphicsExposure.x = pBox->x1; pe->u.graphicsExposure.y = pBox->y1; pe->u.graphicsExposure.width = pBox->x2 - pBox->x1; pe->u.graphicsExposure.height = pBox->y2 - pBox->y1; pe->u.graphicsExposure.count = numRects - i; pe->u.graphicsExposure.majorEvent = major; pe->u.graphicsExposure.minorEvent = minor; } /* GraphicsExpose is a "critical event", which TryClientEvents * handles specially. */ TryClientEvents(client, NULL, pEvent, numRects, (Mask) 0, NoEventMask, NullGrab); free(pEvent); } else { xEvent event = { .u.noExposure.drawable = drawable, .u.noExposure.majorEvent = major, .u.noExposure.minorEvent = minor }; event.u.u.type = NoExpose; WriteEventsToClient(client, 1, &event); } } void miSendExposures(WindowPtr pWin, RegionPtr pRgn, int dx, int dy) { BoxPtr pBox; int numRects; xEvent *pEvent, *pe; int i; pBox = RegionRects(pRgn); numRects = RegionNumRects(pRgn); if (!(pEvent = calloc(1, numRects * sizeof(xEvent)))) return; for (i = numRects, pe = pEvent; --i >= 0; pe++, pBox++) { pe->u.u.type = Expose; pe->u.expose.window = pWin->drawable.id; pe->u.expose.x = pBox->x1 - dx; pe->u.expose.y = pBox->y1 - dy; pe->u.expose.width = pBox->x2 - pBox->x1; pe->u.expose.height = pBox->y2 - pBox->y1; pe->u.expose.count = i; } #ifdef PANORAMIX if (!noPanoramiXExtension) { int scrnum = pWin->drawable.pScreen->myNum; int x = 0, y = 0; XID realWin = 0; if (!pWin->parent) { x = screenInfo.screens[scrnum]->x; y = screenInfo.screens[scrnum]->y; pWin = screenInfo.screens[0]->root; realWin = pWin->drawable.id; } else if (scrnum) { PanoramiXRes *win; win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, scrnum); if (!win) { free(pEvent); return; } realWin = win->info[0].id; dixLookupWindow(&pWin, realWin, serverClient, DixSendAccess); } if (x || y || scrnum) for (i = 0; i < numRects; i++) { pEvent[i].u.expose.window = realWin; pEvent[i].u.expose.x += x; pEvent[i].u.expose.y += y; } } #endif DeliverEvents(pWin, pEvent, numRects, NullWindow); free(pEvent); }
int ProcSetSelectionOwner(ClientPtr client) { WindowPtr pWin = NULL; TimeStamp time; Selection *pSel; int rc; REQUEST(xSetSelectionOwnerReq); REQUEST_SIZE_MATCH(xSetSelectionOwnerReq); UpdateCurrentTime(); time = ClientTimeToServerTime(stuff->time); /* If the client's time stamp is in the future relative to the server's time stamp, do not set the selection, just return success. */ if (CompareTimeStamps(time, currentTime) == LATER) return Success; if (stuff->window != None) { rc = dixLookupWindow(&pWin, stuff->window, client, DixSetAttrAccess); if (rc != Success) return rc; } if (!ValidAtom(stuff->selection)) { client->errorValue = stuff->selection; return BadAtom; } /* * First, see if the selection is already set... */ rc = dixLookupSelection(&pSel, stuff->selection, client, DixSetAttrAccess); if (rc == Success) { xEvent event; /* If the timestamp in client's request is in the past relative to the time stamp indicating the last time the owner of the selection was set, do not set the selection, just return success. */ if (CompareTimeStamps(time, pSel->lastTimeChanged) == EARLIER) return Success; if (pSel->client && (!pWin || (pSel->client != client))) { event.u.u.type = SelectionClear; event.u.selectionClear.time = time.milliseconds; event.u.selectionClear.window = pSel->window; event.u.selectionClear.atom = pSel->selection; TryClientEvents(pSel->client, NULL, &event, 1, NoEventMask, NoEventMask /* CantBeFiltered */, NullGrab); } } else if (rc == BadMatch) { /* * It doesn't exist, so add it... */ pSel = xalloc(sizeof(Selection)); if (!pSel) return BadAlloc; pSel->selection = stuff->selection; pSel->devPrivates = NULL; /* security creation/labeling check */ rc = XaceHookSelectionAccess(client, &pSel, DixCreateAccess|DixSetAttrAccess); if (rc != Success) { xfree(pSel); return rc; } pSel->next = CurrentSelections; CurrentSelections = pSel; } else return rc; pSel->lastTimeChanged = time; pSel->window = stuff->window; pSel->pWin = pWin; pSel->client = (pWin ? client : NullClient); CallSelectionCallback(pSel, client, SelectionSetOwner); return client->noClientException; }