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