7d7e4d8564d936a138b69ecf4bd39ad04df2c92d
[platform/upstream/libXinerama.git] / src / Xinerama.c
1 /*****************************************************************
2 Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
3 Permission is hereby granted, free of charge, to any person obtaining a copy
4 of this software and associated documentation files (the "Software"), to deal
5 in the Software without restriction, including without limitation the rights
6 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 copies of the Software.
8
9 The above copyright notice and this permission notice shall be included in
10 all copies or substantial portions of the Software.
11
12 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
15 DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
16 BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
17 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
18 IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
20 Except as contained in this notice, the name of Digital Equipment Corporation
21 shall not be used in advertising or otherwise to promote the sale, use or other
22 dealings in this Software without prior written authorization from Digital
23 Equipment 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
35 static XExtensionInfo _panoramiX_ext_info_data;
36 static XExtensionInfo *panoramiX_ext_info = &_panoramiX_ext_info_data;
37 static const 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
44 static int close_display(Display *dpy, XExtCodes *codes);
45
46 static /* 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
60 static XEXT_GENERATE_FIND_DISPLAY (find_display, panoramiX_ext_info,
61                                    panoramiX_extension_name,
62                                    &panoramiX_extension_hooks,
63                                    0, NULL)
64
65 static XEXT_GENERATE_CLOSE_DISPLAY (close_display, panoramiX_ext_info)
66
67
68
69 /****************************************************************************
70  *                                                                          *
71  *                          PanoramiX public interfaces                         *
72  *                                                                          *
73  ****************************************************************************/
74
75 Bool 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
93 Status 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
123 XPanoramiXInfo *XPanoramiXAllocInfo(void)
124 {
125         return (XPanoramiXInfo *) Xmalloc (sizeof (XPanoramiXInfo));
126 }
127
128 Status 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
157 Status 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
186 Status 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
225 Bool 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
234 Status XineramaQueryVersion(
235    Display *dpy,
236    int     *major,
237    int     *minor
238 )
239 {
240    return XPanoramiXQueryVersion(dpy, major, minor);
241 }
242
243 Bool 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
266 XineramaScreenInfo *
267 XineramaQueryScreens(
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 }