diff options
| author | 2026-04-13 16:16:25 -0400 | |
|---|---|---|
| committer | 2026-04-13 16:38:55 -0400 | |
| commit | 9913b7d590f46e59a475abbe85e70e02979d8d37 (patch) | |
| tree | 4cda8e52b89775bbeb082216f34d030d58161532 | |
| parent | d13e92193d21e112f45f3c92cf159f27498a3a55 (diff) | |
| download | stela-9913b7d590f46e59a475abbe85e70e02979d8d37.tar.gz stela-9913b7d590f46e59a475abbe85e70e02979d8d37.tar.bz2 stela-9913b7d590f46e59a475abbe85e70e02979d8d37.zip | |
Adjust window api, cleanup and update deps
Signed-off-by: Andrew Opalach <andrew@akon.city>
| -rw-r--r-- | .gitignore | 4 | ||||
| -rw-r--r-- | meson.build | 24 | ||||
| -rw-r--r-- | meson_options.txt | 1 | ||||
| -rw-r--r-- | src/keys.h | 10 | ||||
| -rw-r--r-- | src/poll_common.c | 2 | ||||
| -rw-r--r-- | src/window.c | 7 | ||||
| -rw-r--r-- | src/window.h | 18 | ||||
| -rw-r--r-- | src/window_glfm.c | 29 | ||||
| -rw-r--r-- | src/window_glfw.c | 8 | ||||
| -rw-r--r-- | src/window_kms.c | 7 | ||||
| -rw-r--r-- | src/window_x11.c | 16 | ||||
| -rw-r--r-- | subprojects/expat.wrap | 7 | ||||
| -rw-r--r-- | subprojects/glfw3.wrap | 4 | ||||
| -rw-r--r-- | subprojects/libalabaster.wrap | 4 | ||||
| -rw-r--r-- | subprojects/libnaunet.wrap | 4 | ||||
| -rw-r--r-- | subprojects/packagefiles/expat/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | subprojects/wayland.wrap | 10 | ||||
| -rw-r--r-- | tests/window.c | 31 |
18 files changed, 131 insertions, 57 deletions
@@ -7,10 +7,10 @@ subprojects/glad/ subprojects/glfm-*/ subprojects/glfw3-*/ subprojects/libalabaster -subprojects/libalabaster/ +subprojects/libalabaster-*/ subprojects/libev-*/ subprojects/libev.wrap subprojects/libnaunet -subprojects/libnaunet/ +subprojects/libnaunet-*/ subprojects/wayland-protocols-*/ subprojects/wlr-protocols-*/ diff --git a/meson.build b/meson.build index 2070cda..af738aa 100644 --- a/meson.build +++ b/meson.build @@ -94,6 +94,9 @@ elif get_option('api') in ['gl', 'gles'] stela_src += ['src/gl_common.c'] stela_args += ['-DSTELA_API_OPENGL'] elif get_option('api') == 'vulkan' + if not compiler.has_header('vulkan/vulkan.h') + error('Vulkan headers not found.') + endif vulkan = dependency('vulkan') vulkan_headers = vulkan.partial_dependency(includes: true, compile_args: true, link_args: true) stela_src += ['src/vk_common.c'] @@ -114,9 +117,15 @@ if get_option('window') == 'x11' stela_deps += [x11, xext, xrandr, xfixes, xcursor, xkb] stela_args += ['-DSTELA_WINDOW_X11'] elif get_option('window') == 'wayland' - wl_client = dependency('wayland-client') - wl_cursor = dependency('wayland-cursor') - wl_egl = dependency('wayland-egl') + wl_client = dependency('wayland-client', default_options: [ + 'libraries=true', + 'scanner=false', + 'tests=false', + 'documentation=false', + 'dtd_validation=false' + ], required: false, allow_fallback: false) + wl_cursor = dependency('wayland-cursor', allow_fallback: false) + wl_egl = dependency('wayland-egl', allow_fallback: false) wl_protocols = dependency('wayland-protocols', version: '>=1.32', required: false, allow_fallback: false) if not wl_protocols.found() wl_protocols_datadir = subproject('wayland-protocols', default_options: [ @@ -131,7 +140,7 @@ elif get_option('window') == 'wayland' else wlr_protocols_datadir = wlr_protocols.get_variable(pkgconfig: 'pkgdatadir') endif - scanner = find_program('wayland-scanner') + scanner = find_program('wayland-scanner', native: true) scanner_private_code = generator(scanner, output: '@BASENAME@-protocol.c', arguments: ['private-code','@INPUT@', '@OUTPUT@']) scanner_client_header = generator(scanner, output: '@BASENAME@-client-protocol.h', @@ -145,6 +154,8 @@ elif get_option('window') == 'wayland' wl_protocols_datadir + '/unstable/tablet/tablet-unstable-v2.xml'), scanner_private_code.process( wl_protocols_datadir + '/staging/cursor-shape/cursor-shape-v1.xml'), + scanner_private_code.process( + wl_protocols_datadir + '/staging/xdg-toplevel-icon/xdg-toplevel-icon-v1.xml'), #scanner_private_code.process( # wl_protocols_datadir + '/unstable/xdg-output/xdg-output-unstable-v1.xml'), scanner_private_code.process( @@ -163,6 +174,8 @@ elif get_option('window') == 'wayland' wl_protocols_datadir + '/unstable/tablet/tablet-unstable-v2.xml'), scanner_client_header.process( wl_protocols_datadir + '/staging/cursor-shape/cursor-shape-v1.xml'), + scanner_client_header.process( + wl_protocols_datadir + '/staging/xdg-toplevel-icon/xdg-toplevel-icon-v1.xml'), #scanner_client_header.process( # wl_protocols_datadir + '/unstable/xdg-output/xdg-output-unstable-v1.xml'), scanner_client_header.process( @@ -180,6 +193,9 @@ elif get_option('window') == 'wayland' stela_args += ['-DSTELA_WINDOW_WAYLAND'] elif get_option('window') == 'win32' stela_src += ['src/window_win32.c'] + if not get_option('win32-compat') + stela_deps += [compiler.find_library('dwmapi')] + endif stela_args += ['-DSTELA_WINDOW_WIN32'] elif get_option('window') == 'glfw' glfw3 = dependency('glfw3', required: false, allow_fallback: false) diff --git a/meson_options.txt b/meson_options.txt index f082df8..6632475 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -5,4 +5,5 @@ option('poll', type: 'combo', choices: ['inline', 'fd'], value: 'inline') option('event-buffer', type: 'boolean', value: false) option('pause', type: 'boolean', value: true) option('win32-compat', type: 'boolean', value: false, yield: true) +option('release-asserts', type: 'boolean', value: true, yield: true) option('tests', type: 'feature', value: 'auto', yield: true) @@ -4,11 +4,11 @@ #include <al/lib.h> // Expected behavior of modifiers: -// - Window keeps an internal state of all currently held modifiers. -// - On window focus enter, if modifier is held, send BUTTON_PRESSED event. -// - If a modifier was held on enter, it must still receive a BUTTON_RELEASED -// event when the key is released. -// - On window focus exit, send BUTTON_RELEASED for every active modifier. +// - Window keeps an internal state of currently held modifiers. +// - On window focus enter, if a modifier is held, send BUTTON_PRESSED event. +// - If a modifier was held on enter, it must still receive a BUTTON_RELEASED +// event when the key is released. +// - On window focus exit, send BUTTON_RELEASED for every held modifier. enum { STELA_MOD_NONE = 0, STELA_MOD_LCONTROL = 1, diff --git a/src/poll_common.c b/src/poll_common.c index 0b8cb79..868fa46 100644 --- a/src/poll_common.c +++ b/src/poll_common.c @@ -1,6 +1,6 @@ #define AL_LOG_SECTION "poll" #include <al/log.h> -#include <nnwt/common.h> +#include <nnwt/error.h> #include "poll_common.h" diff --git a/src/window.c b/src/window.c index 0d448af..f85f4fc 100644 --- a/src/window.c +++ b/src/window.c @@ -45,11 +45,12 @@ static bool nop_key_callback(void *userdata, u8 state, u16 button) return false; } -static void nop_key_immediate_callback(void *userdata, u8 state, u16 button) +static bool nop_key_immediate_callback(void *userdata, u8 state, u16 button) { (void)userdata; (void)state; (void)button; + return false; } static void window_default_close(struct stl_window *window) @@ -227,10 +228,10 @@ void stl_window_send_key_event(struct stl_window *window, u8 state, u16 button) #endif } -void stl_window_send_key_immediate_event(struct stl_window *window, u8 state, u16 button) +bool stl_window_send_key_immediate_event(struct stl_window *window, u8 state, u16 button) { // Don't send modifiers on key immediate. - window->key_immediate_callback(window->userdata, state, button * (stl_key_to_mod(button) == STELA_MOD_NONE)); + return window->key_immediate_callback(window->userdata, state, button * (stl_key_to_mod(button) == STELA_MOD_NONE)); } void stl_window_drop_modifiers(struct stl_window *window) diff --git a/src/window.h b/src/window.h index f7f25e2..de18c83 100644 --- a/src/window.h +++ b/src/window.h @@ -44,6 +44,10 @@ #define STELA_MIN_HEIGHT 16u #endif +#ifdef STELA_WINDOW_WAYLAND +#define STELA_ICON_AT_RUNTIME +#endif + // Drag window by clicking anywhere with MOUSE2. #define STELA_MOUSE2_DRAG @@ -81,7 +85,7 @@ struct stl_window { bool fullscreen; u32 flags; // Methods. - bool (*create_window)(struct stl_window *, u32, u32, const char *, const char *, u32); + bool (*create_window)(struct stl_window *, u32, u32, u32, const char *, const char *, const char *); void (*resize_internal)(struct stl_window *, u32, u32); void (*resize)(struct stl_window *, u32, u32); void (*toggle_fullscreen)(struct stl_window *); @@ -127,8 +131,11 @@ struct stl_window { bool (*scroll_callback)(void *, f64); bool (*mouse_button_callback)(void *, u8, u8); bool (*key_callback)(void *, u8, u16); - // Always runs on the thread that received the key event. - void (*key_immediate_callback)(void *, u8, u16); + // Immediate: + // - Always runs on the thread that received the event. + // - Return value decides if the event should "pass through" or not. + // True = Consume, False = Passthrough. + bool (*key_immediate_callback)(void *, u8, u16); void (*should_close_callback)(void *); void *userdata; bool closed; @@ -189,6 +196,9 @@ extern s32 stl_platform_main(u32 argc, str *argv); f64 stl_scale_scroll(f64 v, f64 factor); void stl_set_output_discovered_callback(void (*output_discovered)(void *, struct stl_monitor *), void *userdata); +#ifdef STELA_ICON_AT_RUNTIME +void stl_set_icon_data(u8 *data, u32 size); +#endif bool stl_global_init(bool skip_graphics); s32 stl_global_get_poll_fd(void); @@ -205,7 +215,7 @@ void stl_window_send_scroll_event(struct stl_window *window, f64 y); void stl_window_send_mouse_button_event(struct stl_window *window, u8 state, u8 button); void stl_window_drop_mouse_buttons(struct stl_window *window); void stl_window_send_key_event(struct stl_window *window, u8 state, u16 button); -void stl_window_send_key_immediate_event(struct stl_window *window, u8 state, u16 button); +bool stl_window_send_key_immediate_event(struct stl_window *window, u8 state, u16 button); void stl_window_drop_modifiers(struct stl_window *window); void stl_window_send_should_close_event(struct stl_window *window); #ifdef STELA_EVENT_BUFFER diff --git a/src/window_glfm.c b/src/window_glfm.c index 202a55f..a799f5d 100644 --- a/src/window_glfm.c +++ b/src/window_glfm.c @@ -4,6 +4,7 @@ #include "window_glfm.h" #include "common.h" +#include "keys.h" f64 stl_scale_scroll(f64 v, f64 factor) { @@ -87,6 +88,28 @@ static void onOrientationChanged(GLFMDisplay *display, GLFMInterfaceOrientation global.orientation = orientation; } +static u8 glfm_to_stela_button_action[] = { + [GLFMKeyActionPressed] = STELA_BUTTON_PRESSED, + [GLFMKeyActionReleased] = STELA_BUTTON_RELEASED +}; + +static bool onKey(GLFMDisplay *display, GLFMKeyCode key, GLFMKeyAction action, s32 modifiers) +{ + struct stl_window_glfm *glfm = (struct stl_window_glfm *)glfmGetUserData(display); + (void)modifiers; + u8 mapped_action = glfm_to_stela_button_action[action]; + switch (key) { + case GLFMKeyCodeVolumeUp: + return stl_window_send_key_immediate_event(&glfm->w, mapped_action, STELA_KEY_RIGHT); + case GLFMKeyCodeVolumeDown: + return stl_window_send_key_immediate_event(&glfm->w, mapped_action, STELA_KEY_LEFT); + case GLFMKeyCodeNavigationBack: + default: + break; + } + return true; +} + static u8 glfm_to_stela_touch[] = { [GLFMTouchPhaseHover] = STELA_TOUCH_HOVER, [GLFMTouchPhaseBegan] = STELA_TOUCH_BEGAN, @@ -126,17 +149,19 @@ void glfmMain(GLFMDisplay *display) glfmSetRenderFunc(display, onDraw); glfmSetSurfaceDestroyedFunc(display, onSurfaceDestroyed); glfmSetOrientationChangedFunc(display, onOrientationChanged); + glfmSetKeyFunc(display, onKey); glfmSetTouchFunc(display, onTouch); } -static bool window_glfm_create_window(struct stl_window *window, u32 width, u32 height, - const char *monitor, const char *name, u32 flags) +static bool window_glfm_create_window(struct stl_window *window, u32 width, u32 height, u32 flags, + const char *monitor, const char *name, const char *app_id) { struct stl_window_glfm *glfm = (struct stl_window_glfm *)window; (void)width; (void)height; (void)monitor; (void)name; + (void)app_id; glfmSetUserData(global.display, glfm); s32 display_width, display_height; glfmGetDisplaySize(global.display, &display_width, &display_height); diff --git a/src/window_glfw.c b/src/window_glfw.c index f94c9c2..0f55bc3 100644 --- a/src/window_glfw.c +++ b/src/window_glfw.c @@ -189,16 +189,16 @@ static void close_callback(GLFWwindow *window) stl_window_send_should_close_event(&glfw->w); } -static bool window_glfw_create_window(struct stl_window *window, u32 width, u32 height, - const char *monitor, const char *name, u32 flags) +static bool window_glfw_create_window(struct stl_window *window, u32 width, u32 height, u32 flags, + const char *monitor, const char *name, const char *app_id) { struct stl_window_glfw *glfw = (struct stl_window_glfw *)window; (void)monitor; #if GLFW_VERSION_MAJOR > 3 || (GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR >= 4) - glfwWindowHintString(GLFW_WAYLAND_APP_ID, name); + glfwWindowHintString(GLFW_WAYLAND_APP_ID, app_id); #endif - glfwWindowHintString(GLFW_X11_CLASS_NAME, name); + glfwWindowHintString(GLFW_X11_CLASS_NAME, app_id); #if defined STELA_API_VULKAN if (!glfwVulkanSupported()) { diff --git a/src/window_kms.c b/src/window_kms.c index 900ac59..de3f24a 100644 --- a/src/window_kms.c +++ b/src/window_kms.c @@ -37,16 +37,17 @@ void stl_global_close(void) { } -static bool window_kms_create_window(struct stl_window *window, u32 width, u32 height, - const char *monitor, const char *name, u32 flags) +static bool window_kms_create_window(struct stl_window *window, u32 width, u32 height, u32 flags, + const char *monitor, const char *name, const char *app_id) { struct stl_window_kms *kms = (struct stl_window_kms *)window; (void)kms; (void)monitor; (void)name; - (void)flags; + (void)app_id; (void)width; (void)height; + (void)flags; return true; } diff --git a/src/window_x11.c b/src/window_x11.c index 2f84f19..998beb4 100644 --- a/src/window_x11.c +++ b/src/window_x11.c @@ -180,8 +180,8 @@ static void set_decorations(struct stl_window_x11 *xw, bool enabled) } } -static bool window_x11_create_window(struct stl_window *window, u32 width, u32 height, - const char *monitor, const char *name, u32 flags) +static bool window_x11_create_window(struct stl_window *window, u32 width, u32 height, u32 flags, + const char *monitor, const char *name, const char *app_id) { struct stl_window_x11 *xw = (struct stl_window_x11 *)window; (void)monitor; @@ -201,7 +201,7 @@ static bool window_x11_create_window(struct stl_window *window, u32 width, u32 h XStoreName(global.x11_d, xw->window, name); XClassHint *class_hint = XAllocClassHint(); class_hint->res_name = (char *)name; - class_hint->res_class = (char *)name; + class_hint->res_class = (char *)app_id; XSetClassHint(global.x11_d, xw->window, class_hint); XFree(class_hint); @@ -553,14 +553,14 @@ static void handle_next_xevent(struct stl_window_x11 *xw) event.xclient.send_event = True; event.xclient.display = global.x11_d; event.xclient.window = xw->window; - // https://specifications.freedesktop.org/wm-spec/1.4/ar01s04.html#id-1.5.4 + // https://specifications.freedesktop.org/wm/1.5/ar01s04.html#id-1.5.4 event.xclient.message_type = XInternAtom(global.x11_d, "_NET_WM_MOVERESIZE", False); event.xclient.format = 32; - event.xclient.data.l[0] = xev.xbutton.x; - event.xclient.data.l[1] = xev.xbutton.y; + event.xclient.data.l[0] = xev.xbutton.x_root; + event.xclient.data.l[1] = xev.xbutton.y_root; event.xclient.data.l[2] = _NET_WM_MOVERESIZE_MOVE; - event.xclient.data.l[3] = 0; - // https://specifications.freedesktop.org/wm-spec/1.4/ar01s09.html#sourceindication + event.xclient.data.l[3] = xev.xbutton.button; + // https://specifications.freedesktop.org/wm/1.5/ar01s09.html#sourceindication event.xclient.data.l[4] = 1; // Source indication of "normal applications". Window root = DefaultRootWindow(global.x11_d); XSendEvent(global.x11_d, root, False, SubstructureRedirectMask | SubstructureNotifyMask, &event); diff --git a/subprojects/expat.wrap b/subprojects/expat.wrap new file mode 100644 index 0000000..0a383da --- /dev/null +++ b/subprojects/expat.wrap @@ -0,0 +1,7 @@ +[wrap-git] +directory = expat-2.7.3 +url = https://github.com/libexpat/libexpat.git +revision = R_2_7_3 +depth = 1 +patch_directory = expat +method = cmake diff --git a/subprojects/glfw3.wrap b/subprojects/glfw3.wrap index 692b7a0..4d1a2c2 100644 --- a/subprojects/glfw3.wrap +++ b/subprojects/glfw3.wrap @@ -1,6 +1,6 @@ [wrap-git] -directory = glfw3-162896e +directory = glfw3-b00e6a8 url = https://github.com/glfw/glfw.git -revision = 162896e5b9a40dc382c5c438cd12c90a5ff86ddd +revision = b00e6a8a88ad1b60c0a045e696301deb92c9a13e depth = 1 method = cmake diff --git a/subprojects/libalabaster.wrap b/subprojects/libalabaster.wrap index 3f7a977..c48903d 100644 --- a/subprojects/libalabaster.wrap +++ b/subprojects/libalabaster.wrap @@ -1,5 +1,5 @@ [wrap-git] -directory = libalabaster-dd7a1d1 +directory = libalabaster-c633226 url = https://git.akon.city/libalabaster.git -revision = dd7a1d1afb8b3e93ab1005abdc21edb6efca840a +revision = c633226d2b615f46ef38cc99603775dccdf96ecd depth = 1 diff --git a/subprojects/libnaunet.wrap b/subprojects/libnaunet.wrap index 547bd75..63425dd 100644 --- a/subprojects/libnaunet.wrap +++ b/subprojects/libnaunet.wrap @@ -1,5 +1,5 @@ [wrap-git] -directory = libnaunet-1e0f603 +directory = libnaunet-a389b8f url = https://git.akon.city/libnaunet.git -revision = 1e0f60341192c79bf49e84e6b187ffb7bfded252 +revision = a389b8f2f9c55b76fe5a28c3f1fea798ed37aa98 depth = 1 diff --git a/subprojects/packagefiles/expat/CMakeLists.txt b/subprojects/packagefiles/expat/CMakeLists.txt new file mode 100644 index 0000000..c856a85 --- /dev/null +++ b/subprojects/packagefiles/expat/CMakeLists.txt @@ -0,0 +1,2 @@ +cmake_minimum_required(VERSION 3.9 FATAL_ERROR) +add_subdirectory(expat) diff --git a/subprojects/wayland.wrap b/subprojects/wayland.wrap new file mode 100644 index 0000000..4fc8ba8 --- /dev/null +++ b/subprojects/wayland.wrap @@ -0,0 +1,10 @@ +[wrap-git] +directory = wayland-1.24.0 +url = https://gitlab.freedesktop.org/wayland/wayland.git +revision = 1.24.0 +depth = 1 + +[provide] +wayland-client = wayland_client_dep +wayland-cursor = wayland_cursor_dep +wayland-egl = wayland_egl_dep diff --git a/tests/window.c b/tests/window.c index 31447d8..7ce154c 100644 --- a/tests/window.c +++ b/tests/window.c @@ -62,14 +62,7 @@ static bool mouse_button_callback(void *userdata, u8 state, u8 button) (void)userdata; switch (button) { case STELA_MOUSE1: - switch (state) { - case STELA_BUTTON_PRESSED: - dragging = true; - break; - case STELA_BUTTON_RELEASED: - dragging = false; - break; - } + dragging = state == STELA_BUTTON_PRESSED; break; } return false; @@ -95,7 +88,7 @@ static bool key_callback(void *userdata, u8 state, u16 button) return false; } -static void key_immediate_callback(void *userdata, u8 state, u16 button) +static bool key_immediate_callback(void *userdata, u8 state, u16 button) { (void)userdata; switch (state) { @@ -103,10 +96,11 @@ static void key_immediate_callback(void *userdata, u8 state, u16 button) switch (button) { case STELA_KEY_F: window->toggle_fullscreen(window); - break; + return true; } break; } + return false; } static void should_close_callback(void *userdata) @@ -132,12 +126,19 @@ static GLfloat vertices[] = { ((c >> 8) & 0xff) / 255.f, \ (c & 0xff) / 255.f +// #EDEDF0 +static const u32 cw = 0xEDEDF0; +static const GLfloat winbg[3] = { EXPAND_RGB(cw) }; + +// #2F3C7A static const u32 c0 = 0x2F3C7A; static const GLfloat bg[3] = { EXPAND_RGB(c0) }; -static const u32 c1 = 0x0F1B26; +// #1F2947 +static const u32 c1 = 0x1F2947; static const GLfloat color1[3] = { EXPAND_RGB(c1) }; +// #C3A46F static const u32 c2 = 0xC3A46F; static const GLfloat color2[3] = { EXPAND_RGB(c2) }; @@ -179,7 +180,7 @@ s32 window_system_main(u32 argc, str *argv, void *extra) window->userdata = NULL; u32 flags = STELA_WINDOW_VSYNC; - if (!window->create_window(window, DEFAULT_WIDTH, DEFAULT_HEIGHT, "", "Stella", flags)) { + if (!window->create_window(window, DEFAULT_WIDTH, DEFAULT_HEIGHT, flags, "", "Stella", "stela")) { return EXIT_FAILURE; } @@ -197,7 +198,7 @@ s32 window_system_main(u32 argc, str *argv, void *extra) } glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); - glClearColor(1.f, 1.f, 1.f, 1.f); + glClearColor(winbg[0], winbg[1], winbg[2], 1.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); window->gl_swap_buffers(window); if (argc > 1 && al_str_cmp(&argv[1], &al_str_c("w"), 0, 1) == 0) { @@ -227,9 +228,9 @@ s32 window_system_main(u32 argc, str *argv, void *extra) glScissor(x_offset, y_offset, (GLsizei)w, (GLsizei)h); glEnable(GL_SCISSOR_TEST); - glClearColor(bg[0], bg[1], bg[2], 1.f); + glClearColor(winbg[0], winbg[1], winbg[2], 1.f); glClear(GL_COLOR_BUFFER_BIT); - glClearColor(1.f, 1.f, 1.f, 1.f); + glClearColor(bg[0], bg[1], bg[2], 1.f); glDisable(GL_SCISSOR_TEST); glViewport(x_offset, y_offset, (GLsizei)w, (GLsizei)h); |