e14743d1 |
1 | /* |
2 | * Copyright 1993-2001 by Xi Graphics, Inc. |
3 | * All Rights Reserved. |
4 | * |
5 | * Please see the LICENSE file accompanying this distribution for licensing |
6 | * information. |
7 | * |
8 | * Please send any bug fixes and modifications to src@xig.com. |
9 | * |
10 | * $XiGId: xme.c,v 1.2 2001/11/30 21:56:59 jon Exp $ |
11 | * |
12 | */ |
13 | |
14 | #define NEED_EVENTS |
15 | #define NEED_REPLIES |
16 | |
17 | /* Apparently some X11 systems can't include this multiple times... */ |
18 | #ifndef SDL_INCLUDED_XLIBINT_H |
19 | #define SDL_INCLUDED_XLIBINT_H 1 |
20 | #include <X11/Xlibint.h> |
21 | #endif |
22 | |
23 | #include <X11/Xthreads.h> |
24 | #include <X11/Xmd.h> |
25 | #include <X11/Xproto.h> |
26 | #include "../extensions/Xext.h" |
27 | #include "../extensions/extutil.h" |
28 | |
29 | /*****************************************************************************/ |
30 | |
31 | |
32 | #define XIGMISC_PROTOCOL_NAME "XiG-SUNDRY-NONSTANDARD" |
33 | #define XIGMISC_MAJOR_VERSION 2 |
34 | #define XIGMISC_MINOR_VERSION 0 |
35 | |
36 | #define XiGMiscNumberEvents 0 |
37 | |
38 | #define X_XiGMiscQueryVersion 0 |
39 | #define X_XiGMiscQueryViews 1 |
40 | #define X_XiGMiscQueryResolutions 2 |
41 | #define X_XiGMiscChangeResolution 3 |
42 | #define X_XiGMiscFullScreen 4 |
43 | |
44 | #define sz_xXiGMiscQueryVersionReq 8 |
45 | #define sz_xXiGMiscQueryViewsReq 8 |
46 | #define sz_xXiGMiscQueryResolutionsReq 8 |
47 | #define sz_xXiGMiscChangeResolutionReq 16 |
48 | #define sz_xXiGMiscFullScreenReq 16 |
49 | |
50 | #define sz_xXiGMiscQueryVersionReply 32 |
51 | #define sz_xXiGMiscQueryViewsReply 32 |
52 | #define sz_xXiGMiscQueryResolutionsReply 32 |
53 | #define sz_xXiGMiscQueryFullScreenReply 32 |
54 | |
55 | /*******************************************************************/ |
56 | |
57 | typedef struct { |
58 | CARD8 reqType; /* always codes->major_opcode */ |
59 | CARD8 xigmiscReqType; /* always X_XiGMiscQueryVersion */ |
60 | CARD16 length; |
61 | CARD16 major; |
62 | CARD16 minor; |
63 | } xXiGMiscQueryVersionReq; |
64 | |
65 | typedef struct { |
66 | CARD8 reqType; /* always codes->major_opcode */ |
67 | CARD8 xigmiscReqType; /* always X_XiGMiscQueryViews */ |
68 | CARD16 length; |
69 | CARD8 screen; |
70 | CARD8 pad0; |
71 | CARD16 pad1; |
72 | } xXiGMiscQueryViewsReq; |
73 | |
74 | typedef struct { |
75 | CARD8 reqType; /* always codes->major_opcode */ |
76 | CARD8 xigmiscReqType; /* always X_XiGMiscQueryResolutions */ |
77 | CARD16 length; |
78 | CARD8 screen; |
79 | CARD8 view; |
80 | CARD16 pad0; |
81 | } xXiGMiscQueryResolutionsReq; |
82 | |
83 | typedef struct { |
84 | CARD8 reqType; /* always codes->major_opcode */ |
85 | CARD8 xigmiscReqType; /* always X_XiGMiscChangeResolution */ |
86 | CARD16 length; |
87 | CARD8 screen; |
88 | CARD8 view; |
89 | CARD16 pad0; |
90 | CARD16 width; |
91 | CARD16 height; |
92 | INT32 refresh; |
93 | } xXiGMiscChangeResolutionReq; |
94 | |
95 | typedef struct { |
96 | CARD8 reqType; /* always codes->major_opcode */ |
97 | CARD8 xigmiscReqType; /* always X_XiGMiscFullScreen */ |
98 | CARD16 length; |
99 | CARD8 screen; |
100 | CARD8 pad0; |
101 | CARD16 pad1; |
102 | CARD32 window; |
103 | CARD32 cmap; |
104 | } xXiGMiscFullScreenReq; |
105 | |
106 | /*******************************************************************/ |
107 | |
108 | typedef struct { |
109 | BYTE type; /* X_Reply */ |
110 | CARD8 pad0; |
111 | CARD16 sequenceNumber; |
112 | CARD32 length; |
113 | CARD16 major; |
114 | CARD16 minor; |
115 | CARD32 pad1; |
116 | CARD32 pad2; |
117 | CARD32 pad3; |
118 | CARD32 pad4; |
119 | CARD32 pad5; |
120 | } xXiGMiscQueryVersionReply; |
121 | |
122 | typedef struct { |
123 | BYTE type; /* X_Reply */ |
124 | CARD8 pad0; |
125 | CARD16 sequenceNumber; |
126 | CARD32 length; |
127 | CARD32 nviews; |
128 | CARD32 pad1; |
129 | CARD32 pad2; |
130 | CARD32 pad3; |
131 | CARD32 pad4; |
132 | CARD32 pad5; |
133 | } xXiGMiscQueryViewsReply; |
134 | |
135 | typedef struct { |
136 | BYTE type; /* X_Reply */ |
137 | CARD8 pad0; |
138 | CARD16 sequenceNumber; |
139 | CARD32 length; |
140 | CARD16 active; |
141 | CARD16 nresolutions; |
142 | CARD32 pad1; |
143 | CARD32 pad2; |
144 | CARD32 pad3; |
145 | CARD32 pad4; |
146 | CARD32 pad5; |
147 | } xXiGMiscQueryResolutionsReply; |
148 | |
149 | typedef struct { |
150 | BYTE type; /* X_Reply */ |
151 | BOOL success; |
152 | CARD16 sequenceNumber; |
153 | CARD32 length; |
154 | CARD32 pad1; |
155 | CARD32 pad2; |
156 | CARD32 pad3; |
157 | CARD32 pad4; |
158 | CARD32 pad5; |
159 | CARD32 pad6; |
160 | } xXiGMiscFullScreenReply; |
161 | |
162 | /*******************************************************************/ |
163 | |
164 | typedef struct { |
165 | INT16 x; |
166 | INT16 y; |
167 | CARD16 w; |
168 | CARD16 h; |
169 | } XiGMiscViewInfo; |
170 | |
171 | typedef struct { |
172 | CARD16 width; |
173 | CARD16 height; |
174 | INT32 refresh; |
175 | } XiGMiscResolutionInfo; |
176 | |
177 | /*****************************************************************************/ |
178 | |
179 | static XExtensionInfo *xigmisc_info = NULL; |
180 | static char *xigmisc_extension_name = XIGMISC_PROTOCOL_NAME; |
181 | |
182 | #define XiGMiscCheckExtension(dpy,i,val) \ |
183 | XextCheckExtension (dpy, i, xigmisc_extension_name, val) |
184 | #define XiGMiscSimpleCheckExtension(dpy,i) \ |
185 | XextSimpleCheckExtension (dpy, i, xigmisc_extension_name) |
186 | |
187 | #if defined(__STDC__) && !defined(UNIXCPP) |
188 | #define XiGMiscGetReq(name,req,info) GetReq (name, req); \ |
189 | req->reqType = info->codes->major_opcode; \ |
190 | req->xigmiscReqType = X_##name; |
191 | |
192 | #define XiGMiscGetReqExtra(name,n,req,info) GetReqExtra (name, n, req); \ |
193 | req->reqType = info->codes->major_opcode; \ |
194 | req->xigmicReqType = X_##name; |
195 | #else |
196 | #define XiGMiscGetReq(name,req,info) GetReq (name, req); \ |
197 | req->reqType = info->codes->major_opcode; \ |
198 | req->xigmiscReqType = X_/**/name; |
199 | #define XiGMiscGetReqExtra(name,n,req,info) GetReqExtra (name, n, req); \ |
200 | req->reqType = info->codes->major_opcode; \ |
201 | req->xigmiscReqType = X_/**/name; |
202 | #endif |
203 | |
204 | |
205 | |
206 | /* |
207 | * find_display - locate the display info block |
208 | */ |
209 | static int XiGMiscCloseDisplay(); |
210 | |
211 | static XExtensionHooks xigmisc_extension_hooks = { |
212 | NULL, /* create_gc */ |
213 | NULL, /* copy_gc */ |
214 | NULL, /* flush_gc */ |
215 | NULL, /* free_gc */ |
216 | NULL, /* create_font */ |
217 | NULL, /* free_font */ |
218 | XiGMiscCloseDisplay, /* close_display */ |
219 | NULL, /* wire_to_event */ |
220 | NULL, /* event_to_wire */ |
221 | NULL, /* error */ |
222 | NULL, /* error_string */ |
223 | }; |
224 | |
225 | |
226 | static XEXT_GENERATE_CLOSE_DISPLAY (XiGMiscCloseDisplay, xigmisc_info) |
227 | |
228 | static XEXT_GENERATE_FIND_DISPLAY (XiGMiscFindDisplay, xigmisc_info, |
229 | xigmisc_extension_name, |
230 | &xigmisc_extension_hooks, XiGMiscNumberEvents, NULL) |
231 | |
232 | |
233 | /*****************************************************************************/ |
234 | |
235 | Bool XiGMiscQueryVersion(Display *dpy, int *major, int *minor) |
236 | { |
237 | int opcode, event, error; |
238 | xXiGMiscQueryVersionReq *req; |
239 | xXiGMiscQueryVersionReply rep; |
240 | XExtDisplayInfo *info = XiGMiscFindDisplay(dpy); |
241 | |
242 | if (!XQueryExtension(dpy, XIGMISC_PROTOCOL_NAME, &opcode, &event, &error)) |
243 | return xFalse; |
244 | |
245 | XiGMiscCheckExtension(dpy, info, xFalse); |
246 | |
247 | LockDisplay (dpy); |
248 | XiGMiscGetReq (XiGMiscQueryVersion, req, info); |
249 | |
250 | req->major = XIGMISC_MAJOR_VERSION; |
251 | req->minor = XIGMISC_MINOR_VERSION; |
252 | |
253 | if (!_XReply (dpy, (xReply *)&rep, 0, xTrue)) { |
254 | UnlockDisplay(dpy); |
255 | SyncHandle(); |
256 | return xFalse; |
257 | } |
258 | |
259 | *major = rep.major; |
260 | *minor = rep.minor; |
261 | UnlockDisplay(dpy); |
262 | SyncHandle(); |
263 | |
264 | return xTrue; |
265 | } |
266 | |
267 | int XiGMiscQueryViews(Display *dpy, int screen, XiGMiscViewInfo **pviews) |
268 | { |
269 | int n, size; |
270 | XiGMiscViewInfo *views; |
271 | xXiGMiscQueryViewsReq *req; |
272 | xXiGMiscQueryViewsReply rep; |
273 | XExtDisplayInfo *info = XiGMiscFindDisplay(dpy); |
274 | XiGMiscCheckExtension(dpy, info, 0); |
275 | |
276 | LockDisplay (dpy); |
277 | XiGMiscGetReq (XiGMiscQueryViews, req, info); |
278 | req->screen = screen; |
279 | |
280 | if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) { |
281 | UnlockDisplay(dpy); |
282 | SyncHandle(); |
283 | return 0; |
284 | } |
285 | |
286 | n = rep.nviews; |
287 | |
288 | if (n > 0) { |
289 | size = sizeof(XiGMiscViewInfo) * n; |
290 | views = (XiGMiscViewInfo*)Xmalloc(size); |
291 | if (!views) { |
292 | _XEatData(dpy, (unsigned long)size); |
293 | UnlockDisplay(dpy); |
294 | SyncHandle(); |
295 | return 0; |
296 | } |
297 | |
298 | _XReadPad(dpy, (void*)views, size); |
299 | |
300 | *pviews = views; |
301 | } |
302 | |
303 | UnlockDisplay(dpy); |
304 | SyncHandle(); |
305 | |
306 | return n; |
307 | } |
308 | |
309 | int XiGMiscQueryResolutions(Display *dpy, int screen, int view, int *pactive, XiGMiscResolutionInfo **presolutions) |
310 | { |
311 | int n, size; |
312 | XiGMiscResolutionInfo *resolutions; |
313 | xXiGMiscQueryResolutionsReq *req; |
314 | xXiGMiscQueryResolutionsReply rep; |
315 | XExtDisplayInfo *info = XiGMiscFindDisplay(dpy); |
316 | XiGMiscCheckExtension(dpy, info, 0); |
317 | |
318 | LockDisplay (dpy); |
319 | XiGMiscGetReq (XiGMiscQueryResolutions, req, info); |
320 | req->screen = screen; |
321 | req->view = view; |
322 | |
323 | if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) { |
324 | UnlockDisplay(dpy); |
325 | SyncHandle(); |
326 | return 0; |
327 | } |
328 | |
329 | n = rep.nresolutions; |
330 | |
331 | if (n > 0) { |
332 | size = sizeof(XiGMiscResolutionInfo) * n; |
333 | resolutions = (XiGMiscResolutionInfo*)Xmalloc(size); |
334 | if (!resolutions) { |
335 | _XEatData(dpy, (unsigned long)size); |
336 | UnlockDisplay(dpy); |
337 | SyncHandle(); |
338 | return 0; |
339 | } |
340 | |
341 | _XReadPad(dpy, (void*)resolutions, size); |
342 | |
343 | *presolutions = resolutions; |
344 | *pactive = rep.active; |
345 | } |
346 | |
347 | UnlockDisplay(dpy); |
348 | SyncHandle(); |
349 | |
350 | return n; |
351 | } |
352 | |
353 | void XiGMiscChangeResolution(Display *dpy, int screen, int view, int width, int height, int refresh) |
354 | { |
355 | xXiGMiscChangeResolutionReq *req; |
356 | XExtDisplayInfo *info = XiGMiscFindDisplay(dpy); |
357 | |
358 | XiGMiscSimpleCheckExtension(dpy, info); |
359 | |
360 | LockDisplay (dpy); |
361 | XiGMiscGetReq (XiGMiscChangeResolution, req, info); |
362 | req->screen = screen; |
363 | req->view = view; |
364 | req->width = width; |
365 | req->height = height; |
366 | req->refresh = refresh; |
367 | |
368 | UnlockDisplay(dpy); |
369 | SyncHandle(); |
370 | } |
371 | |
372 | |
373 | Bool XiGMiscFullScreen(Display *dpy, int screen, XID window, XID cmap) |
374 | { |
375 | xXiGMiscFullScreenReq *req; |
376 | xXiGMiscFullScreenReply rep; |
377 | XExtDisplayInfo *info = XiGMiscFindDisplay(dpy); |
378 | |
379 | XiGMiscCheckExtension(dpy, info, xFalse); |
380 | |
381 | LockDisplay (dpy); |
382 | XiGMiscGetReq (XiGMiscFullScreen, req, info); |
383 | req->screen = screen; |
384 | req->pad0 = 0; |
385 | req->pad1 = 0; |
386 | req->window = window; |
387 | req->cmap = cmap; |
388 | |
389 | if (!_XReply (dpy, (xReply *)&rep, 0, xTrue)) { |
390 | UnlockDisplay(dpy); |
391 | SyncHandle(); |
392 | return xFalse; |
393 | } |
394 | |
395 | UnlockDisplay(dpy); |
396 | SyncHandle(); |
397 | |
398 | return (rep.success ? xTrue : xFalse); |
399 | } |
400 | |
401 | |
402 | /* SDL addition from Ryan: free memory used by xme. */ |
403 | void XiGMiscDestroy(void) |
404 | { |
405 | if (xigmisc_info) { |
406 | XextDestroyExtension(xigmisc_info); |
407 | xigmisc_info = NULL; |
408 | } |
409 | } |
410 | |