diff --git a/repos/os/lib/mk/xev_track.mk b/repos/os/lib/mk/xev_track.mk deleted file mode 100644 index 3054b405b..000000000 --- a/repos/os/lib/mk/xev_track.mk +++ /dev/null @@ -1,5 +0,0 @@ -SRC_CC = xev_track.cc -REQUIRES = x11 xdamage -LIBS = lx_hybrid - -vpath xev_track.cc $(REP_DIR)/src/lib/xev_track diff --git a/repos/os/src/app/xvfb/README b/repos/os/src/app/xvfb/README deleted file mode 100644 index 48a697b1b..000000000 --- a/repos/os/src/app/xvfb/README +++ /dev/null @@ -1,48 +0,0 @@ -Xvfb is a virtual X server that uses a plain file as framebuffer instead of a -physical screen. The 'xvfb' glue program makes an Xvfb session available to the -Linux version of Genode such that both native Genode programs and X clients can -run seamlessly integrated in one Nitpicker session. Using the 'xvfb' glue -program contained in this directory. Because Xvfb is executed as Nitpicker -client, it is possible to integrate multiple instances of Xvfb into the same -Nitpicker session. - - -Preconditions for compiling ---------------------------- - -The 'xvfb' glue program is a hybrid process using the Genode interfaces and the -Linux interfaces directly. It tracks dirty screen regions using the X damage -extension and injects user-input events into the X server using the X test -extension. So you need the development package of both extensions to compile -it. The Debian package for the X damage extension is called 'libxdamage-dev'. -The X test extension is normally installed by default. Furthermore you need to -enhance your 'SPECS' declaration in your -'/etc/specs.conf' file as follows: - -! SPECS += x11 xdamage xtest - - -Usage ------ - -First start Xvfb using the following command-line arguments: - -! Xvfb :1 -fbdir /tmp -screen 0 1024x768x16 - -While Xvfb is running, '/tmp/Xvfb_screen0' will contain the content of the X -server's frame buffer. This file must be specified for the 'xvfb' declaration -in the config file. In addition, the display of X server instance must be -declared via the 'display' tag. For example: - -! -! :1 -! /tmp/Xvfb_screen0 -! - - -Known Limitations ------------------ - -* With the current version, some keycodes are not mapped correctly. -* The screen mode of Nitpicker and the Xvfb session must be the same. - Only modes with 16bit color depth are supported. diff --git a/repos/os/src/app/xvfb/inject_input.cc b/repos/os/src/app/xvfb/inject_input.cc deleted file mode 100644 index 40f2d9203..000000000 --- a/repos/os/src/app/xvfb/inject_input.cc +++ /dev/null @@ -1,99 +0,0 @@ -/* - * \brief Inject input event into an X server - * \author Norman Feske - * \date 2009-11-04 - */ - -/* - * Copyright (C) 2009-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -/* local includes */ -#include "inject_input.h" - -/* Genode includes */ -#include -#include - -/* X11 includes */ -#include - - -static int convert_keycode_to_x11[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 43, 85, 86, 87, 88, 115, 119, 120, 121, 375, 123, 90, - 284, 285, 309, 298, 312, 91, 327, 328, 329, 331, 333, 335, 336, 337, 338, 339, - 367, 294, 293, 286, 350, 92, 334, 512, 116, 377, 109, 111, 373, 347, 348, 349, - 360, 93, 94, 95, 98, 376, 100, 101, 357, 316, 354, 304, 289, 102, 351, 355, - 103, 104, 105, 275, 281, 272, 306, 106, 274, 107, 288, 364, 358, 363, 362, 361, - 291, 108, 381, 290, 287, 292, 279, 305, 280, 99, 112, 257, 258, 113, 270, 114, - 118, 117, 125, 374, 379, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, - 271, 273, 276, 277, 278, 282, 283, 295, 296, 297, 299, 300, 301, 302, 303, 307, - 308, 310, 313, 314, 315, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 330, - 332, 340, 341, 342, 343, 344, 345, 346, 356, 359, 365, 368, 369, 370, 371, 372 -}; - - -static int convert_keycode(int keycode) -{ - if (keycode < 0 || keycode >= (int)(sizeof(convert_keycode_to_x11)/sizeof(int))) - return 0; - - return convert_keycode_to_x11[keycode] + 8; -} - - -/********************** - ** Public functions ** - **********************/ - -bool inject_input_init(Display *dpy) -{ - int dummy; - if (!XTestQueryExtension (dpy, &dummy, &dummy, &dummy, &dummy)) { - Genode::printf ("Error: Could not query Xtest extension\n"); - return false; - } - return true; -} - - -void inject_input_event(Display *dpy, Input::Event &ev) -{ - switch (ev.type()) { - - case Input::Event::MOTION: - XTestFakeMotionEvent(dpy, -1, ev.ax(), ev.ay(), CurrentTime); - break; - - case Input::Event::PRESS: - if (ev.code() == Input::BTN_LEFT) - XTestFakeButtonEvent(dpy, 1, 1, CurrentTime); - if (ev.code() == Input::BTN_RIGHT) - XTestFakeButtonEvent(dpy, 2, 1, CurrentTime); - else - XTestFakeKeyEvent(dpy, convert_keycode(ev.code()), 1, CurrentTime); - break; - - case Input::Event::RELEASE: - if (ev.code() == Input::BTN_LEFT) - XTestFakeButtonEvent(dpy, 1, 0, CurrentTime); - if (ev.code() == Input::BTN_RIGHT) - XTestFakeButtonEvent(dpy, 2, 0, CurrentTime); - else - XTestFakeKeyEvent(dpy, convert_keycode(ev.code()), 0, CurrentTime); - break; - - default: break; - } - - /* flush faked input events */ - XFlush(dpy); -} diff --git a/repos/os/src/app/xvfb/inject_input.h b/repos/os/src/app/xvfb/inject_input.h deleted file mode 100644 index b81b2ad63..000000000 --- a/repos/os/src/app/xvfb/inject_input.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * \brief Interface for X input injection - * \author Norman Feske - * \date 2009-11-04 - */ - -/* - * Copyright (C) 2009-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _INJECT_INPUT_H_ -#define _INJECT_INPUT_H_ - -/* Genode includes */ -#include - -/* X11 includes */ -#include - - -/** - * Initialize X input-injection mechanism - * - * \return true on success - */ -bool inject_input_init(Display *dpy); - - -/** - * Inject input event to the X session - */ -void inject_input_event(Display *dpy, Input::Event &ev); - - -#endif /* _INJECT_INPUT_H_ */ diff --git a/repos/os/src/app/xvfb/main.cc b/repos/os/src/app/xvfb/main.cc deleted file mode 100644 index c8db895db..000000000 --- a/repos/os/src/app/xvfb/main.cc +++ /dev/null @@ -1,348 +0,0 @@ -/* - * \brief Xvfb display application for Nitpicker - * \author Norman Feske - * \date 2009-11-03 - */ - -/* - * Copyright (C) 2009-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -/* Linux includes */ -#include -#include -#include -#include - -/* X11 includes */ -#include -#include - -/* Genode includes */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* local includes */ -#include "inject_input.h" - - -typedef Genode::uint16_t Pixel; - - -/** - * Variables defined by the supplied config file - */ -char *config_xvfb_file_name = 0; -char *config_x_display = 0; -int config_force_top = 1; - -/** - * Variables derived from the xvfb screen - */ -static int xvfb_width, xvfb_height; -static Pixel *xvfb_addr; - -static Framebuffer::Session *fb_session; -static Framebuffer::Mode fb_mode; -static Pixel *fb_addr; - - -static Nitpicker::Session *nitpicker() -{ - struct Connection : Nitpicker::Connection - { - Connection() - { - Nitpicker::Connection::buffer(mode(), false); - } - }; - - static Connection connection; - return &connection; -} - - -/** - * Parse configuration - * - * \return true if configuration is complete - */ -static bool read_config() -{ - using namespace Genode; - - Xml_node config_node = config()->xml_node(); - - try { - static char buf[256]; - config_node.sub_node("xvfb").value(buf, sizeof(buf)); - config_xvfb_file_name = buf; - } catch (Xml_node::Nonexistent_sub_node) { - printf("Error: Declaration of xvfb file name is missing\n"); - return false; - } - - try { - static char buf[256]; - config_node.sub_node("display").value(buf, sizeof(buf)); - config_x_display = buf; - } catch (Xml_node::Nonexistent_sub_node) { - printf("Error: Display declaration is missing\n"); - return false; - } - - return true; -} - - -static inline long convert_from_big_endian(long x) -{ - char v[4] = { - (char)((x & 0xff000000) >> 24), - (char)((x & 0x00ff0000) >> 16), - (char)((x & 0x0000ff00) >> 8), - (char)((x & 0x000000ff) >> 0), - }; - return *(long *)v; -} - - -/** - * Map file (read only) to local address space - */ -static void *mmap_file(const char *file_name) -{ - int fd = open(file_name, O_RDONLY); - if (fd < 0) - Genode::printf("Error: Could not open file %s\n", file_name); - - struct stat stat; - if (fstat(fd, &stat) < 0) - Genode::printf("Error: Could not fstat file %s\n", file_name); - - void *addr = mmap(0, stat.st_size, PROT_READ, MAP_SHARED, fd, 0); - if (addr == (void *)-1) - Genode::printf("Error: Could not mmap file\n"); - - return addr; -} - - -/** - * Flush part of the Xvfb screen to the Nitpicker session - */ -static void flush(int x, int y, int width, int height, Framebuffer::Mode const &mode) -{ - /* clip arguments against framebuffer geometry */ - if (x < 0) width += x, x = 0; - if (y < 0) height += y, y = 0; - if (width > mode.width() - x) width = mode.width() - x; - if (height > mode.height() - y) height = mode.height() - y; - - if (width <= 0 || height <= 0) return; - - /* copy pixels from xvfb to the nitpicker buffer */ - blit(xvfb_addr + x + xvfb_width*y, xvfb_width*sizeof(Pixel), - fb_addr + x + mode.width()*y, mode.width()*sizeof(Pixel), - width*sizeof(Pixel), height); - - /* refresh nitpicker views */ - fb_session->refresh(x, y, width, height); -} - - -class Bounding_box -{ - private: - - int _x1, _y1, _x2, _y2; - - - public: - - /** - * Constructor - */ - Bounding_box() { reset(); } - - bool valid() { return _x1 <= _x2 && _y1 <= _y2; } - - void reset() { _x1 = 0, _y1 = 0, _x2 = -1, _y2 = -1; } - - void extend(int x, int y, int w, int h) - { - int nx2 = x + w - 1; - int ny2 = y + h - 1; - - if (!valid()) { - _x1 = x, _y1 = y, _x2 = x + w - 1, _y2 = y + h - 1; - } else { - _x1 = Genode::min(_x1, x); - _y1 = Genode::min(_y1, y); - _x2 = Genode::max(_x2, nx2); - _y2 = Genode::max(_y2, ny2); - } - } - - int x() { return _x1; } - int y() { return _y1; } - int w() { return _x2 - _x1 + 1; } - int h() { return _y2 - _y1 + 1; } -}; - -static Bounding_box pending_redraw; - - -/************************************************** - ** Hook functions called by the X event tracker ** - **************************************************/ - -struct View -{ - Nitpicker::View_capability cap; -}; - -static View views[MAX_VIEWS]; - - -void create_view(int view_id) -{ - views[view_id].cap = nitpicker()->create_view(); -} - - -void destroy_view(int view_id) -{ - nitpicker()->destroy_view(views[view_id].cap); - - /* invalidate capability */ - views[view_id].cap = Nitpicker::View_capability(); -} - - -void set_background_view(int view_id) -{ - nitpicker()->background(views[view_id].cap); -} - - -void place_view(int view_id, int x, int y, int w, int h) -{ - Nitpicker::View_client view(views[view_id].cap); - view.viewport(x, y, w, h, -x, -y, false); -} - - -void stack_view(int view_id, int neighbor_id, bool behind) -{ - Nitpicker::View_client view(views[view_id].cap); - - /* translate invalid neighbor ID to invalid capability */ - Nitpicker::View_capability neighbor_cap; - if (neighbor_id >= 0) - neighbor_cap = views[neighbor_id].cap; - - view.stack(neighbor_cap, behind, true); -} - - -void refresh(int x, int y, int w, int h) -{ - pending_redraw.extend(x, y, w, h); -} - - -int main(int, char **) -{ - if (!read_config()) return -1; - - static Timer::Connection timer; - - static Framebuffer::Session_client fb(nitpicker()->framebuffer_session()); - static Input::Session_client input(nitpicker()->input_session()); - fb_session = &fb; - fb_addr = Genode::env()->rm_session()->attach(fb.dataspace()); - fb_mode = fb.mode(); - - XWDFileHeader *xwd = (XWDFileHeader *)mmap_file(config_xvfb_file_name); - if (!xwd) return -1; - - xvfb_width = convert_from_big_endian(xwd->pixmap_width); - xvfb_height = convert_from_big_endian(xwd->pixmap_height); - - enum { SUPPORTED_BPP = 16 }; - if (convert_from_big_endian(xwd->bits_per_pixel) != SUPPORTED_BPP) { - Genode::printf("Error: Color depth %d is not supported (use %d bpp)\n", - (int)convert_from_big_endian(xwd->pixmap_depth), SUPPORTED_BPP); - return -2; - } - - xvfb_addr = (Pixel *)((long)xwd + convert_from_big_endian(xwd->header_size) - + convert_from_big_endian(xwd->ncolors)*sizeof(XWDColor)); - - if (xvfb_width != fb_mode.width() || xvfb_height != fb_mode.height()) { - Genode::printf("Error: Xvfb mode must equal the Nitpicker screen mode of %dx%d\n", - fb_mode.width(), fb_mode.height()); - return -3; - } - - Input::Event *ev_buf = Genode::env()->rm_session()->attach(input.dataspace()); - - Display *dpy = XOpenDisplay(config_x_display); - if (!dpy) { - Genode::printf("Error: Cannot open display\n"); - return -4; - } - - if (!inject_input_init(dpy)) - return -5; - - if (!xev_track_init(dpy)) - return -6; - - for (;;) { - pending_redraw.reset(); - - /* - * Process due X events and update 'pending_redraw' as side effect - */ - XEvent ev; - while (XPending(dpy)) { - XNextEvent(dpy, &ev); - xev_track_handle_event(dpy, ev); - } - - /* - * Forward input events to the X session - */ - while (input.pending()) { - - int num_ev = input.flush(); - for (int i = 0; i < num_ev; i++) - inject_input_event(dpy, ev_buf[i]); - } - - /* - * Track mouse cursor and update 'pending_redraw' as side effect - */ - xev_track_handle_cursor(dpy); - - if (pending_redraw.valid()) - flush(pending_redraw.x(), pending_redraw.y(), - pending_redraw.w(), pending_redraw.h(), fb_mode); - - timer.msleep(5); - } - return 0; -} diff --git a/repos/os/src/app/xvfb/target.mk b/repos/os/src/app/xvfb/target.mk deleted file mode 100644 index 45e1c59d0..000000000 --- a/repos/os/src/app/xvfb/target.mk +++ /dev/null @@ -1,6 +0,0 @@ -TARGET = xvfb -REQUIRES = linux x11 xtest xdamage -SRC_CC = main.cc inject_input.cc -LIBS = lx_hybrid syscall-linux blit xev_track config - -EXT_OBJECTS += -lX11 -lXdamage /usr/lib/libXtst.so.6 diff --git a/repos/os/src/lib/xev_track/xev_track.cc b/repos/os/src/lib/xev_track/xev_track.cc deleted file mode 100644 index a9ab2b6d0..000000000 --- a/repos/os/src/lib/xev_track/xev_track.cc +++ /dev/null @@ -1,529 +0,0 @@ -/* - * \brief Window-event tracker for the X Window System - * \author Norman Feske - * \date 2009-11-04 - */ - -/* - * Copyright (C) 2009-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -/* Linux includes */ -#include -#include - -/* X11 includes */ -#include -#include - -/* xev includes */ -#include - - -struct View -{ - bool tracked; /* flag indicating that the view is in use */ - Window xwin; - Window above; - int x, y, w, h, border; - - /** - * Default constructor - * - * Make sure that the window is initially marked as free - */ - View() : tracked(false) { } -}; - - -static View views[MAX_VIEWS]; -static Window root; -static int xdamage_ev; -static Damage damage; - - -/*************** - ** Utilities ** - ***************/ - -/** - * Allocate view ID - * - * \return allocated view ID, or - * -1 if allocation failed - */ -static int alloc_view_id() -{ - int i; - for (i = 0; i < MAX_VIEWS; i++) - if (!views[i].tracked) break; - - if (i == MAX_VIEWS) - return -1; - - views[i].tracked = true; - return i; -} - - -/** - * Mark view ID as free - */ -static void release_view_id(int view_id) -{ - views[view_id].tracked = false; -} - - -/** - * Find view ID for a given X window ID - */ -static int find_view_id(Window xwin) -{ - /* search for window with matchin xwin id */ - for (int i = 0; i < MAX_VIEWS; i++) - if (views[i].xwin == xwin && views[i].tracked) - return i; - - return -1; -} - - -/** - * Create new window - * - * \param position -1 .. at top, - * -2 .. background, - * otherwise window id of the neighbor behind the new - * window - */ -static void assign_window(int view_id, Window xwin, Display *dpy, int position) -{ - /* sanity check */ - if (view_id < 0) return; - - View *view = &views[view_id]; - - view->xwin = xwin; - - /* request position and size of new window */ - XWindowAttributes attr; - XGetWindowAttributes(dpy, xwin, &attr); - view->x = attr.x; - view->y = attr.y; - view->w = attr.width; - view->h = attr.height; - view->border = attr.border_width; - - create_view(view_id); - - if (position == -2) { - stack_view(view_id, -1, false); - set_background_view(view_id); - } - - if (position == -1) - stack_view(view_id, -1, true); - - if (position >= 0) - stack_view(view_id, position, true); - - place_view(view_id, view->x, view->y, view->w + view->border*2, - view->h + view->border*2); -} - - -/** - * Scan all currently present windows - */ -static void scan_windows(Display *dpy, Window root) -{ - Window dummy_w1, dummy_w2, *win_list; - unsigned int num_wins; - XQueryTree(dpy, root, &dummy_w1, &dummy_w2, &win_list, &num_wins); - - for (unsigned i = 0; i < num_wins; i++) { - - XWindowAttributes attr; - XGetWindowAttributes(dpy, win_list[i], &attr); - - if (attr.map_state != IsViewable) - continue; - - int view_id = alloc_view_id(); - if (view_id >= 0) - assign_window(view_id, win_list[i], dpy, -1); - } - XFree(win_list); - - /* listen at the root window */ - XSelectInput(dpy, root, SubstructureNotifyMask | PointerMotionMask); -} - - -/** - * Find view belonging to the window in front of the specified X window - * - * \return view ID, or - * -1 if no matching view exists - */ -static int find_view_in_front(Display *dpy, Window root, Window win) -{ - Window dummy_w1, dummy_w2, *win_list; - unsigned int num_wins, i; - - XQueryTree(dpy, root, &dummy_w1, &dummy_w2, &win_list, &num_wins); - - /* find window in X window stack */ - for (i = 0; i < num_wins; i++) - if (win_list[i] == win) - break; - - /* skip current window */ - i++; - - /* find and return view belonging to the X window */ - int curr; - for (; i < num_wins; i++) - if ((curr = find_view_id(win_list[i]))) - return curr; - - return -1; -} - - -static void get_pointer_pos(Display *dpy, int *mx, int *my) -{ - Window dummy_win; - int dummy_int; - unsigned dummy_uint; - XQueryPointer(dpy, root, &dummy_win, &dummy_win, - mx, my, &dummy_int, &dummy_int, &dummy_uint); -} - - -struct Mouse_cursor_tracker -{ - private: - - enum { CURSOR_WIDTH = 20, CURSOR_HEIGHT = 20 }; - int _x1, _y1, _x2, _y2; - bool _valid; - - public: - - Mouse_cursor_tracker() : _valid(false) { } - - void reset(int x, int y) - { - _x1 = x - CURSOR_WIDTH; - _y1 = y - CURSOR_HEIGHT; - _x2 = x + CURSOR_WIDTH; - _y2 = y + CURSOR_HEIGHT; - _valid = false; - } - - void track(int x, int y) - { - if (_x1 > x - CURSOR_WIDTH) _x1 = x - CURSOR_WIDTH; - if (_y1 > y - CURSOR_HEIGHT) _y1 = y - CURSOR_HEIGHT; - if (_x2 < x + CURSOR_WIDTH) _x2 = x + CURSOR_WIDTH; - if (_y2 < y + CURSOR_HEIGHT) _y2 = y + CURSOR_HEIGHT; - _valid = true; - } - - bool bounding_box(int *x, int *y, int *w, int *h) - { - *x = _x1; - *y = _y1; - *w = _x2 - _x1 + 1; - *h = _y2 - _y1 + 1; - return _valid; - } -}; - -struct Mouse_cursor_tracker mouse_cursor_tracker; - - -/**************************** - ** Top-window enforcement ** - ****************************/ - -/* - * Some window managers do not raise a window that is already on top. This is - * bad because there may be overlay windows that are not known to the X window - * system but that cover the topmost X window. Thus, we want always to receive - * a top event. For this, we create a dedicated invisible window that stays - * always on top of all others. The topmost real X window is always the second. - * Therefore, the window manager thinks that this window can be topped and - * generates the desired event. - */ -static Window topwin; - - -static bool window_left_of_screen(Display *dpy, Window xwin) -{ - XWindowAttributes attr; - XGetWindowAttributes(dpy, xwin, &attr); - - return (attr.x + attr.width <= 0); -} - - -enum { - MAGIC_WIN_X = 2000, MAGIC_WIN_Y = 2000, - MAGIC_WIN_W = 1, MAGIC_WIN_H = 1 -}; - - -/** - * Create magic window that stays always on top - */ -static void create_magic_topwin(Display *dpy, Window root) -{ - XWindowChanges wincfg; - - /* create magic window that stays always on top */ - topwin = XCreateWindow(dpy, root, - MAGIC_WIN_X, MAGIC_WIN_Y, /* position */ - MAGIC_WIN_W, MAGIC_WIN_H, /* size */ - 0, /* border */ - CopyFromParent, /* depth */ - InputOutput, /* class */ - CopyFromParent, /* visual */ - 0, 0); - - wincfg.x = MAGIC_WIN_X; - wincfg.y = MAGIC_WIN_Y; - XConfigureWindow(dpy, topwin, CWX | CWY , &wincfg); - XMapWindow(dpy, topwin); - wincfg.x = MAGIC_WIN_X; - wincfg.y = MAGIC_WIN_Y; - XConfigureWindow(dpy, topwin, CWX | CWY , &wincfg); - - - int view_id = alloc_view_id(); - if (view_id >= 0) - assign_window(view_id, topwin, dpy, root); -} - - -/** - * Bring magic window in front of all others - */ -static void raise_magic_window(Display *dpy) -{ - XRaiseWindow(dpy, topwin); - - /* - * Some window managers tend to relocate existing windows on startup. So - * let's re-position the window to make sure that it remains invisible in - * such cases. - */ - XMoveWindow(dpy, topwin, -200, -200); -} - - -/********************** - ** X event handling ** - **********************/ - -static void handle_xwindow_event(Display *dpy, Window root, XEvent &ev) -{ - int view_id, behind_id; - int x, y, w, h; - View *view; - - switch (ev.type) { - - case MotionNotify: - - x = ev.xmotion.x_root; - y = ev.xmotion.y_root; - mouse_cursor_tracker.track(x, y); - break; - - case ConfigureNotify: - - if ((view_id = find_view_id(ev.xconfigure.window)) < 0) - break; - - x = ev.xconfigure.x; - y = ev.xconfigure.y; - w = ev.xconfigure.width; - h = ev.xconfigure.height; - - view = &views[view_id]; - - /* - * If window position and size keeps the same, - * we assume, the window has been topped. - */ - if (x == view->x && y == view->y && w == view->w && h == view->h) { - - int behind_id = find_view_in_front(dpy, root, ev.xconfigure.window); - - stack_view(view_id, behind_id, true); - - if (!window_left_of_screen(dpy, ev.xconfigure.window) && config_force_top) - raise_magic_window(dpy); - - } else { - - /* keep track new window position */ - view->x = x; view->y = y; view->w = w; view->h = h; - - place_view(view_id, x, y, w + view->border*2, h + view->border*2); - } - break; - - case Expose: - - if ((view_id = find_view_id(ev.xconfigure.window)) < 0) - break; - - stack_view(view_id, -1, true); - break; - - case UnmapNotify: - - if ((view_id = find_view_id(ev.xconfigure.window)) < 0) - break; - - /* avoid destroying a view twice */ - if (!views[view_id].tracked) - break; - - destroy_view(view_id); - release_view_id(view_id); - break; - - case MapNotify: - - if ((view_id = find_view_id(ev.xconfigure.window)) >= 0) { - printf("MapRequest: window already present - view ID %d\n", view_id); - break; - } - - behind_id = find_view_in_front(dpy, root, ev.xconfigure.window); - - /* - * Idea: Call XQueryTree to obtain the position where the new - * window is located in the window stack. - * - */ - - view_id = alloc_view_id(); - if (view_id >= 0) - assign_window(view_id, ev.xconfigure.window, dpy, behind_id); - - if (!window_left_of_screen(dpy, ev.xconfigure.window) && config_force_top) - raise_magic_window(dpy); - break; - } -} - - -static void handle_xdamage_event(Display *dpy, XEvent &ev) -{ - if (ev.type != XDamageNotify + xdamage_ev) - return; - - static XserverRegion region = XFixesCreateRegion (dpy, 0, 0); - static XserverRegion part = XFixesCreateRegion (dpy, 0, 0); - - XDamageNotifyEvent *dev = (XDamageNotifyEvent *)&ev; - - XFixesSetRegion(dpy, part, &dev->area, 1); - XFixesUnionRegion(dpy, region, region, part); - XFlush(dpy); - - XRectangle *rects; - int nrects; - - nrects = 0; - rects = XFixesFetchRegion (dpy, region, &nrects); - - for (int i = 0; i < nrects; i++) - refresh(rects[i].x, rects[i].y, rects[i].width, rects[i].height); - - /* clear collected damage region from damage */ - XDamageSubtract (dpy, damage, region, None); - - /* empty collected region */ - XFixesSetRegion (dpy, region, 0, 0); -} - - -/** - * Error handler that is called on xlib errors - */ -static int x_error_handler(Display *dpy, XErrorEvent *r) -{ - printf("Error: x_error_handler called\n"); - return 0; -} - - -/********************** - ** Public interface ** - **********************/ - -void xev_track_handle_event(Display *dpy, XEvent &ev) -{ - handle_xwindow_event(dpy, root, ev); - handle_xdamage_event(dpy, ev); -} - - -void xev_track_handle_cursor(Display *dpy) -{ - int x = 0, y = 0, w = 0, h = 0; - static int old_mx, old_my; - int new_mx, new_my; - - get_pointer_pos(dpy, &new_mx, &new_my); - if (new_mx != old_mx || new_my != old_my) - mouse_cursor_tracker.track(new_mx, new_my); - - if (mouse_cursor_tracker.bounding_box(&x, &y, &w, &h)) - refresh(x, y, w, h); - - mouse_cursor_tracker.reset(old_mx, old_my); - mouse_cursor_tracker.track(new_mx, new_my); - - old_mx = new_mx, old_my = new_my; -} - - -bool xev_track_init(Display *dpy) -{ - XSetErrorHandler(x_error_handler); - - int screen = DefaultScreen(dpy); - root = RootWindow(dpy, screen); - - int error; - if (!XDamageQueryExtension (dpy, &xdamage_ev, &error)) { - printf("Error: Could not query Xdamage extension\n"); - return false; - } - - damage = XDamageCreate(dpy, root, XDamageReportBoundingBox); - - if (config_force_top) - create_magic_topwin(dpy, root); - - /* create background view */ - int bg_view_id = alloc_view_id(); - if (bg_view_id >= 0) - assign_window(bg_view_id, root, dpy, -2); - - /* retrieve information about currently present windows */ - scan_windows(dpy, root); - - return true; -} diff --git a/repos/os/src/test/xev_track/main.cc b/repos/os/src/test/xev_track/main.cc deleted file mode 100644 index 509b29b66..000000000 --- a/repos/os/src/test/xev_track/main.cc +++ /dev/null @@ -1,97 +0,0 @@ -/* - * \brief Test for X event tracker, dumping X11 events - * \author Norman Feske - * \date 2010-02-11 - */ - -/* - * Copyright (C) 2010-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -/* X11 includes */ -#include -#include - -/* X event-tracker includes */ -#include - -/* standard includes */ -#include - - -/***************************** - ** configuration variables ** - *****************************/ - -int config_force_top = 1; /* evaluated by the X event-tracker library */ - -static int config_dump_refresh = false; - - - -/******************************* - ** X event-tracker callbacks ** - *******************************/ - -void create_view(int view_id) { - printf("create_view(view_id=%d)\n", view_id); } - - -void destroy_view(int view_id) { - printf("destroy_view(view_id=%d)\n", view_id); } - - -void set_background_view(int view_id) { - printf("set_background_view(view_id=%d)\n", view_id); } - - -void place_view(int view_id, int x, int y, int w, int h) { - printf("place_view(view_id=%d, x=%d, y=%d, w=%d, h=%d)\n", - view_id, x, y, w, h); } - - -void stack_view(int view_id, int neighbor_id, bool behind) { - printf("stack_view(view_id=%d, neighbor_id=%d, behind=%d)\n", - view_id, neighbor_id, behind); } - - -void refresh(int x, int y, int w, int h) { - if (config_dump_refresh) - printf("refresh(x=%d, y=%d, w=%d, h=%d)\n", x, y, w, h); } - - -/** - * Main program - */ -int main() -{ - /* create connection to the X server */ - Display *dpy = XOpenDisplay(":0"); - if (!dpy) { - printf("Error: Cannot open display\n"); - return -4; - } - - /* init event tracker library */ - if (!xev_track_init(dpy)) - return -6; - - /* busy loop polls X events */ - for (;;) { - XEvent ev; - XNextEvent(dpy, &ev); - - /* - * By calling this function, the callbacks defined above are - * triggered. - */ - xev_track_handle_event(dpy, ev); - xev_track_handle_cursor(dpy); - } - - return 0; -} - diff --git a/repos/os/src/test/xev_track/target.mk b/repos/os/src/test/xev_track/target.mk deleted file mode 100644 index e0a3500c4..000000000 --- a/repos/os/src/test/xev_track/target.mk +++ /dev/null @@ -1,6 +0,0 @@ -TARGET = test-xev_track -REQUIRES = host x11 xtest xdamage -SRC_CC = main.cc -LIBS = xev_track - -EXT_OBJECTS += -lX11 -lXdamage /usr/lib/libXtst.so.6