3 This file is part of libmspgbase
4 Copyright © 2007 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
10 #include <X11/extensions/xf86vmode.h>
11 #include <msp/core/except.h>
12 #include <msp/strings/formatter.h>
13 #include <msp/strings/lexicalcast.h>
21 bool error_flag=false;
22 std::string error_msg;
24 int x_error_handler(Display *display, XErrorEvent *event)
27 XGetErrorText(display, event->error_code, err, sizeof(err));
29 string request_code=Msp::lexical_cast(static_cast<int>(event->request_code));
31 XGetErrorDatabaseText(display, "XRequest", request_code.c_str(), request_code.c_str(), req, sizeof(req));
33 string msg=Msp::format("Request %s failed with %s [%08X]", req, err, event->resourceid);
35 cerr<<"Discarding error: "<<msg<<'\n';
51 Display::Display(const string &disp_name)
54 display=XOpenDisplay(0);
56 display=XOpenDisplay(disp_name.c_str());
58 throw Exception("Couldn't open X display");
60 XSetErrorHandler(x_error_handler);
63 XF86VidModeModeInfo **infos;
64 XF86VidModeGetAllModeLines(display, DefaultScreen(display), &nmodes, &infos);
65 for(int i=0; i<nmodes; ++i)
67 XF86VidModeModeInfo &info=*infos[i];
70 mode.width=info.hdisplay;
71 mode.height=info.vdisplay;
72 mode.rate=info.dotclock/(info.htotal*info.vtotal);
73 modes.push_back(mode);
79 XCloseDisplay(display);
83 void Display::add_window(Window *wnd)
85 windows[wnd->get_handle()]=wnd;
88 void Display::remove_window(Window *wnd)
90 windows.erase(wnd->get_handle());
93 void Display::set_mode(const VideoMode &mode)
95 int screen=DefaultScreen(display);
98 XF86VidModeModeInfo **infos;
99 XF86VidModeGetAllModeLines(display, screen, &nmodes, &infos);
100 for(int i=0; i<nmodes; ++i)
102 XF86VidModeModeInfo &info=*infos[i];
104 unsigned rate=info.dotclock/(info.htotal*info.vtotal);
105 if(info.hdisplay==mode.width && info.vdisplay==mode.height && rate==mode.rate)
107 XF86VidModeSwitchToMode(display, screen, &info);
112 throw InvalidParameterValue("Requested mode not supported");
121 int pending=XPending(display);
125 for(int i=0; i<pending; ++i)
128 XNextEvent(display, &event);
132 map<WindowHandle, Window *>::iterator j=windows.find(event.xany.window);
134 j->second->event(event);
139 void Display::check_error()
144 throw Exception(error_msg);
148 } // namespace Graphics