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
31#include <X11/Xlibint.h>
32#include <X11/Xutil.h>
33#include "../extensions/Xext.h"
34#include "../extensions/extutil.h"			/* in ../include */
35#include "../extensions/panoramiXext.h"
36#include "../extensions/panoramiXproto.h"		/* in ../include */
37#include "../extensions/Xinerama.h"
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();
49static /* const */ XExtensionHooks panoramiX_extension_hooks = {
50    NULL,				/* create_gc */
51    NULL,				/* copy_gc */
52    NULL,				/* flush_gc */
53    NULL,				/* free_gc */
54    NULL,				/* create_font */
55    NULL,				/* free_font */
56    close_display,			/* close_display */
57    NULL,				/* wire_to_event */
58    NULL,				/* event_to_wire */
59    NULL,				/* error */
60    NULL,				/* error_string */
61};
62
63static XEXT_GENERATE_FIND_DISPLAY (find_display, panoramiX_ext_info,
64				   panoramiX_extension_name,
65				   &panoramiX_extension_hooks,
66				   0, NULL)
67
68static XEXT_GENERATE_CLOSE_DISPLAY (close_display, panoramiX_ext_info)
69
70
71
72/****************************************************************************
73 *                                                                          *
74 *			    PanoramiX public interfaces                         *
75 *                                                                          *
76 ****************************************************************************/
77
78Bool SDL_NAME(XPanoramiXQueryExtension) (
79    Display *dpy,
80    int *event_basep,
81    int *error_basep
82)
83{
84    XExtDisplayInfo *info = find_display (dpy);
85
86    if (XextHasExtension(info)) {
87	*event_basep = info->codes->first_event;
88	*error_basep = info->codes->first_error;
89	return True;
90    } else {
91	return False;
92    }
93}
94
95
96Status SDL_NAME(XPanoramiXQueryVersion)(
97    Display *dpy,
98    int	    *major_versionp,
99    int *minor_versionp
100)
101{
102    XExtDisplayInfo *info = find_display (dpy);
103    xPanoramiXQueryVersionReply	    rep;
104    register xPanoramiXQueryVersionReq  *req;
105
106    PanoramiXCheckExtension (dpy, info, 0);
107
108    LockDisplay (dpy);
109    GetReq (PanoramiXQueryVersion, req);
110    req->reqType = info->codes->major_opcode;
111    req->panoramiXReqType = X_PanoramiXQueryVersion;
112    req->clientMajor = PANORAMIX_MAJOR_VERSION;
113    req->clientMinor = PANORAMIX_MINOR_VERSION;
114    if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
115	UnlockDisplay (dpy);
116	SyncHandle ();
117	return 0;
118    }
119    *major_versionp = rep.majorVersion;
120    *minor_versionp = rep.minorVersion;
121    UnlockDisplay (dpy);
122    SyncHandle ();
123    return 1;
124}
125
126SDL_NAME(XPanoramiXInfo) *SDL_NAME(XPanoramiXAllocInfo)(void)
127{
128	return (SDL_NAME(XPanoramiXInfo) *) Xmalloc (sizeof (SDL_NAME(XPanoramiXInfo)));
129}
130
131Status SDL_NAME(XPanoramiXGetState) (
132    Display		*dpy,
133    Drawable		drawable,
134    SDL_NAME(XPanoramiXInfo)	*panoramiX_info
135)
136{
137    XExtDisplayInfo			*info = find_display (dpy);
138    xPanoramiXGetStateReply	rep;
139    register xPanoramiXGetStateReq	*req;
140
141    PanoramiXCheckExtension (dpy, info, 0);
142
143    LockDisplay (dpy);
144    GetReq (PanoramiXGetState, req);
145    req->reqType = info->codes->major_opcode;
146    req->panoramiXReqType = X_PanoramiXGetState;
147    req->window = drawable;
148    if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
149	UnlockDisplay (dpy);
150	SyncHandle ();
151	return 0;
152    }
153    UnlockDisplay (dpy);
154    SyncHandle ();
155    panoramiX_info->window = rep.window;
156    panoramiX_info->State = rep.state;
157    return 1;
158}
159
160Status SDL_NAME(XPanoramiXGetScreenCount) (
161    Display		*dpy,
162    Drawable		drawable,
163    SDL_NAME(XPanoramiXInfo)	*panoramiX_info
164)
165{
166    XExtDisplayInfo			*info = find_display (dpy);
167    xPanoramiXGetScreenCountReply	rep;
168    register xPanoramiXGetScreenCountReq	*req;
169
170    PanoramiXCheckExtension (dpy, info, 0);
171
172    LockDisplay (dpy);
173    GetReq (PanoramiXGetScreenCount, req);
174    req->reqType = info->codes->major_opcode;
175    req->panoramiXReqType = X_PanoramiXGetScreenCount;
176    req->window = drawable;
177    if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
178	UnlockDisplay (dpy);
179	SyncHandle ();
180	return 0;
181    }
182    UnlockDisplay (dpy);
183    SyncHandle ();
184    panoramiX_info->window = rep.window;
185    panoramiX_info->ScreenCount = rep.ScreenCount;
186    return 1;
187}
188
189Status SDL_NAME(XPanoramiXGetScreenSize) (
190    Display		*dpy,
191    Drawable		drawable,
192    int			screen_num,
193    SDL_NAME(XPanoramiXInfo)	*panoramiX_info
194)
195{
196    XExtDisplayInfo			*info = find_display (dpy);
197    xPanoramiXGetScreenSizeReply	rep;
198    register xPanoramiXGetScreenSizeReq	*req;
199
200    PanoramiXCheckExtension (dpy, info, 0);
201
202    LockDisplay (dpy);
203    GetReq (PanoramiXGetScreenSize, req);
204    req->reqType = info->codes->major_opcode;
205    req->panoramiXReqType = X_PanoramiXGetScreenSize;
206    req->window = drawable;
207    req->screen = screen_num;			/* need to define */
208    if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
209	UnlockDisplay (dpy);
210	SyncHandle ();
211	return 0;
212    }
213    UnlockDisplay (dpy);
214    SyncHandle ();
215    panoramiX_info->window = rep.window;
216    panoramiX_info->screen = rep.screen;
217    panoramiX_info->width =  rep.width;
218    panoramiX_info->height = rep.height;
219    return 1;
220}
221
222/*******************************************************************\
223  Alternate interface to make up for shortcomings in the original,
224  namely, the omission of the screen origin.  The new interface is
225  in the "Xinerama" namespace instead of "PanoramiX".
226\*******************************************************************/
227
228Bool SDL_NAME(XineramaQueryExtension) (
229   Display *dpy,
230   int     *event_base,
231   int     *error_base
232)
233{
234   return SDL_NAME(XPanoramiXQueryExtension)(dpy, event_base, error_base);
235}
236
237Status SDL_NAME(XineramaQueryVersion)(
238   Display *dpy,
239   int     *major,
240   int     *minor
241)
242{
243   return SDL_NAME(XPanoramiXQueryVersion)(dpy, major, minor);
244}
245
246Bool SDL_NAME(XineramaIsActive)(Display *dpy)
247{
248    xXineramaIsActiveReply	rep;
249    xXineramaIsActiveReq  	*req;
250    XExtDisplayInfo 		*info = find_display (dpy);
251
252    if(!XextHasExtension(info))
253	return False;  /* server doesn't even have the extension */
254
255    LockDisplay (dpy);
256    GetReq (XineramaIsActive, req);
257    req->reqType = info->codes->major_opcode;
258    req->panoramiXReqType = X_XineramaIsActive;
259    if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
260	UnlockDisplay (dpy);
261	SyncHandle ();
262	return False;
263    }
264    UnlockDisplay (dpy);
265    SyncHandle ();
266    return rep.state;
267}
268
269#include <stdio.h>
270
271SDL_NAME(XineramaScreenInfo) *
272SDL_NAME(XineramaQueryScreens)(
273   Display *dpy,
274   int     *number
275)
276{
277    XExtDisplayInfo		*info = find_display (dpy);
278    xXineramaQueryScreensReply	rep;
279    xXineramaQueryScreensReq	*req;
280    SDL_NAME(XineramaScreenInfo)		*scrnInfo = NULL;
281
282    PanoramiXCheckExtension (dpy, info, 0);
283
284    LockDisplay (dpy);
285    GetReq (XineramaQueryScreens, req);
286    req->reqType = info->codes->major_opcode;
287    req->panoramiXReqType = X_XineramaQueryScreens;
288    if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
289	UnlockDisplay (dpy);
290	SyncHandle ();
291	return NULL;
292    }
293
294    if(rep.number) {
295	if((scrnInfo = Xmalloc(sizeof(SDL_NAME(XineramaScreenInfo)) * rep.number))) {
296	    xXineramaScreenInfo scratch;
297	    int i;
298
299	    for(i = 0; i < rep.number; i++) {
300		_XRead(dpy, (char*)(&scratch), sz_XineramaScreenInfo);
301		scrnInfo[i].screen_number = i;
302		scrnInfo[i].x_org 	  = scratch.x_org;
303		scrnInfo[i].y_org 	  = scratch.y_org;
304		scrnInfo[i].width 	  = scratch.width;
305		scrnInfo[i].height 	  = scratch.height;
306	    }
307
308	    *number = rep.number;
309	} else
310	    _XEatData(dpy, rep.length << 2);
311    }
312
313    UnlockDisplay (dpy);
314    SyncHandle ();
315    return scrnInfo;
316}
317
318
319
320