LINUX.ORG.RU

Помогите разобраться в паре строчек [C][study][OpenGL][POSIX][Async]


0

1

Из одной книжки («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;
					}
			}
		}
Спасибо !

★★★★★

Непонятно что ли как select() работает? В мане написано

anonymous ()

Доп. вопрос: Тяжело перекинуть всю вот эту фунцию в отдельный thred ?

deterok ★★★★★ ()

ну и говнокдище -_-

anonymous ()

Достали темы с тегом C++, внутри которых код на C.

Deleted ()

асинхронному?

timeout.tv_usec = 20000;

я бы сказал, что спорадически и не быстрее, чем каждые 20мс

а хочешь асинхронно, лови SIGIO или SIGPOLL.

dimon555 ★★★★★ ()

select каждые 20 милисекунд провереяет можно ли писать в дескриптор(получен из этой функции ConnectionNumber(scr_Display)), который видимо связан с окном

зачем тебе отдельный тред? синхронизацию ведь придётся делать

dimon555 ★★★★★ ()
Ответ на: комментарий от dimon555

А ConnectionNumber(scr_Display) + 1 что дает, следующий описатель ?

deterok ★★★★★ ()
Ответ на: комментарий от deterok

это из man select

nfds is the highest-numbered file descriptor in any of the three sets,plus 1.

nfds это как раз первый параметр, а у тебя одно множество с одним дескриптором и к нему надо прибваить один.

dimon555 ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.