mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
better internationalization input support
This commit is contained in:
parent
038230f7ec
commit
a84c3ffec4
@ -59,3 +59,15 @@ INLINE Atom glxGraphicsPipe::
|
||||
get_wm_delete_window() const {
|
||||
return _wm_delete_window;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: glxGraphicsPipe::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 glxGraphicsPipe::
|
||||
get_im() const {
|
||||
return _im;
|
||||
}
|
||||
|
@ -46,6 +46,8 @@ glxGraphicsPipe(const string &display) {
|
||||
display_spec = ExecutionEnvironment::get_environment_variable("DISPLAY");
|
||||
}
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
|
||||
_is_valid = false;
|
||||
_supports_fullscreen = false;
|
||||
_display = NULL;
|
||||
@ -61,6 +63,12 @@ glxGraphicsPipe(const string &display) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!XSupportsLocale()) {
|
||||
glxdisplay_cat.warning()
|
||||
<< "X does not support locale " << setlocale(LC_ALL, NULL) << "\n";
|
||||
}
|
||||
XSetLocaleModifiers("");
|
||||
|
||||
int errorBase, eventBase;
|
||||
if (!glXQueryExtension(_display, &errorBase, &eventBase)) {
|
||||
glxdisplay_cat.error()
|
||||
@ -75,6 +83,27 @@ glxGraphicsPipe(const string &display) {
|
||||
_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) {
|
||||
glxdisplay_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 the X atom number.
|
||||
_wm_delete_window = XInternAtom(_display, "WM_DELETE_WINDOW", false);
|
||||
}
|
||||
@ -86,6 +115,9 @@ glxGraphicsPipe(const string &display) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
glxGraphicsPipe::
|
||||
~glxGraphicsPipe() {
|
||||
if (_im) {
|
||||
XCloseIM(_im);
|
||||
}
|
||||
if (_display) {
|
||||
XCloseDisplay(_display);
|
||||
}
|
||||
|
@ -32,6 +32,8 @@ typedef int Window;
|
||||
typedef int XErrorEvent;
|
||||
typedef int XVisualInfo;
|
||||
typedef int Atom;
|
||||
typedef int XIM;
|
||||
typedef int XIC;
|
||||
#else
|
||||
#include <X11/Xlib.h>
|
||||
#include <GL/glx.h>
|
||||
@ -54,6 +56,7 @@ public:
|
||||
INLINE Display *get_display() const;
|
||||
INLINE int get_screen() const;
|
||||
INLINE Window get_root() const;
|
||||
INLINE XIM get_im() const;
|
||||
|
||||
INLINE Atom get_wm_delete_window() const;
|
||||
|
||||
@ -73,6 +76,7 @@ private:
|
||||
Display *_display;
|
||||
int _screen;
|
||||
Window _root;
|
||||
XIM _im;
|
||||
|
||||
Atom _wm_protocols;
|
||||
Atom _wm_delete_window;
|
||||
|
@ -48,6 +48,7 @@ glxGraphicsWindow(GraphicsPipe *pipe, GraphicsStateGuardian *gsg) :
|
||||
_display = glx_pipe->get_display();
|
||||
_screen = glx_pipe->get_screen();
|
||||
_xwindow = (Window)NULL;
|
||||
_ic = (XIC)NULL;
|
||||
_awaiting_configure = false;
|
||||
_wm_delete_window = glx_pipe->get_wm_delete_window();
|
||||
|
||||
@ -162,6 +163,10 @@ process_events() {
|
||||
|
||||
XEvent event;
|
||||
while (XCheckIfEvent(_display, &event, check_event, (char *)this)) {
|
||||
if (XFilterEvent(&event, None)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
WindowProperties properties;
|
||||
ButtonHandle button;
|
||||
|
||||
@ -195,13 +200,22 @@ process_events() {
|
||||
case KeyPress:
|
||||
{
|
||||
_input_devices[0].set_pointer_in_window(event.xkey.x, event.xkey.y);
|
||||
int index = ((event.xkey.state & ShiftMask) != 0) ? 1 : 0;
|
||||
|
||||
// First, get the keystroke, as modified by the shift key.
|
||||
KeySym key = XLookupKeysym(&event.xkey, index);
|
||||
if (key > 0 && key < 128) {
|
||||
// If it's an ASCII key, press it.
|
||||
_input_devices[0].keystroke(key);
|
||||
// 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.xkey, buffer, buffer_size, NULL,
|
||||
&status);
|
||||
if (status == XBufferOverflow) {
|
||||
glxdisplay_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]);
|
||||
}
|
||||
|
||||
// Now get the raw unshifted button.
|
||||
@ -349,9 +363,14 @@ set_properties_now(WindowProperties &properties) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void glxGraphicsWindow::
|
||||
close_window() {
|
||||
if (_ic != (XIC)NULL) {
|
||||
XDestroyIC(_ic);
|
||||
_ic = (XIC)NULL;
|
||||
}
|
||||
|
||||
if (_xwindow != (Window)NULL) {
|
||||
XDestroyWindow(_display, _xwindow);
|
||||
_xwindow = (Window)0;
|
||||
_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.
|
||||
@ -423,6 +442,19 @@ open_window() {
|
||||
}
|
||||
set_wm_properties(_properties);
|
||||
|
||||
// We don't specify any fancy properties of the XIC. It would be
|
||||
// nicer if we could support fancy IM's that want preedit callbacks,
|
||||
// etc., but that can wait until we have an X server that actually
|
||||
// supports these to test it on.
|
||||
_ic = XCreateIC
|
||||
(glx_pipe->get_im(),
|
||||
XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
|
||||
NULL);
|
||||
if (_ic == (XIC)NULL) {
|
||||
glxdisplay_cat.warning()
|
||||
<< "Couldn't create input context.\n";
|
||||
}
|
||||
|
||||
XMapWindow(_display, _xwindow);
|
||||
|
||||
return true;
|
||||
|
@ -65,6 +65,8 @@ private:
|
||||
int _screen;
|
||||
Window _xwindow;
|
||||
Colormap _colormap;
|
||||
XIC _ic;
|
||||
|
||||
long _event_mask;
|
||||
bool _awaiting_configure;
|
||||
Atom _wm_delete_window;
|
||||
|
Loading…
x
Reference in New Issue
Block a user