Browse Source

tinyXGraphicsStuff depend on x11display

rdb 16 years ago
parent
commit
905cd3ad69

+ 0 - 35
panda/src/tinydisplay/config_tinydisplay.cxx

@@ -37,41 +37,6 @@ ConfigureFn(config_tinydisplay) {
   init_libtinydisplay();
 }
 
-ConfigVariableString display_cfg
-("display", "",
- PRC_DESC("Specify the X display string for the default display.  If this "
-          "is not specified, $DISPLAY is used."));
-
-ConfigVariableBool x_error_abort
-("x-error-abort", false,
- PRC_DESC("Set this true to trigger and abort (and a stack trace) on receipt "
-          "of an error from the X window system.  This can make it easier "
-          "to discover where these errors are generated."));
-
-ConfigVariableInt x_wheel_up_button
-("x-wheel-up-button", 4,
- PRC_DESC("This is the mouse button index of the wheel_up event: which "
-          "mouse button number does the system report when the mouse wheel "
-          "is rolled one notch up?"));
-
-ConfigVariableInt x_wheel_down_button
-("x-wheel-down-button", 5,
- PRC_DESC("This is the mouse button index of the wheel_down event: which "
-          "mouse button number does the system report when the mouse wheel "
-          "is rolled one notch down?"));
-
-ConfigVariableInt x_wheel_left_button
-("x-wheel-left-button", 6,
- PRC_DESC("This is the mouse button index of the wheel_left event: which "
-          "mouse button number does the system report when one scrolls "
-          "to the left?"));
-
-ConfigVariableInt x_wheel_right_button
-("x-wheel-right-button", 7,
- PRC_DESC("This is the mouse button index of the wheel_right event: which "
-          "mouse button number does the system report when one scrolls "
-          "to the right?"));
-
 ConfigVariableBool show_resize_box
 ("show-resize-box", true,
  PRC_DESC("When this variable is true, then resizable OSX Panda windows will "

+ 0 - 7
panda/src/tinydisplay/config_tinydisplay.h

@@ -26,13 +26,6 @@ NotifyCategoryDecl(tinydisplay, EXPCL_TINYDISPLAY, EXPTP_TINYDISPLAY);
 extern EXPCL_TINYDISPLAY void init_libtinydisplay();
 extern "C" EXPCL_TINYDISPLAY int get_pipe_type_tinydisplay();
 
-extern ConfigVariableString display_cfg;
-extern ConfigVariableBool x_error_abort;
-extern ConfigVariableInt x_wheel_up_button;
-extern ConfigVariableInt x_wheel_down_button;
-extern ConfigVariableInt x_wheel_left_button;
-extern ConfigVariableInt x_wheel_right_button;
-
 extern ConfigVariableBool show_resize_box;
 extern ConfigVariableBool osx_disable_event_loop;
 extern ConfigVariableInt osx_mouse_wheel_scale;

+ 0 - 58
panda/src/tinydisplay/tinyXGraphicsPipe.I

@@ -12,61 +12,3 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsPipe::get_display
-//       Access: Public
-//  Description: Returns a pointer to the X display associated with
-//               the pipe: the display on which to create the windows.
-////////////////////////////////////////////////////////////////////
-INLINE Display *TinyXGraphicsPipe::
-get_display() const {
-  return _display;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsPipe::get_screen
-//       Access: Public
-//  Description: Returns the X screen number associated with the pipe.
-////////////////////////////////////////////////////////////////////
-INLINE int TinyXGraphicsPipe::
-get_screen() const {
-  return _screen;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsPipe::get_root
-//       Access: Public
-//  Description: Returns the handle to the root window on the pipe's
-//               display.
-////////////////////////////////////////////////////////////////////
-INLINE Window TinyXGraphicsPipe::
-get_root() const {
-  return _root;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsPipe::get_im
-//       Access: Public
-//  Description: Returns the input method opened for the pipe, or NULL
-//               if the input method could not be opened for some
-//               reason.
-////////////////////////////////////////////////////////////////////
-INLINE XIM TinyXGraphicsPipe::
-get_im() const {
-  return _im;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsPipe::get_hidden_cursor
-//       Access: Public
-//  Description: Returns an invisible Cursor suitable for assigning to
-//               windows that have the cursor_hidden property set.
-////////////////////////////////////////////////////////////////////
-INLINE Cursor TinyXGraphicsPipe::
-get_hidden_cursor() {
-  if (_hidden_cursor == None) {
-    make_hidden_cursor();
-  }
-  return _hidden_cursor;
-}

+ 1 - 219
panda/src/tinydisplay/tinyXGraphicsPipe.cxx

@@ -24,100 +24,13 @@
 
 TypeHandle TinyXGraphicsPipe::_type_handle;
 
-bool TinyXGraphicsPipe::_error_handlers_installed = false;
-TinyXGraphicsPipe::ErrorHandlerFunc *TinyXGraphicsPipe::_prev_error_handler;
-TinyXGraphicsPipe::IOErrorHandlerFunc *TinyXGraphicsPipe::_prev_io_error_handler;
-
-LightReMutex TinyXGraphicsPipe::_x_mutex;
-
 ////////////////////////////////////////////////////////////////////
 //     Function: TinyXGraphicsPipe::Constructor
 //       Access: Public
 //  Description: 
 ////////////////////////////////////////////////////////////////////
 TinyXGraphicsPipe::
-TinyXGraphicsPipe(const string &display) {
-  string display_spec = display;
-  if (display_spec.empty()) {
-    display_spec = display_cfg;
-  }
-  if (display_spec.empty()) {
-    display_spec = ExecutionEnvironment::get_environment_variable("DISPLAY");
-  }
-  if (display_spec.empty()) {
-    display_spec = ":0.0";
-  }
-
-  // The X docs say we should do this to get international character
-  // support from the keyboard.
-  setlocale(LC_ALL, "");
-
-  // But it's important that we use the "C" locale for numeric
-  // formatting, since all of the internal Panda code assumes this--we
-  // need a decimal point to mean a decimal point.
-  setlocale(LC_NUMERIC, "C");
-
-  _is_valid = false;
-  _supported_types = OT_window | OT_buffer | OT_texture_buffer;
-  _display = NULL;
-  _screen = 0;
-  _root = (Window)NULL;
-  _im = (XIM)NULL;
-  _hidden_cursor = None;
-
-  install_error_handlers();
-
-  _display = XOpenDisplay(display_spec.c_str());
-  if (!_display) {
-    tinydisplay_cat.error()
-      << "Could not open display \"" << display_spec << "\".\n";
-    return;
-  }
-
-  if (!XSupportsLocale()) {
-    tinydisplay_cat.warning()
-      << "X does not support locale " << setlocale(LC_ALL, NULL) << "\n";
-  }
-  XSetLocaleModifiers("");
-
-  _screen = DefaultScreen(_display);
-  _root = RootWindow(_display, _screen);
-  _display_width = DisplayWidth(_display, _screen);
-  _display_height = DisplayHeight(_display, _screen);
-  _is_valid = true;
-
-  // Connect to an input method for supporting international text
-  // entry.
-  _im = XOpenIM(_display, NULL, NULL, NULL);
-  if (_im == (XIM)NULL) {
-    tinydisplay_cat.warning()
-      << "Couldn't open input method.\n";
-  }
-
-  // What styles does the current input method support?
-  /*
-  XIMStyles *im_supported_styles;
-  XGetIMValues(_im, XNQueryInputStyle, &im_supported_styles, NULL);
-
-  for (int i = 0; i < im_supported_styles->count_styles; i++) {
-    XIMStyle style = im_supported_styles->supported_styles[i];
-    cerr << "style " << i << ". " << hex << style << dec << "\n";
-  }
-
-  XFree(im_supported_styles);
-  */
-
-  // Get some X atom numbers.
-  _wm_delete_window = XInternAtom(_display, "WM_DELETE_WINDOW", false);
-  _net_wm_window_type = XInternAtom(_display, "_NET_WM_WINDOW_TYPE", false);
-  _net_wm_window_type_splash = XInternAtom(_display, "_NET_WM_WINDOW_TYPE_SPLASH", false);
-  _net_wm_window_type_fullscreen = XInternAtom(_display, "_NET_WM_WINDOW_TYPE_FULLSCREEN", false);
-  _net_wm_state = XInternAtom(_display, "_NET_WM_STATE", false);
-  _net_wm_state_fullscreen = XInternAtom(_display, "_NET_WM_STATE_FULLSCREEN", false);
-  _net_wm_state_above = XInternAtom(_display, "_NET_WM_STATE_ABOVE", false);
-  _net_wm_state_below = XInternAtom(_display, "_NET_WM_STATE_BELOW", false);
-  _net_wm_state_add = XInternAtom(_display, "_NET_WM_STATE_ADD", false);
-  _net_wm_state_remove = XInternAtom(_display, "_NET_WM_STATE_REMOVE", false);
+TinyXGraphicsPipe(const string &display) : x11GraphicsPipe(display) {
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -127,13 +40,6 @@ TinyXGraphicsPipe(const string &display) {
 ////////////////////////////////////////////////////////////////////
 TinyXGraphicsPipe::
 ~TinyXGraphicsPipe() {
-  release_hidden_cursor();
-  if (_im) {
-    XCloseIM(_im);
-  }
-  if (_display) {
-    XCloseDisplay(_display);
-  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -163,30 +69,6 @@ pipe_constructor() {
   return new TinyXGraphicsPipe;
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsPipe::get_preferred_window_thread
-//       Access: Public, Virtual
-//  Description: Returns an indication of the thread in which this
-//               GraphicsPipe requires its window processing to be
-//               performed: typically either the app thread (e.g. X)
-//               or the draw thread (Windows).
-////////////////////////////////////////////////////////////////////
-GraphicsPipe::PreferredWindowThread 
-TinyXGraphicsPipe::get_preferred_window_thread() const {
-  // Actually, since we're creating the graphics context in
-  // open_window() now, it appears we need to ensure the open_window()
-  // call is performed in the draw thread for now, even though X wants
-  // all of its calls to be single-threaded.
-
-  // This means that all X windows may have to be handled by the same
-  // draw thread, which we didn't intend (though the global _x_mutex
-  // may allow them to be technically served by different threads,
-  // even though the actual X calls will be serialized).  There might
-  // be a better way.
-
-  return PWT_draw;
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: TinyXGraphicsPipe::make_output
 //       Access: Protected, Virtual
@@ -242,104 +124,4 @@ make_output(const string &name,
   return NULL;
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsPipe::make_hidden_cursor
-//       Access: Private
-//  Description: Called once to make an invisible Cursor for return
-//               from get_hidden_cursor().
-////////////////////////////////////////////////////////////////////
-void TinyXGraphicsPipe::
-make_hidden_cursor() {
-  nassertv(_hidden_cursor == None);
-
-  unsigned int x_size, y_size;
-  XQueryBestCursor(_display, _root, 1, 1, &x_size, &y_size);
-
-  Pixmap empty = XCreatePixmap(_display, _root, x_size, y_size, 1);
-
-  XColor black;
-  memset(&black, 0, sizeof(black));
-
-  _hidden_cursor = XCreatePixmapCursor(_display, empty, empty, 
-                                       &black, &black, x_size, y_size);
-  XFreePixmap(_display, empty);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsPipe::release_hidden_cursor
-//       Access: Private
-//  Description: Called once to release the invisible cursor created
-//               by make_hidden_cursor().
-////////////////////////////////////////////////////////////////////
-void TinyXGraphicsPipe::
-release_hidden_cursor() {
-  if (_hidden_cursor != None) {
-    XFreeCursor(_display, _hidden_cursor);
-    _hidden_cursor = None;
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsPipe::install_error_handlers
-//       Access: Private, Static
-//  Description: Installs new Xlib error handler functions if this is
-//               the first time this function has been called.  These
-//               error handler functions will attempt to reduce Xlib's
-//               annoying tendency to shut down the client at the
-//               first error.  Unfortunately, it is difficult to play
-//               nice with the client if it has already installed its
-//               own error handlers.
-////////////////////////////////////////////////////////////////////
-void TinyXGraphicsPipe::
-install_error_handlers() {
-  if (_error_handlers_installed) {
-    return;
-  }
-
-  _prev_error_handler = (ErrorHandlerFunc *)XSetErrorHandler(error_handler);
-  _prev_io_error_handler = (IOErrorHandlerFunc *)XSetIOErrorHandler(io_error_handler);
-  _error_handlers_installed = true;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsPipe::error_handler
-//       Access: Private, Static
-//  Description: This function is installed as the error handler for a
-//               non-fatal Xlib error.
-////////////////////////////////////////////////////////////////////
-int TinyXGraphicsPipe::
-error_handler(Display *display, XErrorEvent *error) {
-  static const int msg_len = 80;
-  char msg[msg_len];
-  XGetErrorText(display, error->error_code, msg, msg_len);
-  tinydisplay_cat.error()
-    << msg << "\n";
-
-  if (x_error_abort) {
-    abort();
-  }
-
-  // We return to allow the application to continue running, unlike
-  // the default X error handler which exits.
-  return 0;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsPipe::io_error_handler
-//       Access: Private, Static
-//  Description: This function is installed as the error handler for a
-//               fatal Xlib error.
-////////////////////////////////////////////////////////////////////
-int TinyXGraphicsPipe::
-io_error_handler(Display *display) {
-  tinydisplay_cat.fatal()
-    << "X fatal error on display " << (void *)display << "\n";
-
-  // Unfortunately, we can't continue from this function, even if we
-  // promise never to use X again.  We're supposed to terminate
-  // without returning, and if we do return, the caller will exit
-  // anyway.  Sigh.  Very poor design on X's part.
-  return 0;
-}
-
 #endif  // HAVE_X11

+ 5 - 72
panda/src/tinydisplay/tinyXGraphicsPipe.h

@@ -19,37 +19,19 @@
 
 #ifdef HAVE_X11
 
-#include "graphicsWindow.h"
-#include "graphicsPipe.h"
+#include "x11GraphicsWindow.h"
+#include "x11GraphicsPipe.h"
 #include "tinyGraphicsStateGuardian.h"
 #include "lightMutex.h"
 #include "lightReMutex.h"
 
-class FrameBufferProperties;
-
-#ifdef CPPPARSER
-// A simple hack so interrogate can parse this file.
-typedef int Display;
-typedef int Window;
-typedef int XErrorEvent;
-typedef int XVisualInfo;
-typedef int Atom;
-typedef int Cursor;
-typedef int XIM;
-typedef int XIC;
-#else
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-#endif  // CPPPARSER
-
 ////////////////////////////////////////////////////////////////////
 //       Class : TinyXGraphicsPipe
 // Description : This graphics pipe represents the interface for
 //               creating TinyPanda graphics windows on an X11-based
 //               (e.g. Unix) client.
 ////////////////////////////////////////////////////////////////////
-class EXPCL_TINYDISPLAY TinyXGraphicsPipe : public GraphicsPipe {
+class EXPCL_TINYDISPLAY TinyXGraphicsPipe : public x11GraphicsPipe {
 public:
   TinyXGraphicsPipe(const string &display = string());
   virtual ~TinyXGraphicsPipe();
@@ -57,29 +39,6 @@ public:
   virtual string get_interface_name() const;
   static PT(GraphicsPipe) pipe_constructor();
 
-  INLINE Display *get_display() const;
-  INLINE int get_screen() const;
-  INLINE Window get_root() const;
-  INLINE XIM get_im() const;
-
-  INLINE Cursor get_hidden_cursor();
-
-public:
-  virtual PreferredWindowThread get_preferred_window_thread() const;
-
-public:
-  // Atom specifications.
-  Atom _wm_delete_window;
-  Atom _net_wm_window_type;
-  Atom _net_wm_window_type_splash;
-  Atom _net_wm_window_type_fullscreen;
-  Atom _net_wm_state;
-  Atom _net_wm_state_fullscreen;
-  Atom _net_wm_state_above;
-  Atom _net_wm_state_below;
-  Atom _net_wm_state_add;
-  Atom _net_wm_state_remove;
-
 protected:
   virtual PT(GraphicsOutput) make_output(const string &name,
                                          const FrameBufferProperties &fb_prop,
@@ -91,40 +50,14 @@ protected:
                                          int retry,
                                          bool &precertify);
 
-private:
-  void make_hidden_cursor();
-  void release_hidden_cursor();
-
-  static void install_error_handlers();
-  static int error_handler(Display *display, XErrorEvent *error);
-  static int io_error_handler(Display *display);
-
-  Display *_display;
-  int _screen;
-  Window _root;
-  XIM _im;
-
-  Cursor _hidden_cursor;
-
-  typedef int ErrorHandlerFunc(Display *, XErrorEvent *);
-  typedef int IOErrorHandlerFunc(Display *);
-  static bool _error_handlers_installed;
-  static ErrorHandlerFunc *_prev_error_handler;
-  static IOErrorHandlerFunc *_prev_io_error_handler;
-
-public:
-  // This Mutex protects any X library calls, which all have to be
-  // single-threaded.
-  static LightReMutex _x_mutex;
-
 public:
   static TypeHandle get_class_type() {
     return _type_handle;
   }
   static void init_type() {
-    GraphicsPipe::init_type();
+    x11GraphicsPipe::init_type();
     register_type(_type_handle, "TinyXGraphicsPipe",
-                  GraphicsPipe::get_class_type());
+                  x11GraphicsPipe::get_class_type());
   }
   virtual TypeHandle get_type() const {
     return get_class_type();

+ 8 - 1149
panda/src/tinydisplay/tinyXGraphicsWindow.cxx

@@ -30,20 +30,8 @@
 #include "throw_event.h"
 #include "lightReMutexHolder.h"
 
-#include <errno.h>
-#include <sys/time.h>
-#include <X11/keysym.h>
-#include <X11/Xutil.h>
-#include <X11/Xatom.h>
-
-#ifdef HAVE_LINUX_INPUT_H
-#include <linux/input.h>
-#endif
-
 TypeHandle TinyXGraphicsWindow::_type_handle;
 
-#define test_bit(bit, array) ((array)[(bit)/8] & (1<<((bit)&7)))
-
 ////////////////////////////////////////////////////////////////////
 //     Function: TinyXGraphicsWindow::Constructor
 //       Access: Public
@@ -57,35 +45,14 @@ TinyXGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
                     int flags,
                     GraphicsStateGuardian *gsg,
                     GraphicsOutput *host) :
-  GraphicsWindow(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
+  x11GraphicsWindow(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
 {
-  TinyXGraphicsPipe *tinyx_pipe;
-  DCAST_INTO_V(tinyx_pipe, _pipe);
-  _display = tinyx_pipe->get_display();
-  _screen = tinyx_pipe->get_screen();
-  _xwindow = (Window)NULL;
   _gc = (GC)NULL;
-  _ic = (XIC)NULL;
-  _awaiting_configure = false;
-  _wm_delete_window = tinyx_pipe->_wm_delete_window;
-  _net_wm_window_type = tinyx_pipe->_net_wm_window_type;
-  _net_wm_window_type_splash = tinyx_pipe->_net_wm_window_type_splash;
-  _net_wm_window_type_fullscreen = tinyx_pipe->_net_wm_window_type_fullscreen;
-  _net_wm_state = tinyx_pipe->_net_wm_state;
-  _net_wm_state_fullscreen = tinyx_pipe->_net_wm_state_fullscreen;
-  _net_wm_state_above = tinyx_pipe->_net_wm_state_above;
-  _net_wm_state_below = tinyx_pipe->_net_wm_state_below;
-  _net_wm_state_add = tinyx_pipe->_net_wm_state_add;
-  _net_wm_state_remove = tinyx_pipe->_net_wm_state_remove;
 
   _reduced_frame_buffer = NULL;
   _full_frame_buffer = NULL;
   _ximage = NULL;
   update_pixel_factor();
-
-  GraphicsWindowInputDevice device =
-    GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard_mouse");
-  add_input_device(device);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -95,48 +62,14 @@ TinyXGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
 ////////////////////////////////////////////////////////////////////
 TinyXGraphicsWindow::
 ~TinyXGraphicsWindow() {
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsWindow::move_pointer
-//       Access: Published, Virtual
-//  Description: Forces the pointer to the indicated position within
-//               the window, if possible.  
-//
-//               Returns true if successful, false on failure.  This
-//               may fail if the mouse is not currently within the
-//               window, or if the API doesn't support this operation.
-////////////////////////////////////////////////////////////////////
-bool TinyXGraphicsWindow::
-move_pointer(int device, int x, int y) {
-  // Note: this is not thread-safe; it should be called only from App.
-  // Probably not an issue.
-  if (device == 0) {
-    // Move the system mouse pointer.
-    if (!_properties.get_foreground() ||
-        !_input_devices[0].get_pointer().get_in_window()) {
-      // If the window doesn't have input focus, or the mouse isn't
-      // currently within the window, forget it.
-      return false;
-    }
-
-    const MouseData &md = _input_devices[0].get_pointer();
-    if (!md.get_in_window() || md.get_x() != x || md.get_y() != y) {
-      XWarpPointer(_display, None, _xwindow, 0, 0, 0, 0, x, y);
-      _input_devices[0].set_pointer_in_window(x, y);
-    }
-    return true;
-  } else {
-    // Move a raw mouse.
-    if ((device < 1)||(device >= _input_devices.size())) {
-      return false;
-    }
-    _input_devices[device].set_pointer_in_window(x, y);
-    return true;
+  if (_gc != NULL && _display != NULL) {
+    XFreeGC(_display, _gc);
+  }
+  if (_ximage != NULL) {
+    XDestroyImage(_ximage);
   }
 }
 
-
 ////////////////////////////////////////////////////////////////////
 //     Function: TinyXGraphicsWindow::begin_frame
 //       Access: Public, Virtual
@@ -464,145 +397,6 @@ process_events() {
   }
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsWindow::set_properties_now
-//       Access: Public, Virtual
-//  Description: Applies the requested set of properties to the
-//               window, if possible, for instance to request a change
-//               in size or minimization status.
-//
-//               The window properties are applied immediately, rather
-//               than waiting until the next frame.  This implies that
-//               this method may *only* be called from within the
-//               window thread.
-//
-//               The return value is true if the properties are set,
-//               false if they are ignored.  This is mainly useful for
-//               derived classes to implement extensions to this
-//               function.
-////////////////////////////////////////////////////////////////////
-void TinyXGraphicsWindow::
-set_properties_now(WindowProperties &properties) {
-  if (_pipe == (GraphicsPipe *)NULL) {
-    // If the pipe is null, we're probably closing down.
-    GraphicsWindow::set_properties_now(properties);
-    return;
-  }
-
-  TinyXGraphicsPipe *tinyx_pipe;
-  DCAST_INTO_V(tinyx_pipe, _pipe);
-
-  // Fullscreen mode is implemented with a hint to the window manager.
-  // However, we also implicitly set the origin to (0, 0) and the size
-  // to the desktop size, and request undecorated mode, in case the
-  // user has a less-capable window manager (or no window manager at
-  // all).
-  if (properties.get_fullscreen()) {
-    properties.set_undecorated(true);
-    properties.set_origin(0, 0);
-    properties.set_size(tinyx_pipe->get_display_width(),
-                        tinyx_pipe->get_display_height());
-  }
-
-  GraphicsWindow::set_properties_now(properties);
-  if (!properties.is_any_specified()) {
-    // The base class has already handled this case.
-    return;
-  }
-
-  // The window is already open; we are limited to what we can change
-  // on the fly.
-
-  // We'll pass some property requests on as a window manager hint.
-  WindowProperties wm_properties = _properties;
-  wm_properties.add_properties(properties);
-
-  // The window title may be changed by issuing another hint request.
-  // Assume this will be honored.
-  if (properties.has_title()) {
-    _properties.set_title(properties.get_title());
-    properties.clear_title();
-  }
-
-  // Ditto for fullscreen mode.
-  if (properties.has_fullscreen()) {
-    _properties.set_fullscreen(properties.get_fullscreen());
-    properties.clear_fullscreen();
-  }
-
-  // The size and position of an already-open window are changed via
-  // explicit X calls.  These may still get intercepted by the window
-  // manager.  Rather than changing _properties immediately, we'll
-  // wait for the ConfigureNotify message to come back.
-  XWindowChanges changes;
-  int value_mask = 0;
-
-  if (properties.has_origin()) {
-    changes.x = properties.get_x_origin();
-    changes.y = properties.get_y_origin();
-    value_mask |= (CWX | CWY);
-    properties.clear_origin();
-  }
-  if (properties.has_size()) {
-    changes.width = properties.get_x_size();
-    changes.height = properties.get_y_size();
-    value_mask |= (CWWidth | CWHeight);
-    properties.clear_size();
-  }
-  if (properties.has_z_order()) {
-    // We'll send the classic stacking request through the standard
-    // interface, for users of primitive window managers; but we'll
-    // also send it as a window manager hint, for users of modern
-    // window managers.
-    _properties.set_z_order(properties.get_z_order());
-    switch (properties.get_z_order()) {
-    case WindowProperties::Z_bottom:
-      changes.stack_mode = Below;
-      break;
-
-    case WindowProperties::Z_normal:
-      changes.stack_mode = TopIf;
-      break;
-
-    case WindowProperties::Z_top:
-      changes.stack_mode = Above;
-      break;
-    }
-
-    value_mask |= (CWStackMode);
-    properties.clear_z_order();
-  }
-
-  if (value_mask != 0) {
-    XReconfigureWMWindow(_display, _xwindow, _screen, value_mask, &changes);
-
-    // Don't draw anything until this is done reconfiguring.
-    _awaiting_configure = true;
-  }
-
-  // We hide the cursor by setting it to an invisible pixmap.
-  if (properties.has_cursor_hidden()) {
-    _properties.set_cursor_hidden(properties.get_cursor_hidden());
-    if (properties.get_cursor_hidden()) {
-      XDefineCursor(_display, _xwindow, tinyx_pipe->get_hidden_cursor());
-    } else {
-      XDefineCursor(_display, _xwindow, None);
-    }
-    properties.clear_cursor_hidden();
-  }
-
-  if (properties.has_foreground()) {
-    if (properties.get_foreground()) {
-      XSetInputFocus(_display, _xwindow, RevertToPointerRoot, CurrentTime);
-    } else {
-      XSetInputFocus(_display, PointerRoot, RevertToPointerRoot, CurrentTime);
-    }
-    properties.clear_foreground();
-  }
-
-  set_wm_properties(wm_properties, true);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: TinyXGraphicsWindow::close_window
 //       Access: Protected, Virtual
@@ -619,25 +413,7 @@ close_window() {
     _active = false;
   }
   
-  if (_ic != (XIC)NULL) {
-    XDestroyIC(_ic);
-    _ic = (XIC)NULL;
-  }
-
-  if (_gc != (GC)NULL) {
-    XFreeGC(_display, _gc);
-    _gc = (GC)NULL;
-  }
-
-  if (_xwindow != (Window)NULL) {
-    XDestroyWindow(_display, _xwindow);
-    _xwindow = (Window)NULL;
-
-    // This may be necessary if we just closed the last X window in an
-    // application, so the server hears the close request.
-    XFlush(_display);
-  }
-  GraphicsWindow::close_window();
+  x11GraphicsWindow::close_window();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -836,927 +612,10 @@ open_window() {
 ////////////////////////////////////////////////////////////////////
 void TinyXGraphicsWindow::
 pixel_factor_changed() {
-  GraphicsWindow::pixel_factor_changed();
+  x11GraphicsWindow::pixel_factor_changed();
   create_reduced_frame_buffer();
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsWindow::set_wm_properties
-//       Access: Private
-//  Description: Asks the window manager to set the appropriate
-//               properties.  In X, these properties cannot be
-//               specified directly by the application; they must be
-//               requested via the window manager, which may or may
-//               not choose to honor the request.
-//
-//               If already_mapped is true, the window has already
-//               been mapped (manifested) on the display.  This means
-//               we may need to use a different action in some cases.
-////////////////////////////////////////////////////////////////////
-void TinyXGraphicsWindow::
-set_wm_properties(const WindowProperties &properties, bool already_mapped) {
-  // Name the window if there is a name
-  XTextProperty window_name;
-  XTextProperty *window_name_p = (XTextProperty *)NULL;
-  if (properties.has_title()) {
-    char *name = (char *)properties.get_title().c_str();
-    if (XStringListToTextProperty(&name, 1, &window_name) != 0) {
-      window_name_p = &window_name;
-    }
-  }
-
-  // The size hints request a window of a particular size and/or a
-  // particular placement onscreen.
-  XSizeHints *size_hints_p = NULL;
-  if (properties.has_origin() || properties.has_size()) {
-    size_hints_p = XAllocSizeHints();
-    if (size_hints_p != (XSizeHints *)NULL) {
-      if (properties.has_origin()) {
-        size_hints_p->x = properties.get_x_origin();
-        size_hints_p->y = properties.get_y_origin();
-        size_hints_p->flags |= USPosition;
-      }
-      if (properties.has_size()) {
-        size_hints_p->width = properties.get_x_size();
-        size_hints_p->height = properties.get_y_size();
-        size_hints_p->flags |= USSize;
-
-        if (properties.has_fixed_size()) {
-          size_hints_p->min_width = properties.get_x_size();
-          size_hints_p->min_height = properties.get_y_size();
-          size_hints_p->max_width = properties.get_x_size();
-          size_hints_p->max_height = properties.get_y_size();
-          size_hints_p->flags |= (PMinSize | PMaxSize);
-        }
-      }
-    }
-  }
-
-  // The window manager hints include requests to the window manager
-  // other than those specific to window geometry.
-  XWMHints *wm_hints_p = NULL;
-  wm_hints_p = XAllocWMHints();
-  if (wm_hints_p != (XWMHints *)NULL) {
-    if (properties.has_minimized() && properties.get_minimized()) {
-      wm_hints_p->initial_state = IconicState;
-    } else {
-      wm_hints_p->initial_state = NormalState;
-    }
-    wm_hints_p->flags = StateHint;
-  }
-
-  // Two competing window manager interfaces have evolved.  One of
-  // them allows to set certain properties as a "type"; the other one
-  // as a "state".  We'll try to honor both.
-  static const int max_type_data = 32;
-  PN_int32 type_data[max_type_data];
-  int next_type_data = 0;
-
-  static const int max_state_data = 32;
-  PN_int32 state_data[max_state_data];
-  int next_state_data = 0;
-
-  static const int max_set_data = 32;
-  class SetAction {
-  public:
-    inline SetAction() { }
-    inline SetAction(Atom state, Atom action) : _state(state), _action(action) { }
-    Atom _state;
-    Atom _action;
-  };
-  SetAction set_data[max_set_data];
-  int next_set_data = 0;
-
-  if (properties.get_fullscreen()) {
-    // For a "fullscreen" request, we pass this through, hoping the
-    // window manager will support EWMH.
-    type_data[next_type_data++] = _net_wm_window_type_fullscreen;
-
-    // We also request it as a state.
-    state_data[next_state_data++] = _net_wm_state_fullscreen;
-    set_data[next_set_data++] = SetAction(_net_wm_state_fullscreen, _net_wm_state_add);
-  } else {
-    set_data[next_set_data++] = SetAction(_net_wm_state_fullscreen, _net_wm_state_remove);
-  }
-
-  // If we asked for a window without a border, there's no excellent
-  // way to arrange that.  For users whose window managers follow the
-  // EWMH specification, we can ask for a "splash" screen, which is
-  // usually undecorated.  It's not exactly right, but the spec
-  // doesn't give us an exactly-right option.
-
-  // For other users, we'll totally punt and just set the window's
-  // Class to "Undecorated", and let the user configure his/her window
-  // manager not to put a border around windows of this class.
-  XClassHint *class_hints_p = NULL;
-  if (properties.get_undecorated()) {
-    class_hints_p = XAllocClassHint();
-    class_hints_p->res_class = (char *)"Undecorated";
-
-    if (!properties.get_fullscreen()) {
-      type_data[next_type_data++] = _net_wm_window_type_splash;
-    }
-  }
-
-  if (properties.has_z_order()) {
-    switch (properties.get_z_order()) {
-    case WindowProperties::Z_bottom:
-      state_data[next_state_data++] = _net_wm_state_below;
-      set_data[next_set_data++] = SetAction(_net_wm_state_below, _net_wm_state_add);
-      set_data[next_set_data++] = SetAction(_net_wm_state_above, _net_wm_state_remove);
-      break;
-
-    case WindowProperties::Z_normal:
-      set_data[next_set_data++] = SetAction(_net_wm_state_below, _net_wm_state_remove);
-      set_data[next_set_data++] = SetAction(_net_wm_state_above, _net_wm_state_remove);
-      break;
-
-    case WindowProperties::Z_top:
-      state_data[next_state_data++] = _net_wm_state_above;
-      set_data[next_set_data++] = SetAction(_net_wm_state_below, _net_wm_state_remove);
-      set_data[next_set_data++] = SetAction(_net_wm_state_above, _net_wm_state_add);
-      break;
-    }
-  }
-
-  nassertv(next_type_data < max_type_data);
-  nassertv(next_state_data < max_state_data);
-  nassertv(next_set_data < max_set_data);
-
-  XChangeProperty(_display, _xwindow, _net_wm_window_type,
-                  XA_ATOM, 32, PropModeReplace,
-                  (unsigned char *)type_data, next_type_data);
-
-  // Request the state properties all at once.
-  XChangeProperty(_display, _xwindow, _net_wm_state,
-                  XA_ATOM, 32, PropModeReplace,
-                  (unsigned char *)state_data, next_state_data);
-
-  if (already_mapped) {
-    // We have to request state changes differently when the window
-    // has been mapped.  To do this, we need to send a client message
-    // to the root window for each change.
-
-    TinyXGraphicsPipe *tinyx_pipe;
-    DCAST_INTO_V(tinyx_pipe, _pipe);
-  
-    for (int i = 0; i < next_set_data; ++i) {
-      XClientMessageEvent event;
-      memset(&event, 0, sizeof(event));
-
-      event.type = ClientMessage;
-      event.send_event = True;
-      event.display = _display;
-      event.window = _xwindow;
-      event.message_type = _net_wm_state;
-      event.format = 32;
-      event.data.l[0] = set_data[i]._action;
-      event.data.l[1] = set_data[i]._state;
-      event.data.l[2] = 0;
-      event.data.l[3] = 1;
-
-      XSendEvent(_display, tinyx_pipe->get_root(), True, 0, (XEvent *)&event);
-    }
-  }
-
-  XSetWMProperties(_display, _xwindow, window_name_p, window_name_p,
-                   NULL, 0, size_hints_p, wm_hints_p, class_hints_p);
-
-  if (size_hints_p != (XSizeHints *)NULL) {
-    XFree(size_hints_p);
-  }
-  if (wm_hints_p != (XWMHints *)NULL) {
-    XFree(wm_hints_p);
-  }
-  if (class_hints_p != (XClassHint *)NULL) {
-    XFree(class_hints_p);
-  }
-
-  // Also, indicate to the window manager that we'd like to get a
-  // chance to close our windows cleanly, rather than being rudely
-  // disconnected from the X server if the user requests a window
-  // close.
-  Atom protocols[] = {
-    _wm_delete_window,
-  };
-
-  XSetWMProtocols(_display, _xwindow, protocols, 
-                  sizeof(protocols) / sizeof(Atom));
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsWindow::setup_colormap
-//       Access: Private
-//  Description: Allocates a colormap appropriate to the visual and
-//               stores in in the _colormap method.
-////////////////////////////////////////////////////////////////////
-void TinyXGraphicsWindow::
-setup_colormap(XVisualInfo *visual_info) {
-  TinyXGraphicsPipe *tinyx_pipe;
-  DCAST_INTO_V(tinyx_pipe, _pipe);
-  Window root_window = tinyx_pipe->get_root();
-
-  int visual_class = visual_info->c_class;
-  int rc, is_rgb;
-
-  switch (visual_class) {
-    case TrueColor:
-    case DirectColor:
-      _colormap = XCreateColormap(_display, root_window,
-                                  visual_info->visual, AllocNone);
-      break;
-    case StaticColor:
-    case StaticGray:
-    case GrayScale:
-      _colormap = XCreateColormap(_display, root_window,
-                                  visual_info->visual, AllocNone);
-      break;
-
-    default:
-      tinydisplay_cat.error()
-        << "Could not allocate a colormap for visual class "
-        << visual_class << ".\n";
-      break;
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsWindow::open_raw_mice
-//       Access: Private
-//  Description: Adds raw mice to the _input_devices list.
-////////////////////////////////////////////////////////////////////
-void TinyXGraphicsWindow::
-open_raw_mice()
-{
-#ifdef HAVE_LINUX_INPUT_H
-  bool any_present = false;
-  bool any_mice = false;
-  
-  for (int i=0; i<64; i++) {
-    uint8_t evtypes[EV_MAX/8 + 1];
-    ostringstream fnb;
-    fnb << "/dev/input/event" << i;
-    string fn = fnb.str();
-    int fd = open(fn.c_str(), O_RDONLY | O_NONBLOCK, 0);
-    if (fd >= 0) {
-      any_present = true;
-      char name[256];
-      char phys[256];
-      char uniq[256];
-      if ((ioctl(fd, EVIOCGNAME(sizeof(name)), name) < 0)||
-          (ioctl(fd, EVIOCGPHYS(sizeof(phys)), phys) < 0)||
-          (ioctl(fd, EVIOCGPHYS(sizeof(uniq)), uniq) < 0)||
-          (ioctl(fd, EVIOCGBIT(0, EV_MAX), &evtypes) < 0)) {
-        close(fd);
-        tinydisplay_cat.error() <<
-          "Opening raw mice: ioctl failed on " << fn << "\n";
-      } else {
-        if (test_bit(EV_REL, evtypes) || test_bit(EV_ABS, evtypes)) {
-          for (char *p=name; *p; p++) {
-            if (((*p<'a')||(*p>'z')) && ((*p<'A')||(*p>'Z')) && ((*p<'0')||(*p>'9'))) {
-              *p = '_';
-            }
-          }
-          for (char *p=uniq; *p; p++) {
-            if (((*p<'a')||(*p>'z')) && ((*p<'A')||(*p>'Z')) && ((*p<'0')||(*p>'9'))) {
-              *p = '_';
-            }
-          }
-          string full_id = ((string)name) + "." + uniq;
-          MouseDeviceInfo inf;
-          inf._fd = fd;
-          inf._input_device_index = _input_devices.size();
-          inf._io_buffer = "";
-          _mouse_device_info.push_back(inf);
-          GraphicsWindowInputDevice device =
-            GraphicsWindowInputDevice::pointer_only(this, full_id);
-          add_input_device(device);
-          tinydisplay_cat.info() << "Raw mouse " <<
-            inf._input_device_index << " detected: " << full_id << "\n";
-          any_mice = true;
-        } else {
-          close(fd);
-        }
-      }
-    } else {
-      if ((errno == ENOENT)||(errno == ENOTDIR)) {
-        break;
-      } else {
-        any_present = true;
-        tinydisplay_cat.error() << 
-          "Opening raw mice: " << strerror(errno) << " " << fn << "\n";
-      }
-    }
-  }
-  
-  if (!any_present) {
-    tinydisplay_cat.error() << 
-      "Opening raw mice: files not found: /dev/input/event*\n";
-  } else if (!any_mice) {
-    tinydisplay_cat.error() << 
-      "Opening raw mice: no mouse devices detected in /dev/input/event*\n";
-  }
-#else
-  tinydisplay_cat.error() <<
-    "Opening raw mice: panda not compiled with raw mouse support.\n";
-#endif
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsWindow::poll_raw_mice
-//       Access: Private
-//  Description: Reads events from the raw mouse device files.
-////////////////////////////////////////////////////////////////////
-void TinyXGraphicsWindow::
-poll_raw_mice()
-{
-#ifdef HAVE_LINUX_INPUT_H
-  for (int dev=0; dev<_mouse_device_info.size(); dev++) {
-    MouseDeviceInfo &inf = _mouse_device_info[dev];
-
-    // Read all bytes into buffer.
-    if (inf._fd >= 0) {
-      while (1) {
-        char tbuf[1024];
-        int nread = read(inf._fd, tbuf, sizeof(tbuf));
-        if (nread > 0) {
-          inf._io_buffer += string(tbuf, nread);
-        } else {
-          if ((nread < 0)&&((errno == EWOULDBLOCK) || (errno==EAGAIN))) {
-            break;
-          }
-          close(inf._fd);
-          inf._fd = -1;
-          break;
-        }
-      }
-    }
-
-    // Process events.
-    int nevents = inf._io_buffer.size() / sizeof(struct input_event);
-    if (nevents == 0) {
-      continue;
-    }
-    const input_event *events = (const input_event *)(inf._io_buffer.c_str());
-    GraphicsWindowInputDevice &dev = _input_devices[inf._input_device_index];
-    int x = dev.get_raw_pointer().get_x();
-    int y = dev.get_raw_pointer().get_y();
-    for (int i=0; i<nevents; i++) {
-      if (events[i].type == EV_REL) {
-        if (events[i].code == REL_X) x += events[i].value;
-        if (events[i].code == REL_Y) y += events[i].value;
-      } else if (events[i].type == EV_ABS) {
-        if (events[i].code == ABS_X) x = events[i].value;
-        if (events[i].code == ABS_Y) y = events[i].value;
-      } else if (events[i].type == EV_KEY) {
-        if ((events[i].code >= BTN_MOUSE)&&(events[i].code < BTN_MOUSE+8)) {
-          int btn = events[i].code - BTN_MOUSE;
-          dev.set_pointer_in_window(x,y);
-          if (events[i].value) {
-            dev.button_down(MouseButton::button(btn));
-          } else {
-            dev.button_up(MouseButton::button(btn));
-          }
-        }
-      }
-    }
-    inf._io_buffer.erase(0,nevents*sizeof(struct input_event));
-    dev.set_pointer_in_window(x,y);
-  }
-#endif
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsWindow::handle_keystroke
-//       Access: Private
-//  Description: Generates a keystroke corresponding to the indicated
-//               X KeyPress event.
-////////////////////////////////////////////////////////////////////
-void TinyXGraphicsWindow::
-handle_keystroke(XKeyEvent &event) {
-  _input_devices[0].set_pointer_in_window(event.x, event.y);
-
-  if (_ic) {
-    // First, get the keystroke as a wide-character sequence.
-    static const int buffer_size = 256;
-    wchar_t buffer[buffer_size];
-    Status status;
-    int len = XwcLookupString(_ic, &event, buffer, buffer_size, NULL,
-                              &status);
-    if (status == XBufferOverflow) {
-      tinydisplay_cat.error()
-        << "Overflowed input buffer.\n";
-    }
-    
-    // Now each of the returned wide characters represents a
-    // keystroke.
-    for (int i = 0; i < len; i++) {
-      _input_devices[0].keystroke(buffer[i]);
-    }
-
-  } else {
-    // Without an input context, just get the ascii keypress.
-    ButtonHandle button = get_button(event, true);
-    if (button.has_ascii_equivalent()) {
-      _input_devices[0].keystroke(button.get_ascii_equivalent());
-    }
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsWindow::handle_keypress
-//       Access: Private
-//  Description: Generates a keypress corresponding to the indicated
-//               X KeyPress event.
-////////////////////////////////////////////////////////////////////
-void TinyXGraphicsWindow::
-handle_keypress(XKeyEvent &event) {
-  _input_devices[0].set_pointer_in_window(event.x, event.y);
-
-  // Now get the raw unshifted button.
-  ButtonHandle button = get_button(event, false);
-  if (button == KeyboardButton::lcontrol() || button == KeyboardButton::rcontrol()) {
-    _input_devices[0].button_down(KeyboardButton::control());
-  }
-  if (button == KeyboardButton::lshift() || button == KeyboardButton::rshift()) {
-    _input_devices[0].button_down(KeyboardButton::shift());
-  }
-  if (button == KeyboardButton::lalt() || button == KeyboardButton::ralt()) {
-    _input_devices[0].button_down(KeyboardButton::alt());
-  }
-  if (button != ButtonHandle::none()) {
-    _input_devices[0].button_down(button);
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsWindow::handle_keyrelease
-//       Access: Private
-//  Description: Generates a keyrelease corresponding to the indicated
-//               X KeyRelease event.
-////////////////////////////////////////////////////////////////////
-void TinyXGraphicsWindow::
-handle_keyrelease(XKeyEvent &event) {
-  _input_devices[0].set_pointer_in_window(event.x, event.y);
-
-  // Now get the raw unshifted button.
-  ButtonHandle button = get_button(event, false);
-  if (button == KeyboardButton::lcontrol() || button == KeyboardButton::rcontrol()) {
-    _input_devices[0].button_up(KeyboardButton::control());
-  }
-  if (button == KeyboardButton::lshift() || button == KeyboardButton::rshift()) {
-    _input_devices[0].button_up(KeyboardButton::shift());
-  }
-  if (button == KeyboardButton::lalt() || button == KeyboardButton::ralt()) {
-    _input_devices[0].button_up(KeyboardButton::alt());
-  }
-  if (button != ButtonHandle::none()) {
-    _input_devices[0].button_up(button);
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsWindow::get_button
-//       Access: Private
-//  Description: Returns the Panda ButtonHandle corresponding to the
-//               keyboard button indicated by the given key event.
-////////////////////////////////////////////////////////////////////
-ButtonHandle TinyXGraphicsWindow::
-get_button(XKeyEvent &key_event, bool allow_shift) {
-  KeySym key = XLookupKeysym(&key_event, 0);
-
-  if ((key_event.state & Mod2Mask) != 0) {
-    // Mod2Mask corresponds to NumLock being in effect.  In this case,
-    // we want to get the alternate keysym associated with any keypad
-    // keys.  Weird system.
-    KeySym k2;
-    ButtonHandle button;
-    switch (key) {
-    case XK_KP_Space:
-    case XK_KP_Tab:
-    case XK_KP_Enter:
-    case XK_KP_F1:
-    case XK_KP_F2:
-    case XK_KP_F3:
-    case XK_KP_F4:
-    case XK_KP_Equal:
-    case XK_KP_Multiply:
-    case XK_KP_Add:
-    case XK_KP_Separator:
-    case XK_KP_Subtract:
-    case XK_KP_Divide:
-    case XK_KP_Left:
-    case XK_KP_Up:
-    case XK_KP_Right:
-    case XK_KP_Down:
-    case XK_KP_Begin:
-    case XK_KP_Prior:
-    case XK_KP_Next:
-    case XK_KP_Home:
-    case XK_KP_End:
-    case XK_KP_Insert:
-    case XK_KP_Delete:
-    case XK_KP_0:
-    case XK_KP_1:
-    case XK_KP_2:
-    case XK_KP_3:
-    case XK_KP_4:
-    case XK_KP_5:
-    case XK_KP_6:
-    case XK_KP_7:
-    case XK_KP_8:
-    case XK_KP_9:
-      k2 = XLookupKeysym(&key_event, 1);
-      button = map_button(k2);
-      if (button != ButtonHandle::none()) {
-        return button;
-      }
-      // If that didn't produce a button we know, just fall through
-      // and handle the normal, un-numlocked key.
-      break;
-
-    default:
-      break;
-    } 
-  }
-
-  if (allow_shift) {
-    // If shift is held down, get the shifted keysym.
-    if ((key_event.state & ShiftMask) != 0) {
-      KeySym k2 = XLookupKeysym(&key_event, 1);
-      ButtonHandle button = map_button(k2);
-      if (button != ButtonHandle::none()) {
-        return button;
-      }
-    }
-
-    // If caps lock is down, shift lowercase letters to uppercase.  We
-    // can do this in just the ASCII set, because we handle
-    // international keyboards elsewhere (via an input context).
-    if ((key_event.state & (ShiftMask | LockMask)) != 0) {
-      if (key >= XK_a and key <= XK_z) {
-        key += (XK_A - XK_a);
-      }
-    }
-  }
-
-  return map_button(key);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsWindow::map_button
-//       Access: Private
-//  Description: Maps from a single X keysym to Panda's ButtonHandle.
-//               Called by get_button(), above.
-////////////////////////////////////////////////////////////////////
-ButtonHandle TinyXGraphicsWindow::
-map_button(KeySym key) {
-  switch (key) {
-  case XK_BackSpace:
-    return KeyboardButton::backspace();
-  case XK_Tab:
-  case XK_KP_Tab:
-    return KeyboardButton::tab();
-  case XK_Return:
-  case XK_KP_Enter:
-    return KeyboardButton::enter();
-  case XK_Escape:
-    return KeyboardButton::escape();
-  case XK_KP_Space:
-  case XK_space:
-    return KeyboardButton::space();
-  case XK_exclam:
-    return KeyboardButton::ascii_key('!');
-  case XK_quotedbl:
-    return KeyboardButton::ascii_key('"');
-  case XK_numbersign:
-    return KeyboardButton::ascii_key('#');
-  case XK_dollar:
-    return KeyboardButton::ascii_key('$');
-  case XK_percent:
-    return KeyboardButton::ascii_key('%');
-  case XK_ampersand:
-    return KeyboardButton::ascii_key('&');
-  case XK_apostrophe: // == XK_quoteright
-    return KeyboardButton::ascii_key('\'');
-  case XK_parenleft:
-    return KeyboardButton::ascii_key('(');
-  case XK_parenright:
-    return KeyboardButton::ascii_key(')');
-  case XK_asterisk:
-  case XK_KP_Multiply:
-    return KeyboardButton::ascii_key('*');
-  case XK_plus:
-  case XK_KP_Add:
-    return KeyboardButton::ascii_key('+');
-  case XK_comma:
-  case XK_KP_Separator:
-    return KeyboardButton::ascii_key(',');
-  case XK_minus:
-  case XK_KP_Subtract:
-    return KeyboardButton::ascii_key('-');
-  case XK_period:
-  case XK_KP_Decimal:
-    return KeyboardButton::ascii_key('.');
-  case XK_slash:
-  case XK_KP_Divide:
-    return KeyboardButton::ascii_key('/');
-  case XK_0:
-  case XK_KP_0:
-    return KeyboardButton::ascii_key('0');
-  case XK_1:
-  case XK_KP_1:
-    return KeyboardButton::ascii_key('1');
-  case XK_2:
-  case XK_KP_2:
-    return KeyboardButton::ascii_key('2');
-  case XK_3:
-  case XK_KP_3:
-    return KeyboardButton::ascii_key('3');
-  case XK_4:
-  case XK_KP_4:
-    return KeyboardButton::ascii_key('4');
-  case XK_5:
-  case XK_KP_5:
-    return KeyboardButton::ascii_key('5');
-  case XK_6:
-  case XK_KP_6:
-    return KeyboardButton::ascii_key('6');
-  case XK_7:
-  case XK_KP_7:
-    return KeyboardButton::ascii_key('7');
-  case XK_8:
-  case XK_KP_8:
-    return KeyboardButton::ascii_key('8');
-  case XK_9:
-  case XK_KP_9:
-    return KeyboardButton::ascii_key('9');
-  case XK_colon:
-    return KeyboardButton::ascii_key(':');
-  case XK_semicolon:
-    return KeyboardButton::ascii_key(';');
-  case XK_less:
-    return KeyboardButton::ascii_key('<');
-  case XK_equal:
-  case XK_KP_Equal:
-    return KeyboardButton::ascii_key('=');
-  case XK_greater:
-    return KeyboardButton::ascii_key('>');
-  case XK_question:
-    return KeyboardButton::ascii_key('?');
-  case XK_at:
-    return KeyboardButton::ascii_key('@');
-  case XK_A:
-    return KeyboardButton::ascii_key('A');
-  case XK_B:
-    return KeyboardButton::ascii_key('B');
-  case XK_C:
-    return KeyboardButton::ascii_key('C');
-  case XK_D:
-    return KeyboardButton::ascii_key('D');
-  case XK_E:
-    return KeyboardButton::ascii_key('E');
-  case XK_F:
-    return KeyboardButton::ascii_key('F');
-  case XK_G:
-    return KeyboardButton::ascii_key('G');
-  case XK_H:
-    return KeyboardButton::ascii_key('H');
-  case XK_I:
-    return KeyboardButton::ascii_key('I');
-  case XK_J:
-    return KeyboardButton::ascii_key('J');
-  case XK_K:
-    return KeyboardButton::ascii_key('K');
-  case XK_L:
-    return KeyboardButton::ascii_key('L');
-  case XK_M:
-    return KeyboardButton::ascii_key('M');
-  case XK_N:
-    return KeyboardButton::ascii_key('N');
-  case XK_O:
-    return KeyboardButton::ascii_key('O');
-  case XK_P:
-    return KeyboardButton::ascii_key('P');
-  case XK_Q:
-    return KeyboardButton::ascii_key('Q');
-  case XK_R:
-    return KeyboardButton::ascii_key('R');
-  case XK_S:
-    return KeyboardButton::ascii_key('S');
-  case XK_T:
-    return KeyboardButton::ascii_key('T');
-  case XK_U:
-    return KeyboardButton::ascii_key('U');
-  case XK_V:
-    return KeyboardButton::ascii_key('V');
-  case XK_W:
-    return KeyboardButton::ascii_key('W');
-  case XK_X:
-    return KeyboardButton::ascii_key('X');
-  case XK_Y:
-    return KeyboardButton::ascii_key('Y');
-  case XK_Z:
-    return KeyboardButton::ascii_key('Z');
-  case XK_bracketleft:
-    return KeyboardButton::ascii_key('[');
-  case XK_backslash:
-    return KeyboardButton::ascii_key('\\');
-  case XK_bracketright:
-    return KeyboardButton::ascii_key(']');
-  case XK_asciicircum:
-    return KeyboardButton::ascii_key('^');
-  case XK_underscore:
-    return KeyboardButton::ascii_key('_');
-  case XK_grave: // == XK_quoteleft
-    return KeyboardButton::ascii_key('`');
-  case XK_a:
-    return KeyboardButton::ascii_key('a');
-  case XK_b:
-    return KeyboardButton::ascii_key('b');
-  case XK_c:
-    return KeyboardButton::ascii_key('c');
-  case XK_d:
-    return KeyboardButton::ascii_key('d');
-  case XK_e:
-    return KeyboardButton::ascii_key('e');
-  case XK_f:
-    return KeyboardButton::ascii_key('f');
-  case XK_g:
-    return KeyboardButton::ascii_key('g');
-  case XK_h:
-    return KeyboardButton::ascii_key('h');
-  case XK_i:
-    return KeyboardButton::ascii_key('i');
-  case XK_j:
-    return KeyboardButton::ascii_key('j');
-  case XK_k:
-    return KeyboardButton::ascii_key('k');
-  case XK_l:
-    return KeyboardButton::ascii_key('l');
-  case XK_m:
-    return KeyboardButton::ascii_key('m');
-  case XK_n:
-    return KeyboardButton::ascii_key('n');
-  case XK_o:
-    return KeyboardButton::ascii_key('o');
-  case XK_p:
-    return KeyboardButton::ascii_key('p');
-  case XK_q:
-    return KeyboardButton::ascii_key('q');
-  case XK_r:
-    return KeyboardButton::ascii_key('r');
-  case XK_s:
-    return KeyboardButton::ascii_key('s');
-  case XK_t:
-    return KeyboardButton::ascii_key('t');
-  case XK_u:
-    return KeyboardButton::ascii_key('u');
-  case XK_v:
-    return KeyboardButton::ascii_key('v');
-  case XK_w:
-    return KeyboardButton::ascii_key('w');
-  case XK_x:
-    return KeyboardButton::ascii_key('x');
-  case XK_y:
-    return KeyboardButton::ascii_key('y');
-  case XK_z:
-    return KeyboardButton::ascii_key('z');
-  case XK_braceleft:
-    return KeyboardButton::ascii_key('{');
-  case XK_bar:
-    return KeyboardButton::ascii_key('|');
-  case XK_braceright:
-    return KeyboardButton::ascii_key('}');
-  case XK_asciitilde:
-    return KeyboardButton::ascii_key('~');
-  case XK_F1:
-  case XK_KP_F1:
-    return KeyboardButton::f1();
-  case XK_F2:
-  case XK_KP_F2:
-    return KeyboardButton::f2();
-  case XK_F3:
-  case XK_KP_F3:
-    return KeyboardButton::f3();
-  case XK_F4:
-  case XK_KP_F4:
-    return KeyboardButton::f4();
-  case XK_F5:
-    return KeyboardButton::f5();
-  case XK_F6:
-    return KeyboardButton::f6();
-  case XK_F7:
-    return KeyboardButton::f7();
-  case XK_F8:
-    return KeyboardButton::f8();
-  case XK_F9:
-    return KeyboardButton::f9();
-  case XK_F10:
-    return KeyboardButton::f10();
-  case XK_F11:
-    return KeyboardButton::f11();
-  case XK_F12:
-    return KeyboardButton::f12();
-  case XK_KP_Left:
-  case XK_Left:
-    return KeyboardButton::left();
-  case XK_KP_Up:
-  case XK_Up:
-    return KeyboardButton::up();
-  case XK_KP_Right:
-  case XK_Right:
-    return KeyboardButton::right();
-  case XK_KP_Down:
-  case XK_Down:
-    return KeyboardButton::down();
-  case XK_KP_Prior:
-  case XK_Prior:
-    return KeyboardButton::page_up();
-  case XK_KP_Next:
-  case XK_Next:
-    return KeyboardButton::page_down();
-  case XK_KP_Home:
-  case XK_Home:
-    return KeyboardButton::home();
-  case XK_KP_End:
-  case XK_End:
-    return KeyboardButton::end();
-  case XK_KP_Insert:
-  case XK_Insert:
-    return KeyboardButton::insert();
-  case XK_KP_Delete:
-  case XK_Delete:
-    return KeyboardButton::del();
-  case XK_Num_Lock:
-    return KeyboardButton::num_lock();
-  case XK_Scroll_Lock:
-    return KeyboardButton::scroll_lock();
-  case XK_Print:
-    return KeyboardButton::print_screen();
-  case XK_Pause:
-    return KeyboardButton::pause();
-  case XK_Shift_L:
-    return KeyboardButton::lshift();
-  case XK_Shift_R:
-    return KeyboardButton::rshift();
-  case XK_Control_L:
-    return KeyboardButton::lcontrol();
-  case XK_Control_R:
-    return KeyboardButton::rcontrol();
-  case XK_Alt_L:
-    return KeyboardButton::lalt();
-  case XK_Alt_R:
-    return KeyboardButton::ralt();
-  case XK_Meta_L:
-  case XK_Meta_R:
-    return KeyboardButton::meta();
-  case XK_Caps_Lock:
-    return KeyboardButton::caps_lock();
-  case XK_Shift_Lock:
-    return KeyboardButton::shift_lock();
-  }
-
-  return ButtonHandle::none();
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsWindow::get_mouse_button
-//       Access: Private
-//  Description: Returns the Panda ButtonHandle corresponding to the
-//               mouse button indicated by the given button event.
-////////////////////////////////////////////////////////////////////
-ButtonHandle TinyXGraphicsWindow::
-get_mouse_button(XButtonEvent &button_event) {
-  int index = button_event.button;
-  if (index == x_wheel_up_button) {
-    return MouseButton::wheel_up();
-  } else if (index == x_wheel_down_button) {
-    return MouseButton::wheel_down();
-  } else if (index == x_wheel_left_button) {
-    return MouseButton::wheel_left();
-  } else if (index == x_wheel_right_button) {
-    return MouseButton::wheel_right();
-  } else {
-    return MouseButton::button(index - 1);
-  }
-}
-////////////////////////////////////////////////////////////////////
-//     Function: TinyXGraphicsWindow::check_event
-//       Access: Private, Static
-//  Description: This function is used as a predicate to
-//               XCheckIfEvent() to determine if the indicated queued
-//               X event is relevant and should be returned to this
-//               window.
-////////////////////////////////////////////////////////////////////
-Bool TinyXGraphicsWindow::
-check_event(Display *display, XEvent *event, char *arg) {
-  const TinyXGraphicsWindow *self = (TinyXGraphicsWindow *)arg;
-
-  // We accept any event that is sent to our window.
-  return (event->xany.window == self->_xwindow);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: TinyXGraphicsWindow::create_full_frame_buffer
 //       Access: Private

+ 6 - 49
panda/src/tinydisplay/tinyXGraphicsWindow.h

@@ -20,7 +20,7 @@
 #ifdef HAVE_X11
 
 #include "tinyXGraphicsPipe.h"
-#include "graphicsWindow.h"
+#include "x11GraphicsWindow.h"
 #include "buttonHandle.h"
 
 ////////////////////////////////////////////////////////////////////
@@ -28,7 +28,7 @@
 // Description : Opens a window on X11 to display the TinyPanda
 //               software rendering.
 ////////////////////////////////////////////////////////////////////
-class EXPCL_TINYDISPLAY TinyXGraphicsWindow : public GraphicsWindow {
+class EXPCL_TINYDISPLAY TinyXGraphicsWindow : public x11GraphicsWindow {
 public:
   TinyXGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe, 
                       const string &name,
@@ -54,23 +54,6 @@ protected:
   virtual void pixel_factor_changed();
 
 private:
-  void set_wm_properties(const WindowProperties &properties,
-                         bool already_mapped);
-
-  void setup_colormap(XVisualInfo *visual);
-  void handle_keystroke(XKeyEvent &event);
-  void handle_keypress(XKeyEvent &event);
-  void handle_keyrelease(XKeyEvent &event);
-
-  ButtonHandle get_button(XKeyEvent &key_event, bool allow_shift);
-  ButtonHandle map_button(KeySym key);
-  ButtonHandle get_mouse_button(XButtonEvent &button_event);
-
-  static Bool check_event(Display *display, XEvent *event, char *arg);
-
-  void open_raw_mice();
-  void poll_raw_mice();
-
   void create_full_frame_buffer();
   void create_reduced_frame_buffer();
   void create_ximage();
@@ -80,45 +63,19 @@ private:
   ZBuffer *_full_frame_buffer;
   int _pitch;
   XImage *_ximage;
-
-  Display *_display;
-  int _screen;
+  GC _gc;
+  int _bytes_per_pixel;
   Visual *_visual;
   int _depth;
-  int _bytes_per_pixel;
-  Window _xwindow;
-  Colormap _colormap;
-  XIC _ic;
-  GC _gc;
-
-  long _event_mask;
-  bool _awaiting_configure;
-  Atom _wm_delete_window;
-  Atom _net_wm_window_type;
-  Atom _net_wm_window_type_splash;
-  Atom _net_wm_window_type_fullscreen;
-  Atom _net_wm_state;
-  Atom _net_wm_state_fullscreen;
-  Atom _net_wm_state_above;
-  Atom _net_wm_state_below;
-  Atom _net_wm_state_add;
-  Atom _net_wm_state_remove;
-
-  struct MouseDeviceInfo {
-    int    _fd;
-    int    _input_device_index;
-    string _io_buffer;
-  };
-  pvector<MouseDeviceInfo> _mouse_device_info;
   
 public:
   static TypeHandle get_class_type() {
     return _type_handle;
   }
   static void init_type() {
-    GraphicsWindow::init_type();
+    x11GraphicsWindow::init_type();
     register_type(_type_handle, "TinyXGraphicsWindow",
-                  GraphicsWindow::get_class_type());
+                  x11GraphicsWindow::get_class_type());
   }
   virtual TypeHandle get_type() const {
     return get_class_type();