Xinerama.c revision bcbfc08f
1/*****************************************************************
2Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
3Permission is hereby granted, free of charge, to any person obtaining a copy
4of this software and associated documentation files (the "Software"), to deal
5in the Software without restriction, including without limitation the rights
6to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7copies of the Software.
8
9The above copyright notice and this permission notice shall be included in
10all copies or substantial portions of the Software.
11
12THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
15DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
16BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
17WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
18IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
20Except as contained in this notice, the name of Digital Equipment Corporation
21shall not be used in advertising or otherwise to promote the sale, use or other
22dealings in this Software without prior written authorization from Digital
23Equipment Corporation.
24******************************************************************/
25
26#include <X11/Xlibint.h>
27#include <X11/Xutil.h>
28#include <X11/extensions/Xext.h>
29#include <X11/extensions/extutil.h>
30#include <X11/extensions/panoramiXext.h>
31#include <X11/extensions/panoramiXproto.h>
32#include <X11/extensions/Xinerama.h>
33
34
35static XExtensionInfo _panoramiX_ext_info_data;
36static XExtensionInfo *panoramiX_ext_info = &_panoramiX_ext_info_data;
37static char *panoramiX_extension_name = PANORAMIX_PROTOCOL_NAME;
38
39#define PanoramiXCheckExtension(dpy,i,val) \
40  XextCheckExtension (dpy, i, panoramiX_extension_name, val)
41#define PanoramiXSimpleCheckExtension(dpy,i) \
42  XextSimpleCheckExtension (dpy, i, panoramiX_extension_name)
43
44static int close_display(Display *dpy, XExtCodes *codes);
45
46static /* const */ XExtensionHooks panoramiX_extension_hooks = {
47    NULL,				/* create_gc */
48    NULL,				/* copy_gc */
49    NULL,				/* flush_gc */
50    NULL,				/* free_gc */
51    NULL,				/* create_font */
52    NULL,				/* free_font */
53    close_display,			/* close_display */
54    NULL,				/* wire_to_event */
55    NULL,				/* event_to_wire */
56    NULL,				/* error */
57    NULL,				/* error_string */
58};
59
60static XEXT_GENERATE_FIND_DISPLAY (find_display, panoramiX_ext_info,
61				   panoramiX_extension_name,
62				   &panoramiX_extension_hooks,
63				   0, NULL)
64
65static XEXT_GENERATE_CLOSE_DISPLAY (close_display, panoramiX_ext_info)
66
67
68
69/****************************************************************************
70 *                                                                          *
71 *			    PanoramiX public interfaces                         *
72 *                                                                          *
73 ****************************************************************************/
74
75Bool XPanoramiXQueryExtension (
76    Display *dpy,
77    int *event_base_return,
78    int *error_base_return
79)
80{
81    XExtDisplayInfo *info = find_display (dpy);
82
83    if (XextHasExtension(info)) {
84	*event_base_return = info->codes->first_event;
85	*error_base_return = info->codes->first_error;
86	return True;
87    } else {
88	return False;
89    }
90}
91
92
93Status XPanoramiXQueryVersion(
94    Display *dpy,
95    int     *major_version_return,
96    int     *minor_version_return
97)
98{
99    XExtDisplayInfo *info = find_display (dpy);
100    xPanoramiXQueryVersionReply	    rep;
101    register xPanoramiXQueryVersionReq  *req;
102
103    PanoramiXCheckExtension (dpy, info, 0);
104
105    LockDisplay (dpy);
106    GetReq (PanoramiXQueryVersion, req);
107    req->reqType = info->codes->major_opcode;
108    req->panoramiXReqType = X_PanoramiXQueryVersion;
109    req->clientMajor = PANORAMIX_MAJOR_VERSION;
110    req->clientMinor = PANORAMIX_MINOR_VERSION;
111    if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
112	UnlockDisplay (dpy);
113	SyncHandle ();
114	return 0;
115    }
116    *major_version_return = rep.majorVersion;
117    *minor_version_return = rep.minorVersion;
118    UnlockDisplay (dpy);
119    SyncHandle ();
120    return 1;
121}
122
123XPanoramiXInfo *XPanoramiXAllocInfo(void)
124{
125	return (XPanoramiXInfo *) Xmalloc (sizeof (XPanoramiXInfo));
126}
127
128Status XPanoramiXGetState (
129    Display		*dpy,
130    Drawable		drawable,
131    XPanoramiXInfo	*panoramiX_info
132)
133{
134    XExtDisplayInfo			*info = find_display (dpy);
135    xPanoramiXGetStateReply	rep;
136    register xPanoramiXGetStateReq	*req;
137
138    PanoramiXCheckExtension (dpy, info, 0);
139
140    LockDisplay (dpy);
141    GetReq (PanoramiXGetState, req);
142    req->reqType = info->codes->major_opcode;
143    req->panoramiXReqType = X_PanoramiXGetState;
144    req->window = drawable;
145    if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
146	UnlockDisplay (dpy);
147	SyncHandle ();
148	return 0;
149    }
150    UnlockDisplay (dpy);
151    SyncHandle ();
152    panoramiX_info->window = rep.window;
153    panoramiX_info->State = rep.state;
154    return 1;
155}
156
157Status XPanoramiXGetScreenCount (
158    Display		*dpy,
159    Drawable		drawable,
160    XPanoramiXInfo	*panoramiX_info
161)
162{
163    XExtDisplayInfo			*info = find_display (dpy);
164    xPanoramiXGetScreenCountReply	rep;
165    register xPanoramiXGetScreenCountReq	*req;
166
167    PanoramiXCheckExtension (dpy, info, 0);
168
169    LockDisplay (dpy);
170    GetReq (PanoramiXGetScreenCount, req);
171    req->reqType = info->codes->major_opcode;
172    req->panoramiXReqType = X_PanoramiXGetScreenCount;
173    req->window = drawable;
174    if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
175	UnlockDisplay (dpy);
176	SyncHandle ();
177	return 0;
178    }
179    UnlockDisplay (dpy);
180    SyncHandle ();
181    panoramiX_info->window = rep.window;
182    panoramiX_info->ScreenCount = rep.ScreenCount;
183    return 1;
184}
185
186Status XPanoramiXGetScreenSize (
187    Display		*dpy,
188    Drawable		drawable,
189    int			screen_num,
190    XPanoramiXInfo	*panoramiX_info
191)
192{
193    XExtDisplayInfo			*info = find_display (dpy);
194    xPanoramiXGetScreenSizeReply	rep;
195    register xPanoramiXGetScreenSizeReq	*req;
196
197    PanoramiXCheckExtension (dpy, info, 0);
198
199    LockDisplay (dpy);
200    GetReq (PanoramiXGetScreenSize, req);
201    req->reqType = info->codes->major_opcode;
202    req->panoramiXReqType = X_PanoramiXGetScreenSize;
203    req->window = drawable;
204    req->screen = screen_num;			/* need to define */
205    if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
206	UnlockDisplay (dpy);
207	SyncHandle ();
208	return 0;
209    }
210    UnlockDisplay (dpy);
211    SyncHandle ();
212    panoramiX_info->window = rep.window;
213    panoramiX_info->screen = rep.screen;
214    panoramiX_info->width =  rep.width;
215    panoramiX_info->height = rep.height;
216    return 1;
217}
218
219/*******************************************************************\
220  Alternate interface to make up for shortcomings in the original,
221  namely, the omission of the screen origin.  The new interface is
222  in the "Xinerama" namespace instead of "PanoramiX".
223\*******************************************************************/
224
225Bool XineramaQueryExtension (
226   Display *dpy,
227   int     *event_base_return,
228   int     *error_base_return
229)
230{
231   return XPanoramiXQueryExtension(dpy, event_base_return, error_base_return);
232}
233
234Status XineramaQueryVersion(
235   Display *dpy,
236   int     *major,
237   int     *minor
238)
239{
240   return XPanoramiXQueryVersion(dpy, major, minor);
241}
242
243Bool XineramaIsActive(Display *dpy)
244{
245    xXineramaIsActiveReply	rep;
246    xXineramaIsActiveReq  	*req;
247    XExtDisplayInfo 		*info = find_display (dpy);
248
249    if(!XextHasExtension(info))
250	return False;  /* server doesn't even have the extension */
251
252    LockDisplay (dpy);
253    GetReq (XineramaIsActive, req);
254    req->reqType = info->codes->major_opcode;
255    req->panoramiXReqType = X_XineramaIsActive;
256    if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
257	UnlockDisplay (dpy);
258	SyncHandle ();
259	return False;
260    }
261    UnlockDisplay (dpy);
262    SyncHandle ();
263    return rep.state;
264}
265
266XineramaScreenInfo *
267XineramaQueryScreens(
268   Display *dpy,
269   int     *number
270)
271{
272    XExtDisplayInfo		*info = find_display (dpy);
273    xXineramaQueryScreensReply	rep;
274    xXineramaQueryScreensReq	*req;
275    XineramaScreenInfo		*scrnInfo = NULL;
276
277    PanoramiXCheckExtension (dpy, info, NULL);
278
279    LockDisplay (dpy);
280    GetReq (XineramaQueryScreens, req);
281    req->reqType = info->codes->major_opcode;
282    req->panoramiXReqType = X_XineramaQueryScreens;
283    if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
284	UnlockDisplay (dpy);
285	SyncHandle ();
286	return NULL;
287    }
288
289    if(rep.number) {
290	if((scrnInfo = Xmalloc(sizeof(XineramaScreenInfo) * rep.number))) {
291	    xXineramaScreenInfo scratch;
292	    int i;
293
294	    for(i = 0; i < rep.number; i++) {
295		_XRead(dpy, (char*)(&scratch), sz_XineramaScreenInfo);
296		scrnInfo[i].screen_number = i;
297		scrnInfo[i].x_org 	  = scratch.x_org;
298		scrnInfo[i].y_org 	  = scratch.y_org;
299		scrnInfo[i].width 	  = scratch.width;
300		scrnInfo[i].height 	  = scratch.height;
301	    }
302
303	    *number = rep.number;
304	} else
305	    _XEatData(dpy, rep.length << 2);
306    } else {
307	*number = 0;
308    }
309
310    UnlockDisplay (dpy);
311    SyncHandle ();
312    return scrnInfo;
313}
314