예제 #1
0
파일: pugl_x11.c 프로젝트: ViktorNova/Carla
PuglStatus
puglProcessEvents(PuglView* view)
{
	XEvent event;
	while (XPending(view->impl->display) > 0) {
		XNextEvent(view->impl->display, &event);

		if (x_fib_handle_events(view->impl->display, &event)) {
			const int status = x_fib_status();

			if (status > 0) {
				char* const filename = x_fib_filename();
				x_fib_close(view->impl->display);
				if (view->fileSelectedFunc) {
					view->fileSelectedFunc(view, filename);
				}
				free(filename);
			} else if (status < 0) {
				x_fib_close(view->impl->display);
				if (view->fileSelectedFunc) {
					view->fileSelectedFunc(view, NULL);
				}
			}
			break;
		}

		if (event.xany.window != view->impl->win) {
			continue;
		}

		switch (event.type) {
		case MapNotify:
			puglReshape(view, view->width, view->height);
			break;
		case ConfigureNotify:
			if ((event.xconfigure.width != view->width) ||
			    (event.xconfigure.height != view->height)) {
				puglReshape(view,
				            event.xconfigure.width,
				            event.xconfigure.height);
			}
			break;
		case Expose:
			if (event.xexpose.count != 0) {
				break;
			}
			puglDisplay(view);
			break;
		case MotionNotify:
			setModifiers(view, event.xmotion.state, event.xmotion.time);
			if (view->motionFunc) {
				view->motionFunc(view, event.xmotion.x, event.xmotion.y);
			}
			break;
		case ButtonPress:
			setModifiers(view, event.xbutton.state, event.xbutton.time);
			if (event.xbutton.button >= 4 && event.xbutton.button <= 7) {
				if (view->scrollFunc) {
					float dx = 0, dy = 0;
					switch (event.xbutton.button) {
					case 4: dy =  1.0f; break;
					case 5: dy = -1.0f; break;
					case 6: dx = -1.0f; break;
					case 7: dx =  1.0f; break;
					}
					view->scrollFunc(view, event.xbutton.x, event.xbutton.y, dx, dy);
				}
				break;
			}
			// nobreak
		case ButtonRelease:
			setModifiers(view, event.xbutton.state, event.xbutton.time);
			if (view->mouseFunc &&
			    (event.xbutton.button < 4 || event.xbutton.button > 7)) {
				view->mouseFunc(view,
				                event.xbutton.button, event.type == ButtonPress,
				                event.xbutton.x, event.xbutton.y);
			}
			break;
		case KeyPress:
			setModifiers(view, event.xkey.state, event.xkey.time);
			dispatchKey(view, &event, true);
			break;
		case KeyRelease: {
			setModifiers(view, event.xkey.state, event.xkey.time);
			bool repeated = false;
			if (view->ignoreKeyRepeat &&
			    XEventsQueued(view->impl->display, QueuedAfterReading)) {
				XEvent next;
				XPeekEvent(view->impl->display, &next);
				if (next.type == KeyPress &&
				    next.xkey.time == event.xkey.time &&
				    next.xkey.keycode == event.xkey.keycode) {
					XNextEvent(view->impl->display, &event);
					repeated = true;
				}
			}
			if (!repeated) {
				dispatchKey(view, &event, false);
			}
		}	break;
		case ClientMessage: {
			char* type = XGetAtomName(view->impl->display,
			                          event.xclient.message_type);
			if (!strcmp(type, "WM_PROTOCOLS")) {
				if (view->closeFunc) {
					view->closeFunc(view);
					view->redisplay = false;
				}
			}
			XFree(type);
		}	break;
#ifdef PUGL_GRAB_FOCUS
		case EnterNotify:
			XSetInputFocus(view->impl->display, view->impl->win, RevertToPointerRoot, CurrentTime);
			break;
#endif
		default:
			break;
		}
	}

	if (view->redisplay) {
		puglDisplay(view);
	}

	return PUGL_SUCCESS;
}
예제 #2
0
void gl_handle_events () {
	XEvent event;
	while (XPending(_gl_display) > 0) {
		XNextEvent(_gl_display, &event);
#ifdef XDLG
		if (handle_xdlg_event(_gl_display, &event)) continue;
#endif
#ifdef XFIB
		if (x_fib_handle_events (_gl_display, &event)) {
			if (x_fib_status () > 0) {
				char *fn = x_fib_filename ();
				xapi_open (fn);
				free (fn);
			}
		}
#endif
		if (event.xany.window != _gl_win) {
			continue;
		}
#ifdef DND
		if (handle_dnd_event(_gl_display, _gl_win, &event)) continue;
#endif
		switch (event.type) {
			case MapNotify:
				loop_run=1;
				break;
			case UnmapNotify:
				loop_run=0;
				break;

			case ConfigureNotify:
				if (
						(event.xconfigure.width > 1 && event.xconfigure.height > 1)
						&&
						(event.xconfigure.width != _gl_width || event.xconfigure.height != _gl_height)
					 )
				{
					gl_reshape(event.xconfigure.width, event.xconfigure.height);
				}
				break;
			case Expose:
				if (event.xexpose.count != 0) {
					break;
				}
				_gl_reexpose = true;
				break;
			case MotionNotify:
				if (osd_seeking && ui_syncsource() == SYNC_NONE && OSD_mode & OSD_POS) {
					const float sk = calc_slider (event.xmotion.x, event.xmotion.y);
					if (sk >= 0)
						ui_sync_manual (sk);
				}
				break;
			case ButtonPress:
				if (event.xbutton.button == 1 && ui_syncsource() == SYNC_NONE && OSD_mode & OSD_POS) {
					const float sk = calc_slider (event.xbutton.x, event.xbutton.y);
					if (sk >= 0) {
						ui_sync_manual (sk);
						osd_seeking = 1;
						force_redraw = 1;
					}
				}
				break;
			case ButtonRelease:
				if (osd_seeking) {
					osd_seeking = 0;
					force_redraw = 1;
				} else
#ifdef XDLG
				if (event.xbutton.button == 3) {
					if (event.xbutton.x >= 0 && event.xbutton.x < _gl_width
							&& event.xbutton.y >= 0 && event.xbutton.y < _gl_height)
						show_x_dialog(_gl_display, _gl_win,
								event.xbutton.x_root, event.xbutton.y_root
								);
				} else
#endif
				xjglButton(event.xbutton.button);
				break;
			case ReparentNotify:
				break;
			case KeyPress:
				{
				KeySym  sym;
				char    buf[6] = {0,0,0,0,0,0};
				static XComposeStatus stat;
				int n = XLookupString(&event.xkey, buf, sizeof(buf), &sym, &stat);
				if (event.xkey.state & ControlMask && n == 1 && sym == XK_o) {
#ifdef XFIB
					if (!(interaction_override & OVR_LOADFILE)) {
						x_fib_cfg_filter_callback(fib_filter_movie_filename);
						x_fib_show (_gl_display, _gl_win, 0, 0);
					}
#endif
				}
				else if (event.xkey.state & ControlMask && n == 1 && sym == XK_w) {
					if (!(interaction_override & OVR_LOADFILE))
						xapi_close (NULL);
				}
				else if (event.xkey.state & ControlMask && n == 1 && sym == XK_q) {
					if (!(interaction_override&OVR_QUIT_WMG))
						loop_flag = 0;
				}
				else if (n == 1) {
					xjglKeyPress(sym, buf);
				}
				}
				break;
			case ClientMessage:
				if (!strcmp(XGetAtomName(_gl_display, event.xclient.message_type), "WM_PROTOCOLS")) {
					if ((interaction_override&OVR_QUIT_WMG) == 0) loop_flag=0;
				}
				break;
			default:
				break;
		}
	}
	if (_gl_reexpose) {
		_gl_reexpose = false;
		force_redraw = true;
	}

	static int periodic = 10;
	if (--periodic == 0) {
		periodic = 50 * framerate; // we should use 1/delay if delay > 0
		XResetScreenSaver(_gl_display);
		// ..or spawn `xdg-screensaver`
	}
}