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
57typedef 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
65typedef 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
74typedef 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
83typedef 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
95typedef 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
108typedef 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
122typedef 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
135typedef 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
149typedef 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
164typedef struct {
165  INT16		x;
166  INT16		y;
167  CARD16	w;
168  CARD16	h;
169} XiGMiscViewInfo;
170
171typedef struct {
172  CARD16        width;
173  CARD16        height;
174  INT32         refresh;
175} XiGMiscResolutionInfo;
176
177/*****************************************************************************/
178
179static XExtensionInfo *xigmisc_info = NULL;
180static 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 */
209static int XiGMiscCloseDisplay();
210
211static 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
226static XEXT_GENERATE_CLOSE_DISPLAY (XiGMiscCloseDisplay, xigmisc_info)
227
228static XEXT_GENERATE_FIND_DISPLAY (XiGMiscFindDisplay, xigmisc_info,
229				   xigmisc_extension_name,
230				   &xigmisc_extension_hooks, XiGMiscNumberEvents, NULL)
231
232
233/*****************************************************************************/
234
235Bool 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
267int 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
309int 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
353void 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
373Bool 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. */
403void XiGMiscDestroy(void)
404{
405    if (xigmisc_info) {
406        XextDestroyExtension(xigmisc_info);
407        xigmisc_info = NULL;
408    }
409}
410
411