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