/* * $Id$ * * Copyright © 2004 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include "lightpipe.h" #include #include #include #include #include #include #include #include int main (int argc, char **argv) { Display *display; Display *new_display = 0; Window window; Window new = 0; int new_width = 0, new_height = 0; XLightPipeWindow *lpw = 0; XImage *image = 0; GC new_gc = 0; struct pollfd fds[2]; int nfd; if (argc != 4) { fprintf (stderr, "usage: %s \n", argv[0]); exit (1); } display = XOpenDisplay (argv[1]); if (!display) { fprintf (stderr, "can't open display %s\n", argv[1]); exit (1); } if (!strcmp (argv[2], "root")) window = RootWindow (display, 0); else window = strtol (argv[2], 0, 0); XLightPipeInit (); XLightPipeAttendWindow (display, window, False); for (;;) { if (new && XPending (new_display)) { while (QLength (new_display)) { XEvent ev; int x, y, w, h; XNextEvent (new_display, &ev); switch (ev.type) { case Expose: x = ev.xexpose.x; y = ev.xexpose.y; w = ev.xexpose.width; h = ev.xexpose.height; if (x + w > new_width) w = new_width - x; if (y + h > new_height) h = new_height - y; if (w > 0 && h > 0) { XPutImage (new_display, new, new_gc, image, x, y, x, y, w, h); } break; case MotionNotify: XTestFakeMotionEvent (display, 0, ev.xmotion.x, ev.xmotion.y, 0); break; case ButtonPress: XTestFakeButtonEvent (display, ev.xbutton.button, True, 0); break; case ButtonRelease: XTestFakeButtonEvent (display, ev.xbutton.button, False, 0); break; } } } else if (XPending (display)) { lpw = XLightPipeCheckWindow (display, window, True); if (!new) { XWMHints *wmhints; XSizeHints *normalhints; XClassHint *classhint; char *name = "lightpipe"; new_display = XOpenDisplay (argv[3]); new = XCreateSimpleWindow (new_display, RootWindow (new_display, DefaultScreen (new_display)), 0, 0, lpw->geometry.width, lpw->geometry.height, 0, 0, 0); XSelectInput (new_display, new, ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask); new_gc = XCreateGC (new_display, new, 0, 0); normalhints = XAllocSizeHints (); normalhints->flags = 0; normalhints->x = 0; normalhints->y = 0; normalhints->width = lpw->geometry.width; normalhints->height = lpw->geometry.height; classhint = XAllocClassHint (); classhint->res_name = "lightpipe"; classhint->res_class = "Lightpipe"; wmhints = XAllocWMHints (); wmhints->flags = InputHint; wmhints->input = False; Xutf8SetWMProperties (new_display, new, name, name, 0, 0, normalhints, wmhints, classhint); XFree (wmhints); XFree (classhint); XFree (normalhints); XMapWindow (new_display, new); new_width = lpw->geometry.width; new_height = lpw->geometry.height; } if (new_width != lpw->geometry.width || new_height != lpw->geometry.height) { new_width = lpw->geometry.width; new_height = lpw->geometry.height; XResizeWindow (new_display, new, new_width, new_height); } image = lpw->image; #if 0 printf ("@ %4d, %4d -> %4d x %4d\n", lpw->damage.x, lpw->damage.y, lpw->damage.width, lpw->damage.height); #endif XPutImage (new_display, new, new_gc, image, lpw->damage.x, lpw->damage.y, lpw->damage.x, lpw->damage.y, lpw->damage.width, lpw->damage.height); XLightPipeRelease (display, lpw); } else { fds[0].fd = ConnectionNumber (display); fds[0].events = POLLIN; nfd = 1; if (new) { fds[1].fd = ConnectionNumber (new_display); fds[0].events = POLLIN; nfd = 2; } poll (fds, nfd, -1); } } return 0; }