X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgbase%2Fdisplay.cpp;h=cb0cecc59869fbd6aca14c5b8171bd7d63784349;hb=dfa13b10b63d0a813db378c4212e90a32ee4d65c;hp=b39330be1c9fc3353cc387fad8f38241a8b7b765;hpb=881ad898c45954f95972091554af25d775b8c2a8;p=libs%2Fgui.git diff --git a/source/gbase/display.cpp b/source/gbase/display.cpp index b39330b..cb0cecc 100644 --- a/source/gbase/display.cpp +++ b/source/gbase/display.cpp @@ -1,20 +1,23 @@ /* $Id$ This file is part of libmspgbase -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2008 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ #include #ifndef WIN32 #include +#ifdef WITH_XF86VIDMODE #include #endif +#endif #include #include #include #include "display.h" #include "window.h" +#include "display_priv.h" using namespace std; @@ -52,7 +55,8 @@ int x_error_handler(Display *display, XErrorEvent *event) namespace Msp { namespace Graphics { -Display::Display(const string &disp_name) +Display::Display(const string &disp_name): + priv(new Private) { #ifdef WIN32 (void)disp_name; @@ -76,19 +80,20 @@ Display::Display(const string &disp_name) } #else if(disp_name.empty()) - display=XOpenDisplay(0); + priv->display=XOpenDisplay(0); else - display=XOpenDisplay(disp_name.c_str()); - if(!display) + priv->display=XOpenDisplay(disp_name.c_str()); + if(!priv->display) throw Exception("Couldn't open X display"); XSetErrorHandler(x_error_handler); - int screen=DefaultScreen(display); +#ifdef WITH_XF86VIDMODE + int screen=DefaultScreen(priv->display); int nmodes; XF86VidModeModeInfo **infos; - XF86VidModeGetAllModeLines(display, screen, &nmodes, &infos); + XF86VidModeGetAllModeLines(priv->display, screen, &nmodes, &infos); for(int i=0; idisplay, screen, &dotclock, &modeline); orig_mode=VideoMode(modeline.hdisplay, modeline.vdisplay); if(modeline.htotal && modeline.vtotal) orig_mode.rate=dotclock/(modeline.htotal*modeline.vtotal); #endif +#endif } Display::~Display() { #ifndef WIN32 - XCloseDisplay(display); - display=0; + XCloseDisplay(priv->display); + delete priv; #endif } -void Display::add_window(Window *wnd) +void Display::add_window(Window &wnd) { - windows[wnd->get_handle()]=wnd; + priv->windows[wnd.get_private().window]=&wnd; } -void Display::remove_window(Window *wnd) +void Display::remove_window(Window &wnd) { - windows.erase(wnd->get_handle()); + priv->windows.erase(wnd.get_private().window); } void Display::set_mode(const VideoMode &mode) { -#ifdef WIN32 +#if defined(WIN32) DEVMODE info; info.dmSize=sizeof(DEVMODE); info.dmFields=DM_PELSWIDTH|DM_PELSHEIGHT; @@ -143,12 +149,12 @@ void Display::set_mode(const VideoMode &mode) } ChangeDisplaySettings(&info, CDS_FULLSCREEN); -#else - int screen=DefaultScreen(display); +#elif defined(WITH_XF86VIDMODE) + int screen=DefaultScreen(priv->display); int nmodes; XF86VidModeModeInfo **infos; - XF86VidModeGetAllModeLines(display, screen, &nmodes, &infos); + XF86VidModeGetAllModeLines(priv->display, screen, &nmodes, &infos); for(int i=0; idisplay, screen, &info); + XF86VidModeSetViewPort(priv->display, screen, 0, 0); return; } } throw InvalidParameterValue("Requested mode not supported"); +#else + (void)mode; + throw Exception("Video mode switching not supported"); #endif } @@ -181,20 +190,42 @@ void Display::tick() else break; #else - int pending=XPending(display); + int pending=XPending(priv->display); if(pending==0) break; - for(int i=0; idisplay, &event.xevent); check_error(); - map::iterator j=windows.find(event.xany.window); - if(j!=windows.end()) + map::iterator j=priv->windows.find(event.xevent.xany.window); + if(j!=priv->windows.end()) + { + /* Filter keyboard autorepeat. If this packet is a KeyRelease and + the next one is a KeyPress with the exact same parameters, they + indicate autorepeat and must be dropped. */ + if(event.xevent.type==KeyRelease && !j->second->get_keyboard_autorepeat() && pending>0) + { + XKeyEvent &kev=event.xevent.xkey; + XEvent ev2; + XPeekEvent(priv->display, &ev2); + if(ev2.type==KeyPress) + { + XKeyEvent &kev2=ev2.xkey; + if(kev2.window==kev.window && kev2.time==kev.time && kev2.keycode==kev.keycode) + { + XNextEvent(priv->display, &ev2); + --pending; + continue; + } + } + } + j->second->event(event); + } } #endif }