Initial commit
[xorg_rtime.git] / xorg-server-1.4 / hw / darwin / quartz / quartzPasteboard.c
bloba3536fc561ca7082eb34e7b4033e152878de18af
1 /**************************************************************
2 * quartzPasteboard.c
4 * Aqua pasteboard <-> X cut buffer
5 * Greg Parker gparker@cs.stanford.edu March 8, 2001
6 **************************************************************/
7 /*
8 * Copyright (c) 2001 Greg Parker. All Rights Reserved.
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
28 * Except as contained in this notice, the name(s) of the above copyright
29 * holders shall not be used in advertising or otherwise to promote the sale,
30 * use or other dealings in this Software without prior written authorization.
33 #ifdef HAVE_XORG_CONFIG_H
34 #include <xorg-config.h>
35 #endif
36 #include "quartzPasteboard.h"
38 #include <X11/Xatom.h>
39 #include "windowstr.h"
40 #include "propertyst.h"
41 #include "scrnintstr.h"
42 #include "selection.h"
43 #include "globals.h"
45 extern Selection *CurrentSelections;
46 extern int NumCurrentSelections;
49 // Helper function to read the X11 cut buffer
50 // FIXME: What about multiple screens? Currently, this reads the first
51 // CUT_BUFFER0 from the first screen where the buffer content is a string.
52 // Returns a string on the heap that the caller must free.
53 // Returns NULL if there is no cut text or there is not enough memory.
54 static char * QuartzReadCutBuffer(void)
56 int i;
57 char *text = NULL;
59 for (i = 0; i < screenInfo.numScreens; i++) {
60 ScreenPtr pScreen = screenInfo.screens[i];
61 PropertyPtr pProp;
63 pProp = wUserProps (WindowTable[pScreen->myNum]);
64 while (pProp && pProp->propertyName != XA_CUT_BUFFER0) {
65 pProp = pProp->next;
67 if (! pProp) continue;
68 if (pProp->type != XA_STRING) continue;
69 if (pProp->format != 8) continue;
71 text = xalloc(1 + pProp->size);
72 if (! text) continue;
73 memcpy(text, pProp->data, pProp->size);
74 text[pProp->size] = '\0';
75 return text;
78 // didn't find any text
79 return NULL;
82 // Write X cut buffer to Mac OS X pasteboard
83 // Called by ProcessInputEvents() in response to request from X server thread.
84 void QuartzWritePasteboard(void)
86 char *text;
87 text = QuartzReadCutBuffer();
88 if (text) {
89 QuartzWriteCocoaPasteboard(text);
90 free(text);
94 #define strequal(a, b) (0 == strcmp((a), (b)))
96 // Read Mac OS X pasteboard into X cut buffer
97 // Called by ProcessInputEvents() in response to request from X server thread.
98 void QuartzReadPasteboard(void)
100 char *oldText = QuartzReadCutBuffer();
101 char *text = QuartzReadCocoaPasteboard();
103 // Compare text with current cut buffer contents.
104 // Change the buffer if both exist and are different
105 // OR if there is new text but no old text.
106 // Otherwise, don't clear the selection unnecessarily.
108 if ((text && oldText && !strequal(text, oldText)) ||
109 (text && !oldText)) {
110 int scrn, sel;
112 for (scrn = 0; scrn < screenInfo.numScreens; scrn++) {
113 ScreenPtr pScreen = screenInfo.screens[scrn];
114 // Set the cut buffers on each screen
115 // fixme really on each screen?
116 ChangeWindowProperty(WindowTable[pScreen->myNum], XA_CUT_BUFFER0,
117 XA_STRING, 8, PropModeReplace,
118 strlen(text), (pointer)text, TRUE);
121 // Undo any current X selection (similar to code in dispatch.c)
122 // FIXME: what about secondary selection?
123 // FIXME: only touch first XA_PRIMARY selection?
124 sel = 0;
125 while ((sel < NumCurrentSelections) &&
126 CurrentSelections[sel].selection != XA_PRIMARY)
127 sel++;
128 if (sel < NumCurrentSelections) {
129 // Notify client if necessary
130 if (CurrentSelections[sel].client) {
131 xEvent event;
133 event.u.u.type = SelectionClear;
134 event.u.selectionClear.time = GetTimeInMillis();
135 event.u.selectionClear.window = CurrentSelections[sel].window;
136 event.u.selectionClear.atom = CurrentSelections[sel].selection;
137 TryClientEvents(CurrentSelections[sel].client, &event, 1,
138 NoEventMask, NoEventMask /*CantBeFiltered*/,
139 NullGrab);
142 // Erase it
143 // FIXME: need to erase .selection too? dispatch.c doesn't
144 CurrentSelections[sel].pWin = NullWindow;
145 CurrentSelections[sel].window = None;
146 CurrentSelections[sel].client = NullClient;
150 if (text) free(text);
151 if (oldText) free(oldText);