98N/A/* Copyright (c) 1990, 2012, Oracle and/or its affiliates. All rights reserved.
98N/A *
98N/A * Permission is hereby granted, free of charge, to any person obtaining a
98N/A * copy of this software and associated documentation files (the "Software"),
1265N/A * to deal in the Software without restriction, including without limitation
98N/A * the rights to use, copy, modify, merge, publish, distribute, sublicense,
98N/A * and/or sell copies of the Software, and to permit persons to whom the
919N/A * Software is furnished to do so, subject to the following conditions:
919N/A *
919N/A * The above copyright notice and this permission notice (including the next
919N/A * paragraph) shall be included in all copies or substantial portions of the
919N/A * Software.
919N/A *
919N/A * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
919N/A * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
919N/A * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
919N/A * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
919N/A * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
919N/A * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
919N/A * DEALINGS IN THE SOFTWARE.
919N/A */
919N/A
919N/A/*-
919N/A *-----------------------------------------------------------------------
98N/A * XGrabWin.c - X11 Client Side interface to Window Grabber.
98N/A *
98N/A * This code uses the standard R3 extension mechanism for sending the grab or
98N/A * ungrab window requests. If the extension isn't present, it uses the un-used
98N/A * protocol if the server is from Sun.
98N/A *
1265N/A * The global state is only relevant to one display. Multiple displays
493N/A * will have to be implemented via arrays of global data.
98N/A *-----------------------------------------------------------------------
911N/A */
1265N/A#define NEED_REPLIES
1265N/A#define NEED_EVENTS
1265N/A
911N/A#include <string.h>
98N/A#include <unistd.h>
235N/A
493N/A#include <X11/Xlibint.h> /* from usr.lib/libX11 */
98N/A#include <X11/Xproto.h> /* from usr.lib/libX11/include */
916N/A#include <X11/extensions/dgast.h>
916N/A
916N/A#include <sys/socket.h>
916N/A#include <netinet/in.h>
970N/A#include <sys/types.h>
970N/A /* Unused requests */
970N/A#define X_GrabWindow 125 /* should be in Xproto.h */
970N/A#define X_UnGrabWindow 126 /* just before X_NoOperation */
970N/A
970N/A#define BadCookie 0
970N/A
970N/Astatic int X_WxExtensionCode;
970N/A
970N/Astatic int WxError (Display *dpy,int mc);
970N/A
970N/Astatic enum {
970N/A NOT_INITIALIZED,
970N/A USE_EXTENSION,
970N/A USE_EXTRA_PROTOCOL,
970N/A NOT_LOCAL_HOST
970N/A } WxInitialized = NOT_INITIALIZED;
970N/A
970N/Astatic void
970N/AInitialize(dpy)
970N/A Display *dpy;
970N/A{
970N/A int tmp;
970N/A
970N/A if (dpy->display_name[0] != ':') {
1029N/A char hostname[64];
1029N/A
1124N/A gethostname(hostname,64);
1124N/A if (strncmp("unix",dpy->display_name,4) &&
1124N/A strncmp("localhost",dpy->display_name,9) &&
1124N/A strncmp(hostname,dpy->display_name,strlen(hostname))) {
1124N/A WxInitialized = NOT_LOCAL_HOST;
1124N/A return;
970N/A }
98N/A }
98N/A
1265N/A if (XQueryExtension(dpy, "SunWindowGrabber",&X_WxExtensionCode,
1124N/A &tmp, &tmp))
1124N/A WxInitialized = USE_EXTENSION;
1124N/A else if (!strcmp(dpy->vendor,"X11/NeWS - Sun Microsystems Inc."))
1265N/A WxInitialized = USE_EXTRA_PROTOCOL;
1265N/A}
1265N/A
1124N/Aint
98N/AXGrabWindow(
493N/A Display *dpy,
98N/A Window win)
970N/A{
970N/A xResourceReq *req;
970N/A xGenericReply rep;
1026N/A
970N/A if (WxInitialized == NOT_INITIALIZED)
970N/A Initialize(dpy);
1026N/A
1124N/A switch (WxInitialized) {
1003N/A case USE_EXTENSION:
98N/A LockDisplay(dpy);
98N/A GetResReq(WxExtensionCode, win, req);
98N/A req->pad = X_WxGrab;
908N/A (void) _XReply(dpy, (xReply *) &rep, 0, xFalse);
591N/A UnlockDisplay(dpy);
493N/A SyncHandle();
493N/A return rep.data00;
1201N/A case USE_EXTRA_PROTOCOL:
1201N/A LockDisplay(dpy);
1201N/A GetResReq(GrabWindow, win, req);
1201N/A (void) _XReply(dpy, (xReply *) &rep, 0, xFalse);
1265N/A UnlockDisplay(dpy);
1265N/A SyncHandle();
1201N/A return (rep.data00); /* GrabToken */
1201N/A case NOT_INITIALIZED:
1201N/A WxError(dpy,X_WxGrab);
1201N/A case NOT_LOCAL_HOST:
493N/A return BadCookie;
493N/A }
493N/A return BadImplementation;
493N/A}
493N/A
493N/Aint
1026N/AXUnGrabWindow(
705N/A Display *dpy,
493N/A Window win)
557N/A{
1176N/A xResourceReq *req;
493N/A xGenericReply rep;
965N/A
965N/A if (WxInitialized == NOT_INITIALIZED)
965N/A Initialize(dpy);
1196N/A
1196N/A switch (WxInitialized) {
1196N/A case USE_EXTENSION:
1196N/A LockDisplay(dpy);
1196N/A GetResReq(WxExtensionCode, win, req);
1196N/A req->pad = X_WxUnGrab;
1196N/A (void) _XReply(dpy, (xReply *) &rep, 0, xFalse);
1196N/A UnlockDisplay(dpy);
1196N/A SyncHandle();
1196N/A return rep.data00; /* Status */
1196N/A case USE_EXTRA_PROTOCOL:
606N/A LockDisplay(dpy);
606N/A GetResReq(UnGrabWindow, win, req);
851N/A (void) _XReply(dpy, (xReply *) &rep, 0, xFalse);
851N/A UnlockDisplay(dpy);
851N/A SyncHandle();
851N/A return (rep.data00); /* Status */
851N/A case NOT_INITIALIZED:
851N/A WxError(dpy,X_WxUnGrab);
851N/A case NOT_LOCAL_HOST:
98N/A return BadCookie;
1193N/A }
1193N/A return BadImplementation;
1193N/A}
591N/A
963N/A
1201N/Aint
910N/AXGrabColormap(
1097N/A Display *dpy,
910N/A Colormap cmap)
1097N/A{
910N/A xResourceReq *req;
98N/A xGenericReply rep;
98N/A
910N/A if (WxInitialized == NOT_INITIALIZED)
910N/A Initialize(dpy);
970N/A
1030N/A switch (WxInitialized) {
1030N/A case USE_EXTENSION:
970N/A LockDisplay(dpy);
970N/A GetResReq(WxExtensionCode, cmap, req);
970N/A req->pad = X_WxGrabColormap;
1097N/A (void) _XReply(dpy, (xReply *) &rep, 0, xFalse);
1097N/A UnlockDisplay(dpy);
1030N/A SyncHandle();
1030N/A return rep.data00;
910N/A case USE_EXTRA_PROTOCOL:
98N/A case NOT_INITIALIZED:
1193N/A WxError(dpy,X_WxGrabColormap);
1193N/A case NOT_LOCAL_HOST:
1193N/A return BadCookie;
1193N/A }
1193N/A return BadImplementation;
1193N/A}
1193N/A
1193N/Aint
1193N/AXUnGrabColormap(
1193N/A Display *dpy,
1193N/A Colormap cmap)
606N/A{
98N/A xResourceReq *req;
606N/A xGenericReply rep;
98N/A
591N/A if (WxInitialized == NOT_INITIALIZED)
851N/A Initialize(dpy);
111N/A
606N/A switch (WxInitialized) {
1088N/A case USE_EXTENSION:
1088N/A LockDisplay(dpy);
1088N/A GetResReq(WxExtensionCode, cmap, req);
733N/A req->pad = X_WxUnGrabColormap;
1265N/A (void) _XReply(dpy, (xReply *) &rep, 0, xFalse);
1265N/A UnlockDisplay(dpy);
733N/A SyncHandle();
963N/A return rep.data00; /* Status */
851N/A case USE_EXTRA_PROTOCOL:
963N/A case NOT_INITIALIZED:
1088N/A WxError(dpy,X_WxGrabColormap);
1088N/A case NOT_LOCAL_HOST:
1088N/A return BadCookie;
1088N/A }
98N/A return BadImplementation;
851N/A}
1097N/A
1097N/A
851N/Aint
935N/AXGrabRetainedWindow(
851N/A Display *dpy,
851N/A Window win)
935N/A{
606N/A xResourceReq *req;
935N/A xGenericReply rep;
935N/A
935N/A if (WxInitialized == NOT_INITIALIZED)
935N/A Initialize(dpy);
212N/A
1183N/A switch (WxInitialized) {
1183N/A case USE_EXTENSION:
1183N/A LockDisplay(dpy);
1183N/A GetResReq(WxExtensionCode, win, req);
1196N/A req->pad = X_WxGrabRetained;
1183N/A (void) _XReply(dpy, (xReply *) &rep, 0, xFalse);
1183N/A UnlockDisplay(dpy);
1183N/A SyncHandle();
1233N/A return rep.data00;
1196N/A case USE_EXTRA_PROTOCOL:
1196N/A case NOT_INITIALIZED:
1183N/A WxError(dpy,X_WxGrabRetained);
98N/A case NOT_LOCAL_HOST:
98N/A return BadCookie;
1196N/A }
1183N/A return BadImplementation;
1196N/A}
908N/A
963N/Aint
963N/AXUnGrabRetainedWindow(
963N/A Display *dpy,
963N/A Window win)
963N/A{
963N/A xResourceReq *req;
1030N/A xGenericReply rep;
970N/A
1097N/A if (WxInitialized == NOT_INITIALIZED)
1097N/A Initialize(dpy);
970N/A
970N/A switch (WxInitialized) {
970N/A case USE_EXTENSION:
970N/A LockDisplay(dpy);
970N/A GetResReq(WxExtensionCode, win, req);
970N/A req->pad = X_WxUnGrabRetained;
1152N/A (void) _XReply(dpy, (xReply *) &rep, 0, xFalse);
970N/A UnlockDisplay(dpy);
970N/A SyncHandle();
970N/A return rep.data00; /* Status */
970N/A case USE_EXTRA_PROTOCOL:
1026N/A case NOT_INITIALIZED:
974N/A WxError(dpy,X_WxUnGrabRetained);
970N/A case NOT_LOCAL_HOST:
970N/A return BadCookie;
1026N/A }
970N/A return BadImplementation;
970N/A}
974N/A
974N/A
970N/Aint
1026N/AXGetRetainedPath(
970N/A Display *dpy,
970N/A Window win,
970N/A char *path)
970N/A{
970N/A xResourceReq *req;
970N/A xOWGXRtndPathReply rep;
970N/A
970N/A if (WxInitialized == NOT_INITIALIZED)
970N/A Initialize(dpy);
970N/A
970N/A switch (WxInitialized) {
970N/A case USE_EXTENSION:
970N/A LockDisplay(dpy);
970N/A GetResReq(WxExtensionCode, win, req);
970N/A req->pad = X_WxGetRetainedPath;
970N/A (void) _XReply(dpy, (xReply *) &rep,
1003N/A (SIZEOF(xOWGXRtndPathReply) - SIZEOF(xReply)) >> 2, xFalse);
1003N/A UnlockDisplay(dpy);
1003N/A SyncHandle();
1003N/A strcpy(path, rep.path);
1003N/A return Success;
1003N/A case USE_EXTRA_PROTOCOL:
970N/A case NOT_INITIALIZED:
970N/A WxError(dpy,X_WxGetRetainedPath);
970N/A case NOT_LOCAL_HOST:
970N/A return BadCookie;
970N/A }
970N/A return BadImplementation;
970N/A}
970N/A
970N/A
970N/A
970N/A
970N/A
970N/Astatic int
1030N/AWxError (
1030N/A Display *dpy,
1030N/A int mc)
1030N/A{
1030N/A XErrorEvent event;
1030N/A extern int (*_XErrorFunction)();
1030N/A
1030N/A event.display = dpy;
1030N/A event.type = X_Error;
1030N/A event.error_code = BadImplementation;
1030N/A event.request_code = 0xff; /* Means that we were requesting an extension*/
1030N/A event.minor_code = mc;
1030N/A event.serial = dpy->request;
1030N/A if (_XErrorFunction != NULL) {
1030N/A return ((*_XErrorFunction)(dpy, &event));
1030N/A }
1030N/A exit(1);
1030N/A /*NOTREACHED*/
1030N/A}
1030N/A