void gfx_mesh_free( GFXMesh* mesh) { if(mesh) { GFX_Mesh* internal = (GFX_Mesh*)mesh; /* Remove all buckets */ size_t size = _gfx_mesh_bucket_size(mesh, UINT_MAX); size_t total = gfx_vector_get_size(&internal->buckets); while(total) { total -= size; _gfx_mesh_erase_bucket( internal, gfx_vector_at(&internal->buckets, total), size ); } /* Free all layouts */ GFXVectorIterator it; for( it = internal->layouts.begin; it != internal->layouts.end; it = gfx_vector_next(&internal->layouts, it)) { gfx_vertex_layout_free(*(GFXVertexLayout**)it); } /* Clear all shared buffers */ for( it = internal->buffers.begin; it != internal->buffers.end; it = gfx_vector_next(&internal->buffers, it)) { gfx_shared_buffer_clear((GFXSharedBuffer*)it, 1); } /* Free everything */ gfx_vector_clear(&internal->layouts); gfx_vector_clear(&internal->buckets); gfx_vector_clear(&internal->buffers); _gfx_lod_map_clear((GFX_LodMap*)internal); free(mesh); } }
GFX_X11_Window* _gfx_x11_get_window_from_context( GLXContext context) { GFX_X11_Window* it; for( it = _gfx_x11.windows.begin; it != _gfx_x11.windows.end; it = gfx_vector_next(&_gfx_x11.windows, it)) { if(it->context == context) break; } return it != _gfx_x11.windows.end ? it : NULL; }
GFX_X11_Window* _gfx_x11_get_window_from_handle( Window handle) { GFX_X11_Window* it; for( it = _gfx_x11.windows.begin; it != _gfx_x11.windows.end; it = gfx_vector_next(&_gfx_x11.windows, it)) { if(it->handle == handle) break; } return it != _gfx_x11.windows.end ? it : NULL; }
void _gfx_platform_terminate(void) { /* Free all mode references */ GFX_X11_Monitor* mon; for( mon = _gfx_x11.monitors.begin; mon != _gfx_x11.monitors.end; mon = gfx_vector_next(&_gfx_x11.monitors, mon)) { free(mon->modes); } /* Close connection (destroys all resources) */ if(_gfx_x11.display) XCloseDisplay(_gfx_x11.display); gfx_vector_clear(&_gfx_x11.monitors); gfx_vector_clear(&_gfx_x11.modes); gfx_vector_clear(&_gfx_x11.windows); }
static unsigned int _gfx_lod_map_find_data( const GFX_LodMap* map, unsigned int begin, unsigned int end, const void* data, GFXVectorIterator* found) { /* Find the data and count */ GFXVectorIterator it = gfx_vector_at(&map->data, begin); while(begin != end) { if(!memcmp(it, data, map->map.compSize)) break; ++begin; it = gfx_vector_next(&map->data, it); } *found = it; return begin; }
static int _gfx_lod_map_remove_at( GFX_LodMap* map, GFXVectorIterator level, unsigned int index) { /* Get boundaries */ unsigned int begin; unsigned int end; _gfx_lod_map_get_boundaries( map, level, &begin, &end ); unsigned int size = end - begin; if(index >= size) return 0; /* Erase the data */ gfx_vector_erase_at(&map->data, begin + index); if(size == 1) { level = gfx_vector_erase(&map->levels, level); --map->map.levels; } /* Decrease upper bounds */ while(level != map->levels.end) { --(*(unsigned int*)level); level = gfx_vector_next(&map->levels, level); } return 1; }
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); }
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; }