Esempio n. 1
0
File: mesh.c Progetto: Ckef/Groufix
GFXMeshBuffer gfx_mesh_add_buffer(

		GFXMesh*     mesh,
		size_t       size,
		const void*  data)
{
	GFX_Mesh* internal = (GFX_Mesh*)mesh;

	/* Insert new vector element */
	GFXSharedBuffer* it = gfx_vector_insert(
		&internal->buffers,
		NULL,
		internal->buffers.end
	);

	if(it == internal->buffers.end) return 0;

	/* Create new shared buffer */
	/* Align with largest integer so index offset can be aligned */
	GFXDataType type;
	type.unpacked = GFX_LARGE_INTEGER;

	if(!gfx_shared_buffer_init_align(it, size, data, type))
	{
		gfx_vector_erase(&internal->buffers, it);
		return 0;
	}

	/* Return ID */
	return gfx_vector_get_size(&internal->buffers);
}
Esempio n. 2
0
GFX_Win32_Window* _gfx_win32_window_dummy_create(void)
{
	/* Create a dummy window */
	GFX_Win32_Window window;
	window.monitor = NULL;
	window.context = NULL;
	window.flags   = GFX_WIN32_HIDDEN;

	window.handle = CreateWindow(
		GFX_WIN32_WINDOW_CLASS_DUMMY,
		L"",
		0,
		0, 0,
		0, 0,
		NULL, NULL,
		GetModuleHandle(NULL),
		NULL
	);

	if(window.handle)
	{
		/* Add window to vector */
		GFXVectorIterator it = gfx_vector_insert(
			&_gfx_win32.windows,
			&window,
			_gfx_win32.windows.end
		);

		if(it != _gfx_win32.windows.end)
		{
			/* Set pixel format */
			GFXColorDepth depth;
			depth.redBits   = 0;
			depth.greenBits = 0;
			depth.blueBits  = 0;

			_gfx_win32_set_pixel_format(window.handle, &depth, 0);

			return it;
		}

		/* Nevermind */
		DestroyWindow(window.handle);
	}

	return NULL;
}
Esempio n. 3
0
static size_t _gfx_x11_init_modes(

		Screen*              scr,
		XRRScreenResources*  res)
{
	/* Split depth */
	GFXColorDepth depth;
	_gfx_split_depth(
		XDefaultDepthOfScreen(scr),
		&depth.redBits,
		&depth.greenBits,
		&depth.blueBits
	);

	/* Reserve space for all modes */
	size_t first = gfx_vector_get_size(&_gfx_x11.modes);
	gfx_vector_reserve(&_gfx_x11.modes, first + res->nmode);

	unsigned int i;
	for(i = 0; i < res->nmode; ++i)
	{
		/* Skip refresh rate of zero */
		unsigned int refresh = 0;
		if(res->modes[i].hTotal && res->modes[i].vTotal)
		{
			refresh =
				(unsigned int)lround((double)res->modes[i].dotClock /
				((double)res->modes[i].hTotal * (double)res->modes[i].vTotal));
		}

		if(refresh)
		{
			/* Create new mode */
			GFX_X11_Mode mode;
			mode.id           = res->modes[i].id;
			mode.mode.width   = res->modes[i].width;
			mode.mode.height  = res->modes[i].height;
			mode.mode.depth   = depth;
			mode.mode.refresh = refresh;

			gfx_vector_insert(&_gfx_x11.modes, &mode, _gfx_x11.modes.end);
		}
	}

	return first;
}
Esempio n. 4
0
File: mesh.c Progetto: Ckef/Groufix
static GFXMeshLayout _gfx_mesh_insert_layout(

		GFX_Mesh*         mesh,
		GFXVertexLayout*  layout)
{
	GFXVectorIterator it = gfx_vector_insert(
		&mesh->layouts,
		&layout,
		mesh->layouts.end
	);

	if(it == mesh->layouts.end)
	{
		/* Free on failure */
		gfx_vertex_layout_free(layout);
		return 0;
	}

	/* Return the ID */
	return gfx_vector_get_size(&mesh->layouts);
}
Esempio n. 5
0
static int _gfx_thread_pool_push(

		GFX_Pool*  pool,
		GFX_Task   task)
{
	/* Insert the new element */
	size_t elem = gfx_vector_get_size(&pool->tasks);

	GFX_Task* et = gfx_vector_insert(
		&pool->tasks,
		&task,
		pool->tasks.end
	);

	if(et == pool->tasks.end) return 0;

	/* Correct heap again */
	while(elem > 0)
	{
		/* Get parent and compare */
		size_t parent = (elem - 1) >> 1;
		GFX_Task* pt = gfx_vector_at(&pool->tasks, parent);

		if(pt->priority <= et->priority)
			break;

		/* Swap */
		task = *pt;
		*pt = *et;
		*et = task;

		elem = parent;
	}

	return 1;
}
Esempio n. 6
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;
}
Esempio n. 7
0
GFX_PlatformWindow _gfx_platform_window_create(

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

	window.flags |=
		attributes->flags & GFX_WINDOW_RESIZABLE ?
		GFX_WIN32_RESIZABLE : 0;
	window.flags |=
		attributes->flags & GFX_WINDOW_HIDDEN ?
		GFX_WIN32_HIDDEN : 0;

	/* Display mode, style and window rectangle */
	DWORD styleEx =
		WS_EX_APPWINDOW;
	DWORD style =
		(!(attributes->flags & GFX_WINDOW_HIDDEN) ?
		WS_VISIBLE : 0);

	GFXColorDepth depth;
	RECT rect;

	rect.left = window.monitor->x;
	rect.top = window.monitor->y;

	if(attributes->flags & GFX_WINDOW_FULLSCREEN)
	{
		/* Display mode */
		window.flags |= GFX_WIN32_FULLSCREEN;

		window.mode = gfx_vector_at(
			&_gfx_win32.modes,
			window.monitor->modes + attributes->mode);

		_gfx_split_depth(
			window.mode->dmBitsPerPel,
			&depth.redBits,
			&depth.greenBits,
			&depth.blueBits);

		/* Style and rectangle */
		rect.right = window.mode->dmPelsWidth;
		rect.bottom = window.mode->dmPelsHeight;

		styleEx |= WS_EX_TOPMOST;
		style |= WS_POPUP;
	}
	else
	{
		/* Color depth and rectangle */
		depth       = *attributes->depth;
		rect.right  = attributes->w;
		rect.bottom = attributes->h;

		rect.left += attributes->x;
		rect.top += attributes->y;

		/* Style */
		style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;

		if(!(attributes->flags & GFX_WINDOW_BORDERLESS))
		{
			/* With a border */
			styleEx |=
				WS_EX_WINDOWEDGE;

			style |=
				WS_CAPTION |
				WS_MINIMIZEBOX |
				WS_OVERLAPPED |
				WS_SYSMENU;

			/* With size options */
			if(attributes->flags & GFX_WINDOW_RESIZABLE) style |=
				WS_MAXIMIZEBOX |
				WS_SIZEBOX;
		}
		else
		{
			/* Borderless */
			styleEx |= WS_EX_TOPMOST;
			style |= WS_POPUP;
		}
	}

	rect.right += rect.left;
	rect.bottom += rect.top;

	/* Make sure the client area is the specified size */
	AdjustWindowRectEx(&rect, style, FALSE, styleEx);

	/* Convert name to UTF-16 */
	WCHAR* name = _gfx_win32_utf8_to_utf16(attributes->name);

	/* Create the actual window */
	window.handle = CreateWindowEx(
		styleEx,
		GFX_WIN32_WINDOW_CLASS,
		name,
		style,
		rect.left,
		rect.top,
		rect.right - rect.left,
		rect.bottom - rect.top,
		NULL,
		NULL,
		GetModuleHandle(NULL),
		NULL
	);

	free(name);

	if(window.handle)
	{
		/* Add window to vector */
		GFXVectorIterator it = gfx_vector_insert(
			&_gfx_win32.windows,
			&window,
			_gfx_win32.windows.end
		);

		if(it != _gfx_win32.windows.end)
		{
			/* Set pixel format */
			_gfx_win32_set_pixel_format(
				window.handle,
				&depth,
				attributes->flags & GFX_WINDOW_DOUBLE_BUFFER
			);

			/* Start tracking the mouse */
			_gfx_win32_track_mouse(window.handle);

			/* Enter fullscreen */
			if(
				(attributes->flags & GFX_WINDOW_FULLSCREEN) &&
				!(attributes->flags & GFX_WINDOW_HIDDEN))
			{
				_gfx_win32_enter_fullscreen(window.monitor, window.mode);
			}

			return window.handle;
		}

		DestroyWindow(window.handle);
	}

	return NULL;
}
Esempio n. 8
0
static int _gfx_x11_init_monitors(

		int  major,
		int  minor)
{
	/* Iterate over all screens */
	Screen* def = XDefaultScreenOfDisplay(_gfx_x11.display);
	unsigned int count = XScreenCount(_gfx_x11.display);

	while(count--)
	{
		/* Get screen resources */
		Screen* scr =
			XScreenOfDisplay(_gfx_x11.display, count);
		Window root =
			XRootWindowOfScreen(scr);
		XRRScreenResources* res =
			XRRGetScreenResources(_gfx_x11.display, root);
		RROutput prim =
			res->outputs[0];

		/* Get primary if RandR 1.3 is supported */
		if(major > 1 || (major == 1 && minor > 2))
			prim = XRRGetOutputPrimary(_gfx_x11.display, root);

		/* Insert the screen's display modes */
		size_t first = _gfx_x11_init_modes(scr, res);

		/* Iterate through outputs */
		unsigned int i;
		for(i = 0; i < res->noutput; ++i)
		{
			/* Validate output */
			XRROutputInfo* out =
				XRRGetOutputInfo(_gfx_x11.display, res, res->outputs[i]);

			if(out->connection != RR_Connected)
			{
				XRRFreeOutputInfo(out);
				continue;
			}

			/* Create new monitor */
			XRRCrtcInfo* crtc =
				XRRGetCrtcInfo(_gfx_x11.display, res, out->crtc);
			int rot =
				crtc->rotation & (RR_Rotate_90 | RR_Rotate_270);

			GFX_X11_Monitor mon =
			{
				.screen   = scr,
				.crtc     = out->crtc,
				.mode     = crtc->mode,
				.numModes = 0,
				.modes    = malloc(sizeof(size_t) * out->nmode),
				.x        = crtc->x,
				.y        = crtc->y,
				.width    = rot ? crtc->height : crtc->width,
				.height   = rot ? crtc->width : crtc->height
			};

			/* Retrieve output modes */
			unsigned int j;
			if(mon.modes) for(j = 0; j < out->nmode; ++j)
			{
				GFX_X11_Mode* mode;
				for(
					mode = gfx_vector_at(&_gfx_x11.modes, first);
					mode != _gfx_x11.modes.end;
					mode = gfx_vector_next(&_gfx_x11.modes, mode))
				{
					/* Also check if resolution isn't too big */
					if(
						mode->id == out->modes[j] &&
						mode->mode.width <= crtc->width &&
						mode->mode.height <= crtc->height)
					{
						mon.modes[mon.numModes++] = gfx_vector_get_index(
							&_gfx_x11.modes,
							mode
						);
						break;
					}
				}
			}

			/* Insert at beginning if primary */
			GFXVectorIterator monPos =
				scr == def && res->outputs[i] == prim ?
				_gfx_x11.monitors.begin : _gfx_x11.monitors.end;

			monPos = gfx_vector_insert(&_gfx_x11.monitors, &mon, monPos);
			if(monPos == _gfx_x11.monitors.end) free(mon.modes);

			XRRFreeCrtcInfo(crtc);
			XRRFreeOutputInfo(out);
		}

		XRRFreeScreenResources(res);
	}

	/* Need at least one monitor */
	return _gfx_x11.monitors.begin != _gfx_x11.monitors.end;
}

/******************************************************/
static GFXKey _gfx_x11_get_key(

		KeySym symbol)
{
	/* Unicode numbers */
	if(symbol >= XK_0 && symbol <= XK_9)
		return (GFXKey)(symbol - XK_0 + GFX_KEY_0);

	/* Keypad numbers */
	if(symbol >= XK_KP_0 && symbol <= XK_KP_9)
		return (GFXKey)(symbol - XK_KP_0 + GFX_KEY_KP_0);

	/* Unicode capitals */
	if(symbol >= XK_A && symbol <= XK_Z)
		return (GFXKey)(symbol - XK_A + GFX_KEY_A);

	/* Unicode lowercase */
	if(symbol >= XK_a && symbol <= XK_z)
		return (GFXKey)(symbol - XK_a + GFX_KEY_A);

	/* Function keys */
	if(symbol >= XK_F1 && symbol <= XK_F24)
		return (GFXKey)(symbol - XK_F1 + GFX_KEY_F1);

	/* Non-unicode */
	switch(symbol)
	{
		case XK_VoidSymbol   : return GFX_KEY_UNKNOWN;

		case XK_BackSpace    : return GFX_KEY_BACKSPACE;
		case XK_Tab          : return GFX_KEY_TAB;
		case XK_KP_Tab       : return GFX_KEY_TAB;
		case XK_Clear        : return GFX_KEY_CLEAR;
		case XK_Return       : return GFX_KEY_RETURN;
		case XK_Pause        : return GFX_KEY_PAUSE;
		case XK_Scroll_Lock  : return GFX_KEY_SCROLL_LOCK;
		case XK_Escape       : return GFX_KEY_ESCAPE;
		case XK_Delete       : return GFX_KEY_DELETE;
		case XK_KP_Delete    : return GFX_KEY_DELETE;

		case XK_Home         : return GFX_KEY_HOME;
		case XK_KP_Home      : return GFX_KEY_HOME;
		case XK_Left         : return GFX_KEY_LEFT;
		case XK_KP_Left      : return GFX_KEY_LEFT;
		case XK_Up           : return GFX_KEY_UP;
		case XK_KP_Up        : return GFX_KEY_UP;
		case XK_Right        : return GFX_KEY_RIGHT;
		case XK_KP_Right     : return GFX_KEY_RIGHT;
		case XK_Down         : return GFX_KEY_DOWN;
		case XK_KP_Down      : return GFX_KEY_DOWN;
		case XK_Page_Down    : return GFX_KEY_PAGE_DOWN;
		case XK_KP_Page_Down : return GFX_KEY_PAGE_DOWN;
		case XK_Page_Up      : return GFX_KEY_PAGE_UP;
		case XK_KP_Page_Up   : return GFX_KEY_PAGE_UP;
		case XK_End          : return GFX_KEY_END;
		case XK_KP_End       : return GFX_KEY_END;

		case XK_Select       : return GFX_KEY_SELECT;
		case XK_Print        : return GFX_KEY_PRINT;
		case XK_Execute      : return GFX_KEY_EXECUTE;
		case XK_Insert       : return GFX_KEY_INSERT;
		case XK_KP_Insert    : return GFX_KEY_INSERT;
		case XK_Menu         : return GFX_KEY_MENU;
		case XK_Cancel       : return GFX_KEY_CANCEL;
		case XK_Help         : return GFX_KEY_HELP;
		case XK_Num_Lock     : return GFX_KEY_NUM_LOCK;
		case XK_KP_Space     : return GFX_KEY_SPACE;
		case XK_space        : return GFX_KEY_SPACE;

		case XK_KP_Enter     : return GFX_KEY_KP_RETURN;
		case XK_KP_Multiply  : return GFX_KEY_KP_MULTIPLY;
		case XK_KP_Add       : return GFX_KEY_KP_ADD;
		case XK_KP_Separator : return GFX_KEY_KP_SEPARATOR;
		case XK_KP_Subtract  : return GFX_KEY_KP_SUBTRACT;
		case XK_KP_Decimal   : return GFX_KEY_KP_DECIMAL;
		case XK_KP_Divide    : return GFX_KEY_KP_DIVIDE;

		case XK_Shift_L      : return GFX_KEY_SHIFT_LEFT;
		case XK_Shift_R      : return GFX_KEY_SHIFT_RIGHT;
		case XK_Control_L    : return GFX_KEY_CONTROL_LEFT;
		case XK_Control_R    : return GFX_KEY_CONTROL_RIGHT;
		case XK_Alt_L        : return GFX_KEY_ALT_LEFT;
		case XK_Alt_R        : return GFX_KEY_ALT_RIGHT;
		case XK_Super_L      : return GFX_KEY_SUPER_LEFT;
		case XK_Super_R      : return GFX_KEY_SUPER_RIGHT;
	}

	return GFX_KEY_UNKNOWN;
}

/******************************************************/
static void _gfx_x11_create_key_table(void)
{
	/* Get permitted keycodes and their symbols */
	int minKey, maxKey;
	XDisplayKeycodes(_gfx_x11.display, &minKey, &maxKey);
	maxKey = maxKey > GFX_X11_MAX_KEYCODE ? GFX_X11_MAX_KEYCODE : maxKey;

	int numKeys = maxKey - minKey + 1;

	int symbolsPerKey;
	KeySym* symbols = XGetKeyboardMapping(
		_gfx_x11.display,
		minKey,
		numKeys,
		&symbolsPerKey
	);

	/* Use the first symbol of all keycodes */
	size_t i;
	for(i = minKey; i <= maxKey; ++i) _gfx_x11.keys[i] = _gfx_x11_get_key(
		symbols[(i - minKey) * symbolsPerKey]);

	XFree(symbols);
}
Esempio n. 9
0
int gfx_lod_map_add(

		GFXLodMap*    map,
		unsigned int  level,
		void*         data)
{
	GFX_LodMap* internal = (GFX_LodMap*)map;

	/* Overflow */
	size_t size = gfx_vector_get_size(&internal->data);
	if(level > map->levels || size == UINT_MAX) return 0;

	/* Get level iterator */
	GFXVectorIterator levIt;

	if(level == map->levels)
	{
		/* Insert the level if it doesn't exist yet */
		unsigned int upper = size;
		levIt = gfx_vector_insert(
			&internal->levels,
			&upper,
			internal->levels.end
		);

		if(levIt == internal->levels.end) return 0;
		++map->levels;
	}
	else
	{
		/* Check single data flag */
		if(map->flags & GFX_LOD_SINGLE_DATA) return 0;
		levIt = gfx_vector_at(&internal->levels, level);
	}

	/* Get boundaries */
	unsigned int begin;
	unsigned int end;
	_gfx_lod_map_get_boundaries(
		internal,
		levIt,
		&begin,
		&end
	);

	/* Insert the data */
	GFXVectorIterator it = gfx_vector_insert_at(
		&internal->data,
		data,
		end
	);

	if(it == internal->data.end)
	{
		if(begin == end)
		{
			gfx_vector_erase(&internal->levels, levIt);
			--map->levels;
		}
		return 0;
	}

	/* Increase upper bounds */
	while(levIt != internal->levels.end)
	{
		++(*(unsigned int*)levIt);
		levIt = gfx_vector_next(&internal->levels, levIt);
	}

	return 1;
}