Из одной книжки («OpenGL Суперкнига»), достал код по инициализации OpenGL в linux, но мне непонятно как работает его часть по асинхронному реагированию на события, вернее сказать каким образом он начинает асинхронно реагировать. Если можно по подробнее.
Display* scr_Display;
Window wnd_Handle, wnd_Root;
XSetWindowAttributes wnd_Attr;
unsigned int wnd_ValueMask;
boolean wnd_FullScreen = false;
fd_set input;
bool mapped = false;
int wnd_X = 0, wnd_Y = 0, wnd_Width = 800, wnd_Height = 600;
struct timeval timeout;
int ready;
Atom state;
XEvent event;
scr_Display = XOpenDisplay(NULL);
wnd_Root = DefaultRootWindow( scr_Display );
wnd_Attr.event_mask = KeyPressMask | StructureNotifyMask
| PropertyChangeMask;
wnd_ValueMask = CWEventMask | CWBorderPixel | CWBackPixel;
wnd_Handle = XCreateWindow(scr_Display, wnd_Root, wnd_X, wnd_Y, wnd_Width,
wnd_Height, 0, CopyFromParent, InputOutput, CopyFromParent,
wnd_ValueMask, &wnd_Attr);
XMapWindow(scr_Display, wnd_Handle);
// один раз надо бы инициализировать
XSync(scr_Display, 1);
for (;;)
{
if (mapped)
{
FD_ZERO(&input);
FD_SET(ConnectionNumber(scr_Display),&input);
timeout.tv_sec = 0;
timeout.tv_usec = 20000;
ready = select(ConnectionNumber(scr_Display) + 1, &input, NULL, ///??????????????
NULL, &timeout);
}
else
ready = 1;
if (ready)
{
XNextEvent(scr_Display, &event);
switch (event.type)
{
case MapNotify:
mapped = true;
break;
case UnmapNotify:
mapped = false;
break;
case KeyPress:
if (event.xkey.keycode == 24)
{
XEvent eventChange;
wnd_FullScreen = !wnd_FullScreen;
// устанвливаем значение атому через отсылку сообщения
memset(&event, 0, sizeof(XEvent));
eventChange.type = ClientMessage;
eventChange.xclient.type = ClientMessage;
eventChange.xclient.send_event = 1;
eventChange.xclient.window = wnd_Handle;
eventChange.xclient.message_type = XInternAtom(
scr_Display, "_NET_WM_STATE", 0);
eventChange.xclient.format = 32;
eventChange.xclient.data.l[0] = wnd_FullScreen;
eventChange.xclient.data.l[1] = XInternAtom(
scr_Display, "_NET_WM_STATE_FULLSCREEN", 0);
XSendEvent(
scr_Display,
DefaultRootWindow(scr_Display),
0,
SubstructureRedirectMask
| SubstructureNotifyMask, &eventChange);
XFlush(scr_Display);
sleep(5);
XCloseDisplay(scr_Display);
break;
}
}
}