mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 09:23:03 -04:00
Load X11 extensions dynamically; don't expect them to be there at compile time
Add x-cursor-size variable for overriding XCursor size.
This commit is contained in:
parent
122d9dd3ff
commit
28bb737597
@ -88,7 +88,7 @@ PkgListSet(["PYTHON", "DIRECT", # Python support
|
||||
"MFC", "WX", "FLTK", # Used for web plug-in only
|
||||
"ROCKET", "AWESOMIUM", # GUI libraries
|
||||
"CARBON", "COCOA", # Mac OS X toolkits
|
||||
"X11", "XF86DGA", "XRANDR", "XCURSOR", # Unix platform support
|
||||
"X11", # Unix platform support
|
||||
"PANDATOOL", "PVIEW", "DEPLOYTOOLS", # Toolchain
|
||||
"SKEL", # Example SKEL project
|
||||
"PANDAFX", # Some distortion special lenses
|
||||
@ -516,9 +516,6 @@ IncDirectory("ALWAYS", GetOutputDir()+"/include")
|
||||
|
||||
if (COMPILER == "MSVC"):
|
||||
PkgDisable("X11")
|
||||
PkgDisable("XRANDR")
|
||||
PkgDisable("XF86DGA")
|
||||
PkgDisable("XCURSOR")
|
||||
PkgDisable("GLES")
|
||||
PkgDisable("GLES2")
|
||||
PkgDisable("EGL")
|
||||
@ -843,9 +840,6 @@ if (COMPILER=="GCC"):
|
||||
SmartPkgEnable("CGGL", "", ("CgGL"), "Cg/cgGL.h")
|
||||
if not RUNTIME:
|
||||
SmartPkgEnable("X11", "x11", "X11", ("X11", "X11/Xlib.h"))
|
||||
SmartPkgEnable("XRANDR", "xrandr", "Xrandr", "X11/extensions/Xrandr.h")
|
||||
SmartPkgEnable("XF86DGA", "xxf86dga", "Xxf86dga", "X11/extensions/xf86dga.h")
|
||||
SmartPkgEnable("XCURSOR", "xcursor", "Xcursor", "X11/Xcursor/Xcursor.h")
|
||||
|
||||
if GetHost() != "darwin":
|
||||
# Workaround for an issue where pkg-config does not include this path
|
||||
@ -2194,9 +2188,6 @@ DTOOL_CONFIG=[
|
||||
("PHAVE_STDINT_H", '1', '1'),
|
||||
("HAVE_RTTI", '1', '1'),
|
||||
("HAVE_X11", 'UNDEF', '1'),
|
||||
("HAVE_XRANDR", 'UNDEF', '1'),
|
||||
("HAVE_XF86DGA", 'UNDEF', '1'),
|
||||
("HAVE_XCURSOR", 'UNDEF', '1'),
|
||||
("IS_LINUX", 'UNDEF', '1'),
|
||||
("IS_OSX", 'UNDEF', 'UNDEF'),
|
||||
("IS_FREEBSD", 'UNDEF', 'UNDEF'),
|
||||
@ -2301,9 +2292,6 @@ def WriteConfigSettings():
|
||||
dtool_config["PHAVE_SYS_MALLOC_H"] = '1'
|
||||
dtool_config["HAVE_OPENAL_FRAMEWORK"] = '1'
|
||||
dtool_config["HAVE_X11"] = 'UNDEF' # We might have X11, but we don't need it.
|
||||
dtool_config["HAVE_XRANDR"] = 'UNDEF'
|
||||
dtool_config["HAVE_XF86DGA"] = 'UNDEF'
|
||||
dtool_config["HAVE_XCURSOR"] = 'UNDEF'
|
||||
dtool_config["HAVE_GLX"] = 'UNDEF'
|
||||
dtool_config["IS_LINUX"] = 'UNDEF'
|
||||
dtool_config["HAVE_VIDEO4LINUX"] = 'UNDEF'
|
||||
@ -4581,7 +4569,7 @@ if (GetTarget() not in ['windows', 'darwin'] and PkgSkip("GL")==0 and PkgSkip("X
|
||||
TargetAdd('libpandagl.dll', input='p3glgsg_glgsg.obj')
|
||||
TargetAdd('libpandagl.dll', input='p3glxdisplay_composite1.obj')
|
||||
TargetAdd('libpandagl.dll', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('libpandagl.dll', opts=['MODULE', 'GL', 'NVIDIACG', 'CGGL', 'X11', 'XRANDR', 'XF86DGA', 'XCURSOR'])
|
||||
TargetAdd('libpandagl.dll', opts=['MODULE', 'GL', 'NVIDIACG', 'CGGL', 'X11'])
|
||||
|
||||
#
|
||||
# DIRECTORY: panda/src/cocoadisplay/
|
||||
@ -4656,7 +4644,7 @@ if (PkgSkip("EGL")==0 and PkgSkip("GLES")==0 and PkgSkip("X11")==0 and not RUNTI
|
||||
TargetAdd('libpandagles.dll', input='p3glesgsg_glesgsg.obj')
|
||||
TargetAdd('libpandagles.dll', input='pandagles_egldisplay_composite1.obj')
|
||||
TargetAdd('libpandagles.dll', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('libpandagles.dll', opts=['MODULE', 'GLES', 'EGL', 'X11', 'XRANDR', 'XF86DGA', 'XCURSOR'])
|
||||
TargetAdd('libpandagles.dll', opts=['MODULE', 'GLES', 'EGL', 'X11'])
|
||||
|
||||
#
|
||||
# DIRECTORY: panda/src/egldisplay/
|
||||
@ -4674,7 +4662,7 @@ if (PkgSkip("EGL")==0 and PkgSkip("GLES2")==0 and PkgSkip("X11")==0 and not RUNT
|
||||
TargetAdd('libpandagles2.dll', input='p3gles2gsg_gles2gsg.obj')
|
||||
TargetAdd('libpandagles2.dll', input='pandagles2_egldisplay_composite1.obj')
|
||||
TargetAdd('libpandagles2.dll', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('libpandagles2.dll', opts=['MODULE', 'GLES2', 'EGL', 'X11', 'XRANDR', 'XF86DGA', 'XCURSOR'])
|
||||
TargetAdd('libpandagles2.dll', opts=['MODULE', 'GLES2', 'EGL', 'X11'])
|
||||
|
||||
#
|
||||
# DIRECTORY: panda/src/ode/
|
||||
@ -4970,7 +4958,7 @@ if (not RUNTIME and (GetTarget() in ('windows', 'darwin') or PkgSkip("X11")==0)
|
||||
TargetAdd('libp3tinydisplay.dll', opts=['WINIMM', 'WINGDI', 'WINKERNEL', 'WINOLDNAMES', 'WINUSER', 'WINMM'])
|
||||
else:
|
||||
TargetAdd('libp3tinydisplay.dll', input='p3x11display_composite1.obj')
|
||||
TargetAdd('libp3tinydisplay.dll', opts=['X11', 'XRANDR', 'XF86DGA', 'XCURSOR'])
|
||||
TargetAdd('libp3tinydisplay.dll', opts=['X11'])
|
||||
TargetAdd('libp3tinydisplay.dll', input='p3tinydisplay_composite1.obj')
|
||||
TargetAdd('libp3tinydisplay.dll', input='p3tinydisplay_composite2.obj')
|
||||
TargetAdd('libp3tinydisplay.dll', input='p3tinydisplay_ztriangle_1.obj')
|
||||
|
@ -49,19 +49,6 @@ struct XVisualInfo;
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
#ifdef HAVE_XRANDR
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#endif // HAVE_XRANDR
|
||||
|
||||
#ifdef HAVE_XCURSOR
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XF86DGA
|
||||
#include <X11/extensions/Xxf86dga.h>
|
||||
#endif
|
||||
|
||||
#include "post_x11_include.h"
|
||||
|
||||
#endif // CPPPARSER
|
||||
|
@ -60,6 +60,11 @@ ConfigVariableInt x_wheel_right_button
|
||||
"mouse button number does the system report when one scrolls "
|
||||
"to the right?"));
|
||||
|
||||
ConfigVariableInt x_cursor_size
|
||||
("x-cursor-size", -1,
|
||||
PRC_DESC("This sets the cursor size when using XCursor to change the mouse "
|
||||
"cursor. The default is to use the default size for the display."));
|
||||
|
||||
ConfigVariableString x_wm_class_name
|
||||
("x-wm-class-name", "",
|
||||
PRC_DESC("Specify the value to use for the res_name field of the window's "
|
||||
|
@ -32,6 +32,7 @@ extern ConfigVariableInt x_wheel_down_button;
|
||||
extern ConfigVariableInt x_wheel_left_button;
|
||||
extern ConfigVariableInt x_wheel_right_button;
|
||||
|
||||
extern ConfigVariableInt x_cursor_size;
|
||||
extern ConfigVariableString x_wm_class_name;
|
||||
extern ConfigVariableString x_wm_class;
|
||||
|
||||
|
@ -57,6 +57,38 @@ get_hidden_cursor() {
|
||||
return _hidden_cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if relative mouse mode is supported on this display.
|
||||
*/
|
||||
INLINE bool x11GraphicsPipe::
|
||||
supports_relative_mouse() const {
|
||||
return (_XF86DGADirectVideo != NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables relative mouse mode for this display. Returns false if unsupported.
|
||||
*/
|
||||
INLINE bool x11GraphicsPipe::
|
||||
enable_relative_mouse() {
|
||||
if (_XF86DGADirectVideo != NULL) {
|
||||
x11display_cat.info() << "Enabling relative mouse using XF86DGA extension\n";
|
||||
_XF86DGADirectVideo(_display, _screen, XF86DGADirectMouse);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables relative mouse mode for this display.
|
||||
*/
|
||||
INLINE void x11GraphicsPipe::
|
||||
disable_relative_mouse() {
|
||||
if (_XF86DGADirectVideo != NULL) {
|
||||
x11display_cat.info() << "Disabling relative mouse using XF86DGA extension\n";
|
||||
_XF86DGADirectVideo(_display, _screen, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Globally disables the printing of error messages that are raised by the X11
|
||||
* system, for instance in order to test whether a particular X11 operation
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include "frameBufferProperties.h"
|
||||
#include "displayInformation.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
TypeHandle x11GraphicsPipe::_type_handle;
|
||||
|
||||
bool x11GraphicsPipe::_error_handlers_installed = false;
|
||||
@ -31,7 +33,11 @@ LightReMutex x11GraphicsPipe::_x_mutex;
|
||||
*
|
||||
*/
|
||||
x11GraphicsPipe::
|
||||
x11GraphicsPipe(const string &display) {
|
||||
x11GraphicsPipe(const string &display) :
|
||||
_have_xrandr(false),
|
||||
_xcursor_size(-1),
|
||||
_XF86DGADirectVideo(NULL) {
|
||||
|
||||
string display_spec = display;
|
||||
if (display_spec.empty()) {
|
||||
display_spec = display_cfg;
|
||||
@ -86,14 +92,96 @@ x11GraphicsPipe(const string &display) {
|
||||
_display_height = DisplayHeight(_display, _screen);
|
||||
_is_valid = true;
|
||||
|
||||
#ifdef HAVE_XRANDR
|
||||
// Dynamically load the xf86dga extension.
|
||||
void *xf86dga = dlopen("libXxf86dga.so.1", RTLD_NOW | RTLD_LOCAL);
|
||||
if (xf86dga != NULL) {
|
||||
pfn_XF86DGAQueryVersion _XF86DGAQueryVersion = (pfn_XF86DGAQueryVersion)dlsym(xf86dga, "XF86DGAQueryVersion");
|
||||
_XF86DGADirectVideo = (pfn_XF86DGADirectVideo)dlsym(xf86dga, "XF86DGADirectVideo");
|
||||
|
||||
int major_ver, minor_ver;
|
||||
if (_XF86DGAQueryVersion == NULL || _XF86DGADirectVideo == NULL) {
|
||||
x11display_cat.warning()
|
||||
<< "libXxf86dga.so.1 does not provide required functions; relative mouse mode will not work.\n";
|
||||
|
||||
} else if (!_XF86DGAQueryVersion(_display, &major_ver, &minor_ver)) {
|
||||
_XF86DGADirectVideo = NULL;
|
||||
}
|
||||
} else {
|
||||
_XF86DGADirectVideo = NULL;
|
||||
if (x11display_cat.is_debug()) {
|
||||
x11display_cat.debug()
|
||||
<< "cannot dlopen libXxf86dga.so.1; cursor changing will not work.\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Dynamically load the XCursor extension.
|
||||
void *xcursor = dlopen("libXcursor.so.1", RTLD_NOW | RTLD_LOCAL);
|
||||
if (xcursor != NULL) {
|
||||
pfn_XcursorGetDefaultSize _XcursorGetDefaultSize = (pfn_XcursorGetDefaultSize)dlsym(xcursor, "XcursorGetDefaultSize");
|
||||
_XcursorXcFileLoadImages = (pfn_XcursorXcFileLoadImages)dlsym(xcursor, "XcursorXcFileLoadImages");
|
||||
_XcursorImagesLoadCursor = (pfn_XcursorImagesLoadCursor)dlsym(xcursor, "XcursorImagesLoadCursor");
|
||||
_XcursorImagesDestroy = (pfn_XcursorImagesDestroy)dlsym(xcursor, "XcursorImagesDestroy");
|
||||
_XcursorImageCreate = (pfn_XcursorImageCreate)dlsym(xcursor, "XcursorImageCreate");
|
||||
_XcursorImageLoadCursor = (pfn_XcursorImageLoadCursor)dlsym(xcursor, "XcursorImageLoadCursor");
|
||||
_XcursorImageDestroy = (pfn_XcursorImageDestroy)dlsym(xcursor, "XcursorImageDestroy");
|
||||
|
||||
if (_XcursorGetDefaultSize == NULL || _XcursorXcFileLoadImages == NULL ||
|
||||
_XcursorImagesLoadCursor == NULL || _XcursorImagesDestroy == NULL ||
|
||||
_XcursorImageCreate == NULL || _XcursorImageLoadCursor == NULL ||
|
||||
_XcursorImageDestroy == NULL) {
|
||||
_xcursor_size = -1;
|
||||
x11display_cat.warning()
|
||||
<< "libXcursor.so.1 does not provide required functions; cursor changing will not work.\n";
|
||||
|
||||
} else if (x_cursor_size.get_value() >= 0) {
|
||||
_xcursor_size = x_cursor_size;
|
||||
} else {
|
||||
_xcursor_size = _XcursorGetDefaultSize(_display);
|
||||
}
|
||||
} else {
|
||||
_xcursor_size = -1;
|
||||
if (x11display_cat.is_debug()) {
|
||||
x11display_cat.debug()
|
||||
<< "cannot dlopen libXcursor.so.1; cursor changing will not work.\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Dynamically load the XRandr extension.
|
||||
void *xrandr = dlopen("libXrandr.so.2", RTLD_NOW | RTLD_LOCAL);
|
||||
if (xrandr != NULL) {
|
||||
pfn_XRRQueryExtension _XRRQueryExtension = (pfn_XRRQueryExtension)dlsym(xrandr, "XRRQueryExtension");
|
||||
_XRRSizes = (pfn_XRRSizes)dlsym(xrandr, "XRRSizes");
|
||||
_XRRRates = (pfn_XRRRates)dlsym(xrandr, "XRRRates");
|
||||
_XRRGetScreenInfo = (pfn_XRRGetScreenInfo)dlsym(xrandr, "XRRGetScreenInfo");
|
||||
_XRRConfigCurrentConfiguration = (pfn_XRRConfigCurrentConfiguration)dlsym(xrandr, "XRRConfigCurrentConfiguration");
|
||||
_XRRSetScreenConfig = (pfn_XRRSetScreenConfig)dlsym(xrandr, "XRRSetScreenConfig");
|
||||
|
||||
if (_XRRQueryExtension == NULL || _XRRSizes == NULL || _XRRRates == NULL ||
|
||||
_XRRGetScreenInfo == NULL || _XRRConfigCurrentConfiguration == NULL ||
|
||||
_XRRSetScreenConfig == NULL) {
|
||||
_have_xrandr = false;
|
||||
x11display_cat.warning()
|
||||
<< "libXrandr.so.2 does not provide required functions; resolution setting will not work.\n";
|
||||
} else {
|
||||
int event, error;
|
||||
_have_xrandr = _XRRQueryExtension(_display, &event, &error);
|
||||
}
|
||||
} else {
|
||||
_have_xrandr = false;
|
||||
if (x11display_cat.is_debug()) {
|
||||
x11display_cat.debug()
|
||||
<< "cannot dlopen libXrandr.so.2; resolution setting will not work.\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Use Xrandr to fill in the supported resolution list.
|
||||
if (_have_xrandr) {
|
||||
int num_sizes, num_rates;
|
||||
XRRScreenSize *xrrs;
|
||||
xrrs = XRRSizes(_display, 0, &num_sizes);
|
||||
xrrs = _XRRSizes(_display, 0, &num_sizes);
|
||||
_display_information->_total_display_modes = 0;
|
||||
for (int i = 0; i < num_sizes; ++i) {
|
||||
XRRRates(_display, 0, i, &num_rates);
|
||||
_XRRRates(_display, 0, i, &num_rates);
|
||||
_display_information->_total_display_modes += num_rates;
|
||||
}
|
||||
|
||||
@ -102,7 +190,7 @@ x11GraphicsPipe(const string &display) {
|
||||
_display_information->_display_mode_array = new DisplayMode[_display_information->_total_display_modes];
|
||||
for (int i = 0; i < num_sizes; ++i) {
|
||||
int num_rates;
|
||||
rates = XRRRates(_display, 0, i, &num_rates);
|
||||
rates = _XRRRates(_display, 0, i, &num_rates);
|
||||
for (int j = 0; j < num_rates; ++j) {
|
||||
DisplayMode* dm = _display_information->_display_mode_array + counter;
|
||||
dm->width = xrrs[i].width;
|
||||
@ -113,7 +201,7 @@ x11GraphicsPipe(const string &display) {
|
||||
++counter;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Connect to an input method for supporting international text entry.
|
||||
_im = XOpenIM(_display, NULL, NULL, NULL);
|
||||
|
@ -21,6 +21,22 @@
|
||||
#include "lightReMutex.h"
|
||||
#include "windowHandle.h"
|
||||
#include "get_x11.h"
|
||||
#include "config_x11display.h"
|
||||
|
||||
// Excerpt the few definitions we need for the extensions.
|
||||
#define XF86DGADirectMouse 0x0004
|
||||
|
||||
typedef struct _XcursorFile XcursorFile;
|
||||
typedef struct _XcursorImage XcursorImage;
|
||||
typedef struct _XcursorImages XcursorImages;
|
||||
|
||||
typedef unsigned short Rotation;
|
||||
typedef unsigned short SizeID;
|
||||
typedef struct _XRRScreenConfiguration XRRScreenConfiguration;
|
||||
typedef struct {
|
||||
int width, height;
|
||||
int mwidth, mheight;
|
||||
} XRRScreenSize;
|
||||
|
||||
class FrameBufferProperties;
|
||||
|
||||
@ -40,6 +56,10 @@ public:
|
||||
|
||||
INLINE X11_Cursor get_hidden_cursor();
|
||||
|
||||
INLINE bool supports_relative_mouse() const;
|
||||
INLINE bool enable_relative_mouse();
|
||||
INLINE void disable_relative_mouse();
|
||||
|
||||
static INLINE int disable_x_error_messages();
|
||||
static INLINE int enable_x_error_messages();
|
||||
static INLINE int get_x_error_count();
|
||||
@ -61,6 +81,38 @@ public:
|
||||
Atom _net_wm_state_add;
|
||||
Atom _net_wm_state_remove;
|
||||
|
||||
// Extension functions.
|
||||
typedef int (*pfn_XcursorGetDefaultSize)(X11_Display *);
|
||||
typedef XcursorImages *(*pfn_XcursorXcFileLoadImages)(XcursorFile *, int);
|
||||
typedef X11_Cursor (*pfn_XcursorImagesLoadCursor)(X11_Display *, const XcursorImages *);
|
||||
typedef void (*pfn_XcursorImagesDestroy)(XcursorImages *);
|
||||
typedef XcursorImage *(*pfn_XcursorImageCreate)(int, int);
|
||||
typedef X11_Cursor (*pfn_XcursorImageLoadCursor)(X11_Display *, const XcursorImage *);
|
||||
typedef void (*pfn_XcursorImageDestroy)(XcursorImage *);
|
||||
|
||||
int _xcursor_size;
|
||||
pfn_XcursorXcFileLoadImages _XcursorXcFileLoadImages;
|
||||
pfn_XcursorImagesLoadCursor _XcursorImagesLoadCursor;
|
||||
pfn_XcursorImagesDestroy _XcursorImagesDestroy;
|
||||
pfn_XcursorImageCreate _XcursorImageCreate;
|
||||
pfn_XcursorImageLoadCursor _XcursorImageLoadCursor;
|
||||
pfn_XcursorImageDestroy _XcursorImageDestroy;
|
||||
|
||||
typedef Bool (*pfn_XRRQueryExtension)(X11_Display *, int*, int*);
|
||||
typedef XRRScreenSize *(*pfn_XRRSizes)(X11_Display*, int, int*);
|
||||
typedef short *(*pfn_XRRRates)(X11_Display*, int, int, int*);
|
||||
typedef XRRScreenConfiguration *(*pfn_XRRGetScreenInfo)(X11_Display*, X11_Window);
|
||||
typedef SizeID (*pfn_XRRConfigCurrentConfiguration)(XRRScreenConfiguration*, Rotation*);
|
||||
typedef Status (*pfn_XRRSetScreenConfig)(X11_Display*, XRRScreenConfiguration *,
|
||||
Drawable, int, Rotation, Time);
|
||||
|
||||
bool _have_xrandr;
|
||||
pfn_XRRSizes _XRRSizes;
|
||||
pfn_XRRRates _XRRRates;
|
||||
pfn_XRRGetScreenInfo _XRRGetScreenInfo;
|
||||
pfn_XRRConfigCurrentConfiguration _XRRConfigCurrentConfiguration;
|
||||
pfn_XRRSetScreenConfig _XRRSetScreenConfig;
|
||||
|
||||
protected:
|
||||
X11_Display *_display;
|
||||
int _screen;
|
||||
@ -69,6 +121,10 @@ protected:
|
||||
|
||||
X11_Cursor _hidden_cursor;
|
||||
|
||||
typedef Bool (*pfn_XF86DGAQueryVersion)(X11_Display *, int*, int*);
|
||||
typedef Status (*pfn_XF86DGADirectVideo)(X11_Display *, int, int);
|
||||
pfn_XF86DGADirectVideo _XF86DGADirectVideo;
|
||||
|
||||
private:
|
||||
void make_hidden_cursor();
|
||||
void release_hidden_cursor();
|
||||
|
@ -38,7 +38,24 @@
|
||||
#include <linux/input.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XCURSOR
|
||||
struct _XcursorFile {
|
||||
void *closure;
|
||||
int (*read)(XcursorFile *, unsigned char *, int);
|
||||
int (*write)(XcursorFile *, unsigned char *, int);
|
||||
int (*seek)(XcursorFile *, long, int);
|
||||
};
|
||||
|
||||
typedef struct _XcursorImage {
|
||||
unsigned int version;
|
||||
unsigned int size;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int xhot;
|
||||
unsigned int yhot;
|
||||
unsigned int delay;
|
||||
unsigned int *pixels;
|
||||
} XcursorImage;
|
||||
|
||||
static int xcursor_read(XcursorFile *file, unsigned char *buf, int len) {
|
||||
istream* str = (istream*) file->closure;
|
||||
str->read((char*) buf, len);
|
||||
@ -66,7 +83,6 @@ static int xcursor_seek(XcursorFile *file, long offset, int whence) {
|
||||
|
||||
return str->tellg();
|
||||
}
|
||||
#endif
|
||||
|
||||
TypeHandle x11GraphicsWindow::_type_handle;
|
||||
|
||||
@ -92,14 +108,14 @@ x11GraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
_xwindow = (X11_Window)NULL;
|
||||
_ic = (XIC)NULL;
|
||||
_visual_info = NULL;
|
||||
|
||||
#ifdef HAVE_XRANDR
|
||||
_orig_size_id = -1;
|
||||
int event, error;
|
||||
_have_xrandr = XRRQueryExtension(_display, &event, &error);
|
||||
#else
|
||||
_have_xrandr = false;
|
||||
#endif
|
||||
|
||||
if (x11_pipe->_have_xrandr) {
|
||||
// We may still need these functions after the pipe is already destroyed,
|
||||
// so we copy them into the x11GraphicsWindow.
|
||||
_XRRGetScreenInfo = x11_pipe->_XRRGetScreenInfo;
|
||||
_XRRSetScreenConfig = x11_pipe->_XRRSetScreenConfig;
|
||||
}
|
||||
|
||||
_awaiting_configure = false;
|
||||
_dga_mouse_enabled = false;
|
||||
@ -474,10 +490,9 @@ set_properties_now(WindowProperties &properties) {
|
||||
|
||||
if (is_fullscreen != want_fullscreen || (is_fullscreen && properties.has_size())) {
|
||||
if (want_fullscreen) {
|
||||
if (_have_xrandr) {
|
||||
#ifdef HAVE_XRANDR
|
||||
XRRScreenConfiguration* conf = XRRGetScreenInfo(_display, x11_pipe->get_root());
|
||||
SizeID old_size_id = XRRConfigCurrentConfiguration(conf, &_orig_rotation);
|
||||
if (x11_pipe->_have_xrandr) {
|
||||
XRRScreenConfiguration* conf = _XRRGetScreenInfo(_display, x11_pipe->get_root());
|
||||
SizeID old_size_id = x11_pipe->_XRRConfigCurrentConfiguration(conf, &_orig_rotation);
|
||||
SizeID new_size_id = (SizeID) -1;
|
||||
int num_sizes = 0, reqsizex, reqsizey;
|
||||
if (properties.has_size()) {
|
||||
@ -488,7 +503,7 @@ set_properties_now(WindowProperties &properties) {
|
||||
reqsizey = _properties.get_y_size();
|
||||
}
|
||||
XRRScreenSize *xrrs;
|
||||
xrrs = XRRSizes(_display, 0, &num_sizes);
|
||||
xrrs = x11_pipe->_XRRSizes(_display, 0, &num_sizes);
|
||||
for (int i = 0; i < num_sizes; ++i) {
|
||||
if (xrrs[i].width == reqsizex &&
|
||||
xrrs[i].height == reqsizey) {
|
||||
@ -502,14 +517,13 @@ set_properties_now(WindowProperties &properties) {
|
||||
} else {
|
||||
if (new_size_id != old_size_id) {
|
||||
|
||||
XRRSetScreenConfig(_display, conf, x11_pipe->get_root(), new_size_id, _orig_rotation, CurrentTime);
|
||||
_XRRSetScreenConfig(_display, conf, x11_pipe->get_root(), new_size_id, _orig_rotation, CurrentTime);
|
||||
if (_orig_size_id == (SizeID) -1) {
|
||||
// Remember the original resolution so we can switch back to it.
|
||||
_orig_size_id = old_size_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
// If we don't have Xrandr support, we fake the fullscreen support by
|
||||
// setting the window size to the desktop size.
|
||||
@ -517,15 +531,13 @@ set_properties_now(WindowProperties &properties) {
|
||||
x11_pipe->get_display_height());
|
||||
}
|
||||
} else {
|
||||
#ifdef HAVE_XRANDR
|
||||
// Change the resolution back to what it was. Don't remove the SizeID
|
||||
// typecast!
|
||||
if (_have_xrandr && _orig_size_id != (SizeID) -1) {
|
||||
XRRScreenConfiguration* conf = XRRGetScreenInfo(_display, x11_pipe->get_root());
|
||||
XRRSetScreenConfig(_display, conf, x11_pipe->get_root(), _orig_size_id, _orig_rotation, CurrentTime);
|
||||
if (_orig_size_id != (SizeID) -1) {
|
||||
XRRScreenConfiguration *conf = _XRRGetScreenInfo(_display, x11_pipe->get_root());
|
||||
_XRRSetScreenConfig(_display, conf, x11_pipe->get_root(), _orig_size_id, _orig_rotation, CurrentTime);
|
||||
_orig_size_id = (SizeID) -1;
|
||||
}
|
||||
#endif
|
||||
// Set the origin back to what it was
|
||||
if (!properties.has_origin() && _properties.has_origin()) {
|
||||
properties.set_origin(_properties.get_x_origin(), _properties.get_y_origin());
|
||||
@ -686,23 +698,17 @@ set_properties_now(WindowProperties &properties) {
|
||||
switch (properties.get_mouse_mode()) {
|
||||
case WindowProperties::M_absolute:
|
||||
XUngrabPointer(_display, CurrentTime);
|
||||
#ifdef HAVE_XF86DGA
|
||||
if (_dga_mouse_enabled) {
|
||||
x11display_cat.info() << "Disabling relative mouse using XF86DGA extension\n";
|
||||
XF86DGADirectVideo(_display, _screen, 0);
|
||||
x11_pipe->disable_relative_mouse();
|
||||
_dga_mouse_enabled = false;
|
||||
}
|
||||
#endif
|
||||
_properties.set_mouse_mode(WindowProperties::M_absolute);
|
||||
properties.clear_mouse_mode();
|
||||
break;
|
||||
|
||||
case WindowProperties::M_relative:
|
||||
#ifdef HAVE_XF86DGA
|
||||
if (!_dga_mouse_enabled) {
|
||||
int major_ver, minor_ver;
|
||||
if (XF86DGAQueryVersion(_display, &major_ver, &minor_ver)) {
|
||||
|
||||
if (x11_pipe->supports_relative_mouse()) {
|
||||
X11_Cursor cursor = None;
|
||||
if (_properties.get_cursor_hidden()) {
|
||||
x11GraphicsPipe *x11_pipe;
|
||||
@ -714,8 +720,7 @@ set_properties_now(WindowProperties &properties) {
|
||||
GrabModeAsync, _xwindow, cursor, CurrentTime) != GrabSuccess) {
|
||||
x11display_cat.error() << "Failed to grab pointer!\n";
|
||||
} else {
|
||||
x11display_cat.info() << "Enabling relative mouse using XF86DGA extension\n";
|
||||
XF86DGADirectVideo(_display, _screen, XF86DGADirectMouse);
|
||||
x11_pipe->enable_relative_mouse();
|
||||
|
||||
_properties.set_mouse_mode(WindowProperties::M_relative);
|
||||
properties.clear_mouse_mode();
|
||||
@ -730,25 +735,24 @@ set_properties_now(WindowProperties &properties) {
|
||||
_input_devices[0].set_pointer_in_window(event.xbutton.x, event.xbutton.y);
|
||||
}
|
||||
} else {
|
||||
x11display_cat.info() << "XF86DGA extension not available\n";
|
||||
x11display_cat.info()
|
||||
<< "XF86DGA extension not available, cannot enable relative mouse mode\n";
|
||||
_dga_mouse_enabled = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case WindowProperties::M_confined:
|
||||
{
|
||||
#ifdef HAVE_XF86DGA
|
||||
if (_dga_mouse_enabled) {
|
||||
XF86DGADirectVideo(_display, _screen, 0);
|
||||
_dga_mouse_enabled = false;
|
||||
}
|
||||
#endif
|
||||
X11_Cursor cursor = None;
|
||||
if (_properties.get_cursor_hidden()) {
|
||||
x11GraphicsPipe *x11_pipe;
|
||||
DCAST_INTO_V(x11_pipe, _pipe);
|
||||
|
||||
if (_dga_mouse_enabled) {
|
||||
x11_pipe->disable_relative_mouse();
|
||||
_dga_mouse_enabled = false;
|
||||
}
|
||||
X11_Cursor cursor = None;
|
||||
if (_properties.get_cursor_hidden()) {
|
||||
cursor = x11_pipe->get_hidden_cursor();
|
||||
}
|
||||
|
||||
@ -813,10 +817,9 @@ close_window() {
|
||||
XFlush(_display);
|
||||
}
|
||||
|
||||
#ifdef HAVE_XRANDR
|
||||
// Change the resolution back to what it was. Don't remove the SizeID
|
||||
// typecast!
|
||||
if (_have_xrandr && _orig_size_id != (SizeID) -1) {
|
||||
if (_orig_size_id != (SizeID) -1) {
|
||||
X11_Window root;
|
||||
if (_pipe != NULL) {
|
||||
x11GraphicsPipe *x11_pipe;
|
||||
@ -827,11 +830,10 @@ close_window() {
|
||||
// closed. Oh well, let's get the root window by ourselves.
|
||||
root = RootWindow(_display, _screen);
|
||||
}
|
||||
XRRScreenConfiguration* conf = XRRGetScreenInfo(_display, root);
|
||||
XRRSetScreenConfig(_display, conf, root, _orig_size_id, _orig_rotation, CurrentTime);
|
||||
XRRScreenConfiguration *conf = _XRRGetScreenInfo(_display, root);
|
||||
_XRRSetScreenConfig(_display, conf, root, _orig_size_id, _orig_rotation, CurrentTime);
|
||||
_orig_size_id = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
GraphicsWindow::close_window();
|
||||
}
|
||||
@ -859,15 +861,14 @@ open_window() {
|
||||
_properties.set_size(100, 100);
|
||||
}
|
||||
|
||||
#ifdef HAVE_XRANDR
|
||||
if (_properties.get_fullscreen() && _have_xrandr) {
|
||||
XRRScreenConfiguration* conf = XRRGetScreenInfo(_display, x11_pipe->get_root());
|
||||
if (_properties.get_fullscreen() && x11_pipe->_have_xrandr) {
|
||||
XRRScreenConfiguration* conf = _XRRGetScreenInfo(_display, x11_pipe->get_root());
|
||||
if (_orig_size_id == (SizeID) -1) {
|
||||
_orig_size_id = XRRConfigCurrentConfiguration(conf, &_orig_rotation);
|
||||
_orig_size_id = x11_pipe->_XRRConfigCurrentConfiguration(conf, &_orig_rotation);
|
||||
}
|
||||
int num_sizes, new_size_id = -1;
|
||||
XRRScreenSize *xrrs;
|
||||
xrrs = XRRSizes(_display, 0, &num_sizes);
|
||||
xrrs = x11_pipe->_XRRSizes(_display, 0, &num_sizes);
|
||||
for (int i = 0; i < num_sizes; ++i) {
|
||||
if (xrrs[i].width == _properties.get_x_size() &&
|
||||
xrrs[i].height == _properties.get_y_size()) {
|
||||
@ -882,12 +883,11 @@ open_window() {
|
||||
return false;
|
||||
}
|
||||
if (new_size_id != _orig_size_id) {
|
||||
XRRSetScreenConfig(_display, conf, x11_pipe->get_root(), new_size_id, _orig_rotation, CurrentTime);
|
||||
_XRRSetScreenConfig(_display, conf, x11_pipe->get_root(), new_size_id, _orig_rotation, CurrentTime);
|
||||
} else {
|
||||
_orig_size_id = -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
X11_Window parent_window = x11_pipe->get_root();
|
||||
WindowHandle *window_handle = _properties.get_parent_window();
|
||||
@ -2081,11 +2081,15 @@ check_event(X11_Display *display, XEvent *event, char *arg) {
|
||||
*/
|
||||
X11_Cursor x11GraphicsWindow::
|
||||
get_cursor(const Filename &filename) {
|
||||
#ifndef HAVE_XCURSOR
|
||||
x11GraphicsPipe *x11_pipe;
|
||||
DCAST_INTO_R(x11_pipe, _pipe, None);
|
||||
|
||||
if (x11_pipe->_xcursor_size == -1) {
|
||||
x11display_cat.info()
|
||||
<< "XCursor support not enabled in build; cannot change mouse cursor.\n";
|
||||
<< "libXcursor.so.1 not available; cannot change mouse cursor.\n";
|
||||
return None;
|
||||
#else // HAVE_XCURSOR
|
||||
}
|
||||
|
||||
// First, look for the unresolved filename in our index.
|
||||
pmap<Filename, X11_Cursor>::iterator fi = _cursor_filenames.find(filename);
|
||||
if (fi != _cursor_filenames.end()) {
|
||||
@ -2135,10 +2139,10 @@ get_cursor(const Filename &filename) {
|
||||
xcfile.write = &xcursor_write;
|
||||
xcfile.seek = &xcursor_seek;
|
||||
|
||||
XcursorImages *images = XcursorXcFileLoadImages(&xcfile, XcursorGetDefaultSize(_display));
|
||||
XcursorImages *images = x11_pipe->_XcursorXcFileLoadImages(&xcfile, x11_pipe->_xcursor_size);
|
||||
if (images != NULL) {
|
||||
h = XcursorImagesLoadCursor(_display, images);
|
||||
XcursorImagesDestroy(images);
|
||||
h = x11_pipe->_XcursorImagesLoadCursor(_display, images);
|
||||
x11_pipe->_XcursorImagesDestroy(images);
|
||||
}
|
||||
|
||||
} else if (memcmp(magic, "\0\0\1\0", 4) == 0
|
||||
@ -2159,16 +2163,17 @@ get_cursor(const Filename &filename) {
|
||||
|
||||
_cursor_filenames[resolved] = h;
|
||||
return h;
|
||||
#endif // HAVE_XCURSOR
|
||||
}
|
||||
|
||||
#ifdef HAVE_XCURSOR
|
||||
/**
|
||||
* Reads a Windows .ico or .cur file from the indicated stream and returns it
|
||||
* as an X11 Cursor. If the file cannot be loaded, returns None.
|
||||
*/
|
||||
X11_Cursor x11GraphicsWindow::
|
||||
read_ico(istream &ico) {
|
||||
x11GraphicsPipe *x11_pipe;
|
||||
DCAST_INTO_R(x11_pipe, _pipe, None);
|
||||
|
||||
// Local structs, this is just POD, make input easier
|
||||
typedef struct {
|
||||
uint16_t reserved, type, count;
|
||||
@ -2204,7 +2209,7 @@ read_ico(istream &ico) {
|
||||
XcursorImage *image = NULL;
|
||||
X11_Cursor ret = None;
|
||||
|
||||
int def_size = XcursorGetDefaultSize(_display);
|
||||
int def_size = x11_pipe->_xcursor_size;
|
||||
|
||||
// Get our header, note that ICO = type 1 and CUR = type 2.
|
||||
ico.read(reinterpret_cast<char *>(&header), sizeof(IcoHeader));
|
||||
@ -2240,7 +2245,7 @@ read_ico(istream &ico) {
|
||||
}
|
||||
img.set_maxval(255);
|
||||
|
||||
image = XcursorImageCreate(img.get_x_size(), img.get_y_size());
|
||||
image = x11_pipe->_XcursorImageCreate(img.get_x_size(), img.get_y_size());
|
||||
|
||||
xel *ptr = img.get_array();
|
||||
xelval *alpha = img.get_alpha_array();
|
||||
@ -2285,7 +2290,7 @@ read_ico(istream &ico) {
|
||||
ico.read(andBmp, andBmpSize);
|
||||
if (!ico.good()) goto cleanup;
|
||||
|
||||
image = XcursorImageCreate(infoHeader.width, infoHeader.height / 2);
|
||||
image = x11_pipe->_XcursorImageCreate(infoHeader.width, infoHeader.height / 2);
|
||||
|
||||
// Support all the formats that GIMP supports.
|
||||
switch (bitsPerPixel) {
|
||||
@ -2370,10 +2375,10 @@ read_ico(istream &ico) {
|
||||
image->yhot = 0;
|
||||
}
|
||||
|
||||
ret = XcursorImageLoadCursor(_display, image);
|
||||
ret = x11_pipe->_XcursorImageLoadCursor(_display, image);
|
||||
|
||||
cleanup:
|
||||
XcursorImageDestroy(image);
|
||||
x11_pipe->_XcursorImageDestroy(image);
|
||||
delete[] entries;
|
||||
delete[] palette;
|
||||
delete[] xorBmp;
|
||||
@ -2381,4 +2386,3 @@ cleanup:
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif // HAVE_XCURSOR
|
||||
|
@ -20,11 +20,6 @@
|
||||
#include "graphicsWindow.h"
|
||||
#include "buttonHandle.h"
|
||||
|
||||
#ifdef HAVE_XRANDR
|
||||
typedef unsigned short Rotation;
|
||||
typedef unsigned short SizeID;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Interfaces to the X11 window system.
|
||||
*/
|
||||
@ -76,9 +71,7 @@ protected:
|
||||
|
||||
private:
|
||||
X11_Cursor get_cursor(const Filename &filename);
|
||||
#ifdef HAVE_XCURSOR
|
||||
X11_Cursor read_ico(istream &ico);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
X11_Display *_display;
|
||||
@ -87,12 +80,8 @@ protected:
|
||||
Colormap _colormap;
|
||||
XIC _ic;
|
||||
XVisualInfo *_visual_info;
|
||||
|
||||
bool _have_xrandr;
|
||||
#ifdef HAVE_XRANDR
|
||||
Rotation _orig_rotation;
|
||||
SizeID _orig_size_id;
|
||||
#endif
|
||||
|
||||
LVecBase2i _fixed_size;
|
||||
|
||||
@ -109,6 +98,9 @@ protected:
|
||||
};
|
||||
pvector<MouseDeviceInfo> _mouse_device_info;
|
||||
|
||||
x11GraphicsPipe::pfn_XRRGetScreenInfo _XRRGetScreenInfo;
|
||||
x11GraphicsPipe::pfn_XRRSetScreenConfig _XRRSetScreenConfig;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
Loading…
x
Reference in New Issue
Block a user