Beispiel #1
0
static void* _gfx_unix_thread_addr(

		void* arg)
{
	GFX_ThreadArgs data = *(GFX_ThreadArgs*)arg;
	free(arg);

	return GFX_UINT_TO_VOID(data.addr(data.args));
}
Beispiel #2
0
GFX_PlatformWindow _gfx_platform_window_create(

		const GFX_PlatformAttributes* attributes)
{
	/* Setup the x11 window */
	GFX_X11_Window window;
	window.monitor = attributes->monitor;
	window.context = NULL;
	window.flags   = 0;

	window.flags |=
		attributes->flags & GFX_WINDOW_RESIZABLE ?
		GFX_X11_RESIZABLE : 0;
	window.flags |=
		attributes->flags & GFX_WINDOW_HIDDEN ?
		GFX_X11_HIDDEN : 0;

	/* Get display mode & position */
	GFXDisplayMode mode;
	int x = window.monitor->x;
	int y = window.monitor->y;

	if(attributes->flags & GFX_WINDOW_FULLSCREEN)
	{
		window.flags |= GFX_X11_FULLSCREEN;

		GFX_X11_Mode* it = gfx_vector_at(
			&_gfx_x11.modes,
			window.monitor->modes[attributes->mode]
		);

		window.mode = it->id;
		mode = it->mode;
	}
	else
	{
		mode.width  = attributes->w;
		mode.height = attributes->h;
		mode.depth  = *attributes->depth;

		x += attributes->x;
		y += attributes->y;
	}

	/* Get FB Config */
	GLXFBConfig* config = _gfx_x11_get_config(
		window.monitor->screen,
		&mode.depth,
		attributes->flags & GFX_WINDOW_DOUBLE_BUFFER
	);

	if(!config) return NULL;

	/* Get visual from config */
	XVisualInfo* visual = glXGetVisualFromFBConfig(
		_gfx_x11.display,
		*config
	);

	window.config = *config;
	XFree(config);

	/* Create the window attributes */
	unsigned long mask = CWColormap | CWEventMask;
	XSetWindowAttributes attr;

	if(
		attributes->flags & GFX_WINDOW_BORDERLESS ||
		attributes->flags & GFX_WINDOW_FULLSCREEN)
	{
		/* Borderless window */
		mask |= CWBorderPixel;
		attr.border_pixel = 0;
	}

	/* Event mask & Color map */
	Window root =
		XRootWindowOfScreen(window.monitor->screen);

	attr.event_mask =
		KeyPressMask |
		KeyReleaseMask |
		PointerMotionMask |
		EnterWindowMask |
		LeaveWindowMask |
		ButtonPressMask |
		ButtonReleaseMask |
		StructureNotifyMask |
		FocusChangeMask;

	attr.colormap = XCreateColormap(
		_gfx_x11.display,
		root,
		visual->visual,
		AllocNone
	);

	/* Create the actual window */
	window.handle = XCreateWindow(
		_gfx_x11.display,
		root,
		x,
		y,
		mode.width,
		mode.height,
		0,
		visual->depth,
		InputOutput,
		visual->visual,
		mask,
		&attr
	);

	XFree(visual);

	if(window.handle)
	{
		/* Get properties to check for events */
		XWindowAttributes get;
		get.x      = 0;
		get.y      = 0;
		get.width  = 0;
		get.height = 0;
		XGetWindowAttributes(_gfx_x11.display, window.handle, &get);

		window.x      = get.x;
		window.y      = get.y;
		window.width  = get.width;
		window.height = get.height;

		/* Delete protocol & name */
		XSetWMProtocols(
			_gfx_x11.display,
			window.handle,
			&_gfx_x11.WM_DELETE_WINDOW,
			1);

		XStoreName(
			_gfx_x11.display,
			window.handle,
			attributes->name);

		/* Disable decorations */
		if(mask & CWBorderPixel)
		{
			unsigned long hints[5];
			hints[0] = MWM_HINTS_DECORATIONS;
			hints[2] = 0;

			XChangeProperty(
				_gfx_x11.display,
				window.handle,
				_gfx_x11.MOTIF_WM_HINTS,
				_gfx_x11.MOTIF_WM_HINTS,
				32,
				PropModeReplace,
				(unsigned char*)hints,
				5);
		}

		/* Bypass compositor */
		if(attributes->flags & GFX_WINDOW_FULLSCREEN)
		{
			unsigned long bypass = 1;

			XChangeProperty(
				_gfx_x11.display,
				window.handle,
				_gfx_x11.NET_WM_BYPASS_COMPOSITOR,
				XA_CARDINAL,
				32,
				PropModeReplace,
				(unsigned char*)&bypass,
				1
			);
		}

		/* Set size hints */
		if(!(attributes->flags & GFX_WINDOW_RESIZABLE))
		{
			XSizeHints* hints = XAllocSizeHints();
			hints->flags = PMinSize | PMaxSize;

			hints->min_width = mode.width;
			hints->max_width = mode.width;
			hints->min_height = mode.height;
			hints->max_height = mode.height;

			XSetWMNormalHints(_gfx_x11.display, window.handle, hints);

			XFree(hints);
		}

		/* Add window to vector */
		GFXVectorIterator it = gfx_vector_insert(
			&_gfx_x11.windows,
			&window,
			_gfx_x11.windows.end
		);

		if(it != _gfx_x11.windows.end)
		{
			/* Make it visible */
			/* Triggers FocusIn event for fullscreen */
			if(!(attributes->flags & GFX_WINDOW_HIDDEN))
				XMapWindow(_gfx_x11.display, window.handle);

			return GFX_UINT_TO_VOID(window.handle);
		}

		XDestroyWindow(_gfx_x11.display, window.handle);
	}

	XFreeColormap(_gfx_x11.display, attr.colormap);

	return NULL;
}
Beispiel #3
0
static void _gfx_x11_event_proc(

		XEvent* event)
{
	/* Get window */
	GFX_PlatformWindow window = GFX_UINT_TO_VOID(event->xany.window);

	switch(event->type)
	{
		/* Protocol messages */
		case ClientMessage :
		{
			if(event->xclient.data.l[0] == _gfx_x11.WM_DELETE_WINDOW)
				_gfx_event_window_close(window);

			break;
		}

		/* Resize & Move */
		case ConfigureNotify :
		{
			GFX_X11_Window* internal =
				_gfx_x11_get_window_from_handle(event->xany.window);

			if(!internal) break;

			if(
				internal->x != event->xconfigure.x ||
				internal->y != event->xconfigure.y)
			{
				internal->x = event->xconfigure.x;
				internal->y = event->xconfigure.y;

				int xS = 0;
				int yS = 0;

				GFX_X11_Monitor* monitor =
					_gfx_platform_window_get_monitor(window);

				if(monitor)
				{
					xS = monitor->x;
					yS = monitor->y;
				}

				_gfx_event_window_move(
					window,
					internal->x - xS,
					internal->y - yS
				);
			}

			if(
				internal->width != event->xconfigure.width ||
				internal->height != event->xconfigure.height)
			{
				internal->width = event->xconfigure.width;
				internal->height = event->xconfigure.height;

				_gfx_event_window_resize(
					window,
					internal->width,
					internal->height
				);
			}

			break;
		}

		/* Focus */
		case FocusIn :
		{
			/* Enter fullscreen */
			GFX_X11_Window* internal =
				_gfx_x11_get_window_from_handle(event->xany.window);

			if(!internal) break;

			if(
				(internal->flags & GFX_X11_FULLSCREEN) &&
				!(internal->flags & GFX_X11_HIDDEN))
			{
				_gfx_x11_enter_fullscreen(
					internal->monitor,
					event->xany.window,
					internal->mode
				);
			}

			_gfx_event_window_focus(window);

			break;
		}

		/* Blur */
		case FocusOut :
		{
			/* Leave fullscreen */
			GFX_X11_Window* internal =
				_gfx_x11_get_window_from_handle(event->xany.window);

			if(!internal) break;

			if(internal->flags & GFX_X11_FULLSCREEN)
			{
				_gfx_x11_leave_fullscreen(internal->monitor);

				if(!(internal->flags & GFX_X11_HIDDEN))
					XIconifyWindow(
						_gfx_x11.display,
						event->xany.window,
						XScreenNumberOfScreen(internal->monitor->screen)
					);
			}

			_gfx_event_window_blur(window);

			break;
		}

		/* Key press */
		case KeyPress :
		{
			GFXKey key;
			if(event->xkey.keycode > GFX_X11_MAX_KEYCODE) key = GFX_KEY_UNKNOWN;
			else key = _gfx_x11.keys[event->xkey.keycode];

			_gfx_event_key_press(
				window,
				key,
				_gfx_x11_get_key_state(event->xkey.state)
			);

			break;
		}

		/* Key release */
		case KeyRelease :
		{
			GFXKey key;
			if(event->xkey.keycode > GFX_X11_MAX_KEYCODE) key = GFX_KEY_UNKNOWN;
			else key = _gfx_x11.keys[event->xkey.keycode];

			_gfx_event_key_release(
				window,
				key,
				_gfx_x11_get_key_state(event->xkey.state)
			);

			break;
		}

		/* Pointer motion */
		case MotionNotify :
		{
			_gfx_event_mouse_move(
				window,
				event->xmotion.x,
				event->xmotion.y,
				_gfx_x11_get_key_state(event->xmotion.state)
			);

			break;
		}

		/* Pointer enter */
		case EnterNotify :
		{
			_gfx_event_mouse_enter(
				window,
				event->xcrossing.x,
				event->xcrossing.y,
				_gfx_x11_get_key_state(event->xcrossing.state)
			);

			break;
		}

		/* Pointer leave */
		case LeaveNotify :
		{
			_gfx_event_mouse_leave(
				window,
				event->xcrossing.x,
				event->xcrossing.y,
				_gfx_x11_get_key_state(event->xcrossing.state)
			);

			break;
		}

		/* Mouse key press */
		case ButtonPress :
		{
			GFXKeyState state = _gfx_x11_get_key_state(event->xbutton.state);
			int x = event->xbutton.x;
			int y = event->xbutton.y;

			switch(event->xbutton.button)
			{
				case Button1 :
					_gfx_event_mouse_press(window, GFX_MOUSE_KEY_LEFT, x, y, state);
					break;
				case Button2 :
					_gfx_event_mouse_press(window, GFX_MOUSE_KEY_MIDDLE, x, y, state);
					break;
				case Button3 :
					_gfx_event_mouse_press(window, GFX_MOUSE_KEY_RIGHT, x, y, state);
					break;

				case Button4 :
					_gfx_event_mouse_wheel(window, 0, 1, x, y, state);
					break;
				case Button5 :
					_gfx_event_mouse_wheel(window, 0, -1, x, y, state);
					break;
				case Button6 :
					_gfx_event_mouse_wheel(window, -1, 0, x, y, state);
					break;
				case Button7 :
					_gfx_event_mouse_wheel(window, 1, 0, x, y, state);
					break;
			}
		}

		/* Mouse key release */
		case ButtonRelease :
		{
			GFXKeyState state = _gfx_x11_get_key_state(event->xbutton.state);
			int x = event->xbutton.x;
			int y = event->xbutton.y;

			switch(event->xbutton.button)
			{
				case Button1 :
					_gfx_event_mouse_release(window, GFX_MOUSE_KEY_LEFT, x, y, state);
					break;
				case Button2 :
					_gfx_event_mouse_release(window, GFX_MOUSE_KEY_MIDDLE, x, y, state);
					break;
				case Button3 :
					_gfx_event_mouse_release(window, GFX_MOUSE_KEY_RIGHT, x, y, state);
					break;
			}
		}
	}
}