Git init
[framework/uifw/xorg/lib/libxext.git] / src / Xcup.c
1 /*
2
3 Copyright 1987, 1988, 1998  The Open Group
4
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
24
25 */
26
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30 #ifdef WIN32
31 #include <X11/Xwindows.h>
32 #endif
33
34 #include <X11/Xlibint.h>
35 #include <X11/extensions/Xcup.h>
36 #include <X11/extensions/cupproto.h>
37 #include <X11/extensions/Xext.h>
38 #include <X11/extensions/extutil.h>
39
40 static XExtensionInfo _xcup_info_data;
41 static XExtensionInfo *xcup_info = &_xcup_info_data;
42 static char *xcup_extension_name = XCUPNAME;
43
44 /*****************************************************************************
45  *                                                                           *
46  *                         private utility routines                          *
47  *                                                                           *
48  *****************************************************************************/
49
50 static int close_display(Display *dpy, XExtCodes *codes);
51 static /* const */ XExtensionHooks xcup_extension_hooks = {
52     NULL,                               /* create_gc */
53     NULL,                               /* copy_gc */
54     NULL,                               /* flush_gc */
55     NULL,                               /* free_gc */
56     NULL,                               /* create_font */
57     NULL,                               /* free_font */
58     close_display,                      /* close_display */
59     NULL,                               /* wire_to_event */
60     NULL,                               /* event_to_wire */
61     NULL,                               /* error */
62     NULL,                               /* error_string */
63 };
64
65 static XEXT_GENERATE_FIND_DISPLAY (find_display, xcup_info, 
66                                    xcup_extension_name, 
67                                    &xcup_extension_hooks, 
68                                    0, NULL)
69
70 static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xcup_info)
71
72
73 /*****************************************************************************
74  *                                                                           *
75  *                  public Xcup Extension routines                           *
76  *                                                                           *
77  *****************************************************************************/
78
79 Status
80 XcupQueryVersion(
81     Display* dpy,
82     int* major_version_return,
83     int* minor_version_return)
84 {
85     XExtDisplayInfo *info = find_display (dpy);
86     xXcupQueryVersionReply rep;
87     xXcupQueryVersionReq *req;
88
89     XextCheckExtension (dpy, info, xcup_extension_name, False);
90
91     LockDisplay(dpy);
92     GetReq(XcupQueryVersion, req);
93     req->reqType = info->codes->major_opcode;
94     req->xcupReqType = X_XcupQueryVersion;
95     req->client_major_version = XCUP_MAJOR_VERSION;
96     req->client_minor_version = XCUP_MINOR_VERSION;
97     if (!_XReply(dpy, (xReply *)&rep, 0, xTrue)) {
98         UnlockDisplay(dpy);
99         SyncHandle();
100         return False;
101     }
102     *major_version_return = rep.server_major_version;
103     *minor_version_return = rep.server_minor_version;
104     UnlockDisplay(dpy);
105     SyncHandle();
106     return True;
107 }
108
109 /* Win32 reserves 20 colormap entries for its desktop */
110 #ifndef TYP_RESERVED_ENTRIES
111 #define TYP_RESERVED_ENTRIES 20
112 #endif
113
114 Status 
115 XcupGetReservedColormapEntries(
116     Display* dpy,
117     int screen,
118     XColor** colors_out,
119     int* ncolors)
120 {
121     XExtDisplayInfo *info = find_display (dpy);
122     xXcupGetReservedColormapEntriesReply rep;
123     xXcupGetReservedColormapEntriesReq *req;
124     xColorItem rbuf[TYP_RESERVED_ENTRIES];
125
126     *ncolors = 0;
127
128     XextCheckExtension (dpy, info, xcup_extension_name, False);
129
130     LockDisplay(dpy);
131     GetReq(XcupGetReservedColormapEntries, req);
132     req->reqType = info->codes->major_opcode;
133     req->xcupReqType = X_XcupGetReservedColormapEntries;
134     req->screen = screen;
135     if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
136         long nbytes;
137         xColorItem* rbufp;
138         int nentries = rep.length / 3;
139
140         nbytes = nentries * SIZEOF (xColorItem);
141         if (nentries > TYP_RESERVED_ENTRIES)
142             rbufp = (xColorItem*) Xmalloc (nbytes);
143         else
144             rbufp = rbuf;
145
146         if (rbufp == NULL) {
147             _XEatData (dpy, (unsigned long) nbytes);
148             UnlockDisplay (dpy);
149             SyncHandle ();
150             return False;
151         }
152         _XRead (dpy, (char*) rbufp, nbytes);
153
154         *colors_out = (XColor*) Xmalloc (nentries  * sizeof (XColor));
155         if (*colors_out) {
156             xColorItem* cs = (xColorItem *) rbufp;
157             XColor* cd = *colors_out;
158             int i;
159
160             *ncolors = nentries;
161             for (i = 0; i < *ncolors; i++, cd++) {
162                 cd->pixel = cs->pixel;
163                 cd->red = cs->red;
164                 cd->green = cs->green;
165                 cd->blue = cs->blue;
166                 cs = (xColorItem*) (((char*) cs) + SIZEOF(xColorItem));
167             }
168             if (rbufp != rbuf) XFree ((char*) rbufp);
169             UnlockDisplay(dpy);
170             SyncHandle();
171             return True;
172         }
173         if (rbufp != rbuf) XFree ((char*) rbufp);
174     }
175     UnlockDisplay(dpy);
176     SyncHandle();
177     return False;
178 }
179
180 Status
181 XcupStoreColors(
182     Display* dpy,
183     Colormap colormap,
184     XColor* colors_in_out,
185     int ncolors)
186 {
187     XExtDisplayInfo *info = find_display (dpy);
188     xXcupStoreColorsReply rep;
189     xXcupStoreColorsReq *req;
190     xColorItem rbuf[256];
191     xColorItem citem;
192     int i;
193     XColor* xcp;
194
195     XextCheckExtension (dpy, info, xcup_extension_name, False);
196
197     LockDisplay(dpy);
198     GetReq(XcupStoreColors, req);
199     req->reqType = info->codes->major_opcode;
200     req->xcupReqType = X_XcupStoreColors;
201     req->cmap = colormap;
202     req->length += (ncolors * SIZEOF(xColorItem)) >> 2;
203
204     for (i = 0, xcp = colors_in_out; i < ncolors; i++, xcp++) {
205         citem.pixel = xcp->pixel;
206         citem.red = xcp->red;
207         citem.green = xcp->green;
208         citem.blue = xcp->blue;
209
210         /* note that xColorItem doesn't contain all 16-bit quantities, so
211            we can't use Data16 */
212         Data(dpy, (char *)&citem, (long) SIZEOF(xColorItem));
213     }
214
215     if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
216         long nbytes;
217         xColorItem* rbufp;
218         xColorItem* cs;
219         int nentries = rep.length / 3;
220
221         nbytes = nentries * SIZEOF (xColorItem);
222
223         if (nentries != ncolors) {
224             _XEatData (dpy, (unsigned long) nbytes);
225             UnlockDisplay (dpy);
226             SyncHandle ();
227             return False;
228         }
229
230         if (ncolors > 256)
231             rbufp = (xColorItem*) Xmalloc (nbytes);
232         else
233             rbufp = rbuf;
234
235         if (rbufp == NULL) {
236             _XEatData (dpy, (unsigned long) nbytes);
237             UnlockDisplay (dpy);
238             SyncHandle ();
239             return False;
240
241         }
242
243         _XRead (dpy, (char*) rbufp, nbytes);
244
245         for (i = 0, xcp = colors_in_out, cs = rbufp; i < ncolors; i++, xcp++, cs++) {
246             xcp->pixel = cs->pixel;
247             xcp->red = cs->red;
248             xcp->green = cs->green;
249             xcp->blue = cs->blue;
250             xcp->flags = cs->flags;
251         }
252         if (rbufp != rbuf) XFree ((char*)rbufp);
253
254         UnlockDisplay(dpy);
255         SyncHandle();
256         return True;
257     }
258     UnlockDisplay(dpy);
259     SyncHandle();
260     return False;
261 }
262