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