X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgraphics%2Fdisplay.cpp;h=de5a06952a58e8efa8f3e956ee0f949126775426;hb=d163b3628fee61ea4acad0e9429aab904b03bf70;hp=da036a1baa9a4174049f40920fd0575e42fc0ceb;hpb=1023b38fa278cea71fba3d2881e1bfde930cd025;p=libs%2Fgui.git diff --git a/source/graphics/display.cpp b/source/graphics/display.cpp index da036a1..de5a069 100644 --- a/source/graphics/display.cpp +++ b/source/graphics/display.cpp @@ -1,242 +1,61 @@ -#include -#ifndef WIN32 -#include -#ifdef WITH_XF86VIDMODE -#include -#endif -#endif -#include -#include #include "display.h" +#include "display_private.h" #include "window.h" -#include "display_priv.h" using namespace std; -namespace { - -bool error_flag = false; -std::string error_msg; - -#ifndef WIN32 -int x_error_handler(Display *display, XErrorEvent *event) -{ - char err[128]; - XGetErrorText(display, event->error_code, err, sizeof(err)); - - string request_code = Msp::lexical_cast(static_cast(event->request_code)); - char req[128]; - XGetErrorDatabaseText(display, "XRequest", request_code.c_str(), request_code.c_str(), req, sizeof(req)); - - string msg = Msp::format("Request %s failed with %s [%08X]", req, err, event->resourceid); - if(error_flag) - cerr<<"Discarding error: "<display = XOpenDisplay(0); - else - priv->display = XOpenDisplay(disp_name.c_str()); - if(!priv->display) - throw runtime_error("XOpenDisplay"); - - XSetErrorHandler(x_error_handler); - -#ifdef WITH_XF86VIDMODE - int screen = DefaultScreen(priv->display); - - int nmodes; - XF86VidModeModeInfo **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 + priv->windows[wnd.get_private().window] = &wnd; } -Display::~Display() +void Display::remove_window(Window &wnd) { -#ifndef WIN32 - XCloseDisplay(priv->display); - delete priv; -#endif + priv->windows.erase(wnd.get_private().window); } -void Display::add_window(Window &wnd) +const VideoMode &Display::get_desktop_mode() const { - priv->windows[wnd.get_private().window] = &wnd; + if(!primary_monitor || !primary_monitor->desktop_mode) + throw logic_error("no desktop mode"); + return *primary_monitor->desktop_mode; } -void Display::remove_window(Window &wnd) +void Display::restore_mode() { - priv->windows.erase(wnd.get_private().window); + for(list::const_iterator i=monitors.begin(); i!=monitors.end(); ++i) + if(i->desktop_mode) + set_mode(*i->desktop_mode, false); } -void Display::set_mode(const VideoMode &mode) +const VideoMode *Display::find_mode(const VideoMode &mode) const { -#if defined(WIN32) - DEVMODE info; - info.dmSize = sizeof(DEVMODE); - info.dmFields = DM_PELSWIDTH|DM_PELSHEIGHT; - info.dmPelsWidth = mode.width; - info.dmPelsHeight = mode.height; - if(mode.rate) + for(list::const_iterator i=modes.begin(); i!=modes.end(); ++i) { - info.dmFields |= DM_DISPLAYFREQUENCY; - info.dmDisplayFrequency = mode.rate; + if(mode.monitor && i->monitor!=mode.monitor) + continue; + if(mode.rate && i->rate!=mode.rate) + continue; + if(i->width==mode.width && i->height==mode.height) + return &*i; } - LONG ret = ChangeDisplaySettings(&info, CDS_FULLSCREEN); - if(ret!=DISP_CHANGE_SUCCESSFUL) - throw unsupported_video_mode(mode); -#elif defined(WITH_XF86VIDMODE) - int screen = DefaultScreen(priv->display); - - int nmodes; - XF86VidModeModeInfo **infos; - XF86VidModeGetAllModeLines(priv->display, screen, &nmodes, &infos); - for(int i=0; idisplay, screen, &info); - XF86VidModeSetViewPort(priv->display, screen, 0, 0); - return; - } - } + return 0; +} - throw unsupported_video_mode(mode); -#else - (void)mode; - throw runtime_error("no xf86vidmode support"); -#endif +const VideoMode *Display::find_mode(unsigned width, unsigned height) const +{ + return find_mode(VideoMode(width, height)); } void Display::tick() { check_error(); - while(1) - { -#ifdef WIN32 - MSG msg; - if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) - DispatchMessage(&msg); - else - break; -#else - int pending = XPending(priv->display); - if(pending==0) - break; - - for(; pending--;) - { - Window::Event event; - XNextEvent(priv->display, &event.xevent); - - check_error(); - - 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 - } -} - -void Display::check_error() -{ - if(error_flag) - { - error_flag = false; - throw runtime_error(error_msg); - } + while(process_events()) ; } } // namespace Graphics