tinyXGraphicsStuff depend on x11display

This commit is contained in:
rdb 2009-07-17 13:55:14 +00:00
parent 9d7fc0bd2f
commit 905cd3ad69
7 changed files with 20 additions and 1589 deletions

View File

@ -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 "

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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();

File diff suppressed because it is too large Load Diff

View File

@ -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();