XRes.c revision bcbfc08f
1/*
2   Copyright (c) 2002  XFree86 Inc
3*/
4
5#ifdef HAVE_CONFIG_H
6#include <config.h>
7#endif
8#include <stdlib.h>
9#include <X11/Xlibint.h>
10#include <X11/Xutil.h>
11#include <X11/extensions/Xext.h>
12#include <X11/extensions/extutil.h>
13#include <X11/extensions/XResproto.h>
14#include <X11/extensions/XRes.h>
15#include <limits.h>
16
17#ifndef HAVE__XEATDATAWORDS
18static inline void _XEatDataWords(Display *dpy, unsigned long n)
19{
20# ifndef LONG64
21    if (n >= (ULONG_MAX >> 2))
22        _XIOError(dpy);
23# endif
24    _XEatData (dpy, n << 2);
25}
26#endif
27
28static XExtensionInfo _xres_ext_info_data;
29static XExtensionInfo *xres_ext_info = &_xres_ext_info_data;
30static char *xres_extension_name = XRES_NAME;
31
32#define XResCheckExtension(dpy,i,val) \
33  XextCheckExtension (dpy, i, xres_extension_name, val)
34
35static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xres_ext_info)
36
37static XExtensionHooks xres_extension_hooks = {
38    NULL,                               /* create_gc */
39    NULL,                               /* copy_gc */
40    NULL,                               /* flush_gc */
41    NULL,                               /* free_gc */
42    NULL,                               /* create_font */
43    NULL,                               /* free_font */
44    close_display,                      /* close_display */
45    NULL,                               /* wire_to_event */
46    NULL,                               /* event_to_wire */
47    NULL,                               /* error */
48    NULL,                               /* error_string */
49};
50
51static XEXT_GENERATE_FIND_DISPLAY (find_display, xres_ext_info,
52                                   xres_extension_name,
53                                   &xres_extension_hooks,
54                                   0, NULL)
55
56Bool XResQueryExtension (
57    Display *dpy,
58    int *event_base_return,
59    int *error_base_return
60)
61{
62    XExtDisplayInfo *info = find_display (dpy);
63
64    if (XextHasExtension(info)) {
65        *event_base_return = info->codes->first_event;
66        *error_base_return = info->codes->first_error;
67        return True;
68    } else {
69        return False;
70    }
71}
72
73Status XResQueryVersion(
74    Display *dpy,
75    int *major_version_return,
76    int *minor_version_return
77)
78{
79    XExtDisplayInfo *info = find_display (dpy);
80    xXResQueryVersionReply rep;
81    xXResQueryVersionReq *req;
82
83    XResCheckExtension (dpy, info, 0);
84
85    LockDisplay (dpy);
86    GetReq (XResQueryVersion, req);
87    req->reqType = info->codes->major_opcode;
88    req->XResReqType = X_XResQueryVersion;
89    req->client_major = XRES_MAJOR_VERSION;
90    req->client_minor = XRES_MINOR_VERSION;
91    if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
92        UnlockDisplay (dpy);
93        SyncHandle ();
94        return 0;
95    }
96    *major_version_return = rep.server_major;
97    *minor_version_return = rep.server_minor;
98    UnlockDisplay (dpy);
99    SyncHandle ();
100    return 1;
101}
102
103
104Status XResQueryClients (
105    Display *dpy,
106    int *num_clients,
107    XResClient **clients
108)
109{
110    XExtDisplayInfo *info = find_display (dpy);
111    xXResQueryClientsReq *req;
112    xXResQueryClientsReply rep;
113    XResClient *clnts;
114    int result = 0;
115
116    *num_clients = 0;
117    *clients = NULL;
118
119    XResCheckExtension (dpy, info, 0);
120
121    LockDisplay (dpy);
122    GetReq (XResQueryClients, req);
123    req->reqType = info->codes->major_opcode;
124    req->XResReqType = X_XResQueryClients;
125    if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
126        UnlockDisplay (dpy);
127        SyncHandle ();
128        return 0;
129    }
130
131    if(rep.num_clients) {
132        if (rep.num_clients < (INT_MAX / sizeof(XResClient)))
133            clnts = Xmalloc(sizeof(XResClient) * rep.num_clients);
134        else
135            clnts = NULL;
136
137        if (clnts != NULL) {
138            xXResClient scratch;
139            int i;
140
141            for(i = 0; i < rep.num_clients; i++) {
142                _XRead(dpy, (char*)&scratch, sz_xXResClient);
143                clnts[i].resource_base = scratch.resource_base;
144                clnts[i].resource_mask = scratch.resource_mask;
145            }
146            *clients = clnts;
147            *num_clients = rep.num_clients;
148            result = 1;
149        } else {
150            _XEatDataWords(dpy, rep.length);
151        }
152    }
153
154    UnlockDisplay (dpy);
155    SyncHandle ();
156    return result;
157}
158
159Status XResQueryClientResources (
160    Display *dpy,
161    XID xid,
162    int *num_types,
163    XResType **types
164)
165{
166    XExtDisplayInfo *info = find_display (dpy);
167    xXResQueryClientResourcesReq *req;
168    xXResQueryClientResourcesReply rep;
169    XResType *typs;
170    int result = 0;
171
172    *num_types = 0;
173    *types = NULL;
174
175    XResCheckExtension (dpy, info, 0);
176
177    LockDisplay (dpy);
178    GetReq (XResQueryClientResources, req);
179    req->reqType = info->codes->major_opcode;
180    req->XResReqType = X_XResQueryClientResources;
181    req->xid = xid;
182    if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
183        UnlockDisplay (dpy);
184        SyncHandle ();
185        return 0;
186    }
187
188    if(rep.num_types) {
189        if (rep.num_types < (INT_MAX / sizeof(XResType)))
190            typs = Xmalloc(sizeof(XResType) * rep.num_types);
191        else
192            typs = NULL;
193
194        if (typs != NULL) {
195            xXResType scratch;
196            int i;
197
198            for(i = 0; i < rep.num_types; i++) {
199                _XRead(dpy, (char*)&scratch, sz_xXResType);
200                typs[i].resource_type = scratch.resource_type;
201                typs[i].count = scratch.count;
202            }
203            *types = typs;
204            *num_types = rep.num_types;
205            result = 1;
206        } else {
207            _XEatDataWords(dpy, rep.length);
208        }
209    }
210
211    UnlockDisplay (dpy);
212    SyncHandle ();
213    return result;
214}
215
216Status XResQueryClientPixmapBytes (
217    Display *dpy,
218    XID xid,
219    unsigned long *bytes
220)
221{
222    XExtDisplayInfo *info = find_display (dpy);
223    xXResQueryClientPixmapBytesReq *req;
224    xXResQueryClientPixmapBytesReply rep;
225
226    *bytes = 0;
227
228    XResCheckExtension (dpy, info, 0);
229
230    LockDisplay (dpy);
231    GetReq (XResQueryClientPixmapBytes, req);
232    req->reqType = info->codes->major_opcode;
233    req->XResReqType = X_XResQueryClientPixmapBytes;
234    req->xid = xid;
235    if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
236        UnlockDisplay (dpy);
237        SyncHandle ();
238        return 0;
239    }
240
241#ifdef LONG64
242    *bytes = (rep.bytes_overflow * 4294967295) + rep.bytes;
243#else
244    *bytes = rep.bytes_overflow ? 0xffffffff : rep.bytes;
245#endif
246
247    UnlockDisplay (dpy);
248    SyncHandle ();
249    return 1;
250}
251
252