3 This file is part of libmspgbase
4 Copyright © 2007 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
11 #include <X11/extensions/xf86vmode.h>
13 #include <msp/core/except.h>
14 #include <msp/strings/formatter.h>
15 #include <msp/strings/lexicalcast.h>
23 bool error_flag=false;
24 std::string error_msg;
27 int x_error_handler(Display *display, XErrorEvent *event)
30 XGetErrorText(display, event->error_code, err, sizeof(err));
32 string request_code=Msp::lexical_cast(static_cast<int>(event->request_code));
34 XGetErrorDatabaseText(display, "XRequest", request_code.c_str(), request_code.c_str(), req, sizeof(req));
36 string msg=Msp::format("Request %s failed with %s [%08X]", req, err, event->resourceid);
38 cerr<<"Discarding error: "<<msg<<'\n';
55 Display::Display(const string &disp_name)
59 display=XOpenDisplay(0);
61 display=XOpenDisplay(disp_name.c_str());
63 throw Exception("Couldn't open X display");
65 XSetErrorHandler(x_error_handler);
67 int screen=DefaultScreen(display);
70 XF86VidModeModeInfo **infos;
71 XF86VidModeGetAllModeLines(display, screen, &nmodes, &infos);
72 for(int i=0; i<nmodes; ++i)
74 XF86VidModeModeInfo &info=*infos[i];
76 VideoMode mode(info.hdisplay, info.vdisplay);
77 mode.rate=info.dotclock/(info.htotal*info.vtotal);
78 modes.push_back(mode);
83 XF86VidModeModeLine modeline;
85 XF86VidModeGetModeLine(display, screen, &dotclock, &modeline);
86 orig_mode=VideoMode(modeline.hdisplay, modeline.vdisplay);
87 orig_mode.rate=dotclock/(modeline.htotal*modeline.vtotal);
96 XCloseDisplay(display);
101 void Display::add_window(Window *wnd)
103 windows[wnd->get_handle()]=wnd;
106 void Display::remove_window(Window *wnd)
108 windows.erase(wnd->get_handle());
111 void Display::set_mode(const VideoMode &mode)
114 int screen=DefaultScreen(display);
117 XF86VidModeModeInfo **infos;
118 XF86VidModeGetAllModeLines(display, screen, &nmodes, &infos);
119 for(int i=0; i<nmodes; ++i)
121 XF86VidModeModeInfo &info=*infos[i];
123 unsigned rate=info.dotclock/(info.htotal*info.vtotal);
124 if(info.hdisplay==mode.width && info.vdisplay==mode.height && (mode.rate==0 || rate==mode.rate))
126 XF86VidModeSwitchToMode(display, screen, &info);
127 XF86VidModeSetViewPort(display, screen, 0, 0);
132 throw InvalidParameterValue("Requested mode not supported");
146 if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
147 DispatchMessage(&msg);
151 int pending=XPending(display);
155 for(int i=0; i<pending; ++i)
158 XNextEvent(display, &event);
162 map<WindowHandle, Window *>::iterator j=windows.find(event.xany.window);
164 j->second->event(event);
170 void Display::check_error()
175 throw Exception(error_msg);
179 } // namespace Graphics