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