summaryrefslogtreecommitdiff
path: root/platform/x11/os_x11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/x11/os_x11.cpp')
-rw-r--r--platform/x11/os_x11.cpp146
1 files changed, 113 insertions, 33 deletions
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 2cb8247799..e0dc594441 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -168,6 +168,55 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
visual_server =memnew(VisualServerWrapMT(visual_server,get_render_thread_mode()==RENDER_SEPARATE_THREAD));
}
+ // borderless fullscreen window mode
+ if (current_videomode.fullscreen) {
+ // needed for lxde/openbox, possibly others
+ Hints hints;
+ Atom property;
+ hints.flags = 2;
+ hints.decorations = 0;
+ property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True);
+ XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5);
+ XMapRaised(x11_display, x11_window);
+ XWindowAttributes xwa;
+ XGetWindowAttributes(x11_display, DefaultRootWindow(x11_display), &xwa);
+ XMoveResizeWindow(x11_display, x11_window, 0, 0, xwa.width, xwa.height);
+
+ // code for netwm-compliants
+ XEvent xev;
+ Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False);
+ Atom fullscreen = XInternAtom(x11_display, "_NET_WM_STATE_FULLSCREEN", False);
+
+ memset(&xev, 0, sizeof(xev));
+ xev.type = ClientMessage;
+ xev.xclient.window = x11_window;
+ xev.xclient.message_type = wm_state;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = 1;
+ xev.xclient.data.l[1] = fullscreen;
+ xev.xclient.data.l[2] = 0;
+
+ XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev);
+ }
+
+ // disable resizeable window
+ if (!current_videomode.resizable) {
+ XSizeHints *xsh;
+ xsh = XAllocSizeHints();
+ xsh->flags = PMinSize | PMaxSize;
+ XWindowAttributes xwa;
+ if (current_videomode.fullscreen) {
+ XGetWindowAttributes(x11_display,DefaultRootWindow(x11_display),&xwa);
+ } else {
+ XGetWindowAttributes(x11_display,x11_window,&xwa);
+ }
+ xsh->min_width = xwa.width;
+ xsh->max_width = xwa.width;
+ xsh->min_height = xwa.height;
+ xsh->max_height = xwa.height;
+ XSetWMNormalHints(x11_display, x11_window, xsh);
+ }
+
AudioDriverManagerSW::get_driver(p_audio_driver)->set_singleton();
if (AudioDriverManagerSW::get_driver(p_audio_driver)->init()!=OK) {
@@ -204,6 +253,20 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
XChangeWindowAttributes(x11_display, x11_window,CWEventMask,&new_attr);
+ XClassHint* classHint;
+
+ /* set the titlebar name */
+ XStoreName(x11_display, x11_window, "Godot");
+
+ /* set the name and class hints for the window manager to use */
+ classHint = XAllocClassHint();
+ if (classHint) {
+ classHint->res_name = "Godot";
+ classHint->res_class = "Godot";
+ }
+ XSetClassHint(x11_display, x11_window, classHint);
+ XFree(classHint);
+
wm_delete = XInternAtom(x11_display, "WM_DELETE_WINDOW", true);
XSetWMProtocols(x11_display, x11_window, &wm_delete, 1);
@@ -368,7 +431,6 @@ void OS_X11::finalize() {
void OS_X11::set_mouse_mode(MouseMode p_mode) {
- print_line("WUTF "+itos(p_mode)+" old "+itos(mouse_mode));
if (p_mode==mouse_mode)
return;
@@ -480,7 +542,7 @@ unsigned int OS_X11::get_mouse_button_state(unsigned int p_x11_state) {
return state;
}
-void OS_X11::handle_key_event(XKeyEvent *p_event) {
+void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) {
// X11 functions don't know what const is
@@ -591,17 +653,9 @@ void OS_X11::handle_key_event(XKeyEvent *p_event) {
// To detect them, i use XPeekEvent and check that their
// difference in time is below a treshold.
- bool echo=false;
-
- if (xkeyevent->type == KeyPress) {
-
- // saved the time of the last keyrelease to see
- // if it's the same as this keypress.
- if (xkeyevent->time==last_keyrelease_time)
- echo=true;
- } else {
-
+ if (xkeyevent->type != KeyPress) {
+
// make sure there are events pending,
// so this call won't block.
if (XPending(x11_display)>0) {
@@ -615,17 +669,21 @@ void OS_X11::handle_key_event(XKeyEvent *p_event) {
// not very helpful today.
::Time tresh=ABS(peek_event.xkey.time-xkeyevent->time);
- if (peek_event.type == KeyPress && tresh<5 )
- echo=true;
+ if (peek_event.type == KeyPress && tresh<5 ) {
+ KeySym rk;
+ nbytes=XLookupString((XKeyEvent*)&peek_event, str, 256, &rk, NULL);
+ if (rk==keysym_keycode) {
+ XEvent event;
+ XNextEvent(x11_display, &event); //erase next event
+ handle_key_event( (XKeyEvent*)&event,true );
+ return; //ignore current, echo next
+ }
+ }
// use the time from peek_event so it always works
- last_keyrelease_time=peek_event.xkey.time;
- } else {
- last_keyrelease_time=xkeyevent->time;
}
- // save the time to check for echo when keypress happens
-
+ // save the time to check for echo when keypress happens
}
@@ -643,7 +701,7 @@ void OS_X11::handle_key_event(XKeyEvent *p_event) {
event.key.scancode=keycode;
event.key.unicode=unicode;
- event.key.echo=echo;
+ event.key.echo=p_echo;
if (event.key.scancode==KEY_BACKTAB) {
//make it consistent accross platforms.
@@ -1017,7 +1075,7 @@ String OS_X11::get_name() {
Error OS_X11::shell_open(String p_uri) {
-
+ return ERR_UNAVAILABLE;
}
@@ -1036,10 +1094,12 @@ void OS_X11::close_joystick(int p_id) {
close(joysticks[p_id].fd);
joysticks[p_id].fd = -1;
};
+ input->joy_connection_changed(p_id, false, "");
};
void OS_X11::probe_joystick(int p_id) {
#ifndef __FreeBSD__
+
if (p_id == -1) {
for (int i=0; i<JOYSTICKS_MAX; i++) {
@@ -1049,7 +1109,8 @@ void OS_X11::probe_joystick(int p_id) {
return;
};
- close_joystick(p_id);
+ if (joysticks[p_id].fd != -1)
+ close_joystick(p_id);
const char *joy_names[] = {
"/dev/input/js%d",
@@ -1062,12 +1123,22 @@ void OS_X11::probe_joystick(int p_id) {
char fname[64];
sprintf(fname, joy_names[i], p_id);
- int fd = open(fname, O_RDONLY);
+ int fd = open(fname, O_RDONLY|O_NONBLOCK);
if (fd != -1) {
- fcntl( fd, F_SETFL, O_NONBLOCK );
+ //fcntl( fd, F_SETFL, O_NONBLOCK );
joysticks[p_id] = Joystick(); // this will reset the axis array
joysticks[p_id].fd = fd;
+
+ String name;
+ char namebuf[255] = {0};
+ if (ioctl(fd, JSIOCGNAME(sizeof(namebuf)), namebuf) >= 0) {
+ name = namebuf;
+ } else {
+ name = "error";
+ };
+
+ input->joy_connection_changed(p_id, true, name);
break; // don't try the next name
};
@@ -1088,8 +1159,11 @@ void OS_X11::process_joysticks() {
InputEvent ievent;
for (int i=0; i<JOYSTICKS_MAX; i++) {
- if (joysticks[i].fd == -1)
- continue;
+ if (joysticks[i].fd == -1) {
+ probe_joystick(i);
+ if (joysticks[i].fd == -1)
+ continue;
+ };
ievent.device = i;
while ( (bytes = read(joysticks[i].fd, &events, sizeof(events))) > 0) {
@@ -1107,8 +1181,9 @@ void OS_X11::process_joysticks() {
case JS_EVENT_AXIS:
- if (joysticks[i].last_axis[event.number] != event.value) {
+ //if (joysticks[i].last_axis[event.number] != event.value) {
+ /*
if (event.number==5 || event.number==6) {
int axis=event.number-5;
@@ -1155,17 +1230,19 @@ void OS_X11::process_joysticks() {
dpad_last[axis]=val;
}
+ */
//print_line("ev: "+itos(event.number)+" val: "+ rtos((float)event.value / (float)MAX_JOY_AXIS));
- if (event.number >= JOY_AXIS_MAX)
- break;
+ //if (event.number >= JOY_AXIS_MAX)
+ // break;
//ERR_FAIL_COND(event.number >= JOY_AXIS_MAX);
ievent.type = InputEvent::JOYSTICK_MOTION;
ievent.ID = ++event_id;
- ievent.joy_motion.axis = _pc_joystick_get_native_axis(event.number);
+ ievent.joy_motion.axis = event.number; //_pc_joystick_get_native_axis(event.number);
ievent.joy_motion.axis_value = (float)event.value / (float)MAX_JOY_AXIS;
- joysticks[i].last_axis[event.number] = event.value;
+ if (event.number < JOY_AXIS_MAX)
+ joysticks[i].last_axis[event.number] = event.value;
input->parse_input_event( ievent );
- };
+ //};
break;
case JS_EVENT_BUTTON:
@@ -1173,13 +1250,16 @@ void OS_X11::process_joysticks() {
ievent.type = InputEvent::JOYSTICK_BUTTON;
ievent.ID = ++event_id;
- ievent.joy_button.button_index = _pc_joystick_get_native_button(event.number);
+ ievent.joy_button.button_index = event.number; // _pc_joystick_get_native_button(event.number);
ievent.joy_button.pressed = event.value;
input->parse_input_event( ievent );
break;
};
};
};
+ if (bytes == 0 || (bytes < 0 && errno != EAGAIN)) {
+ close_joystick(i);
+ };
};
#endif
};