diff options
Diffstat (limited to 'platform/x11/os_x11.cpp')
-rw-r--r-- | platform/x11/os_x11.cpp | 146 |
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 }; |