From fa8bf266f0c65d2e5bc28973e5e55106dff2a34a Mon Sep 17 00:00:00 2001 From: Carlos Aragones Date: Fri, 19 Feb 2021 10:51:58 +0100 Subject: [PATCH] Changes related to dpi. Introduced new function mfb_get_monitor_scale Deprecated function mfb_get_monitor_dpi --- README.md | 2 + include/MiniFB.h | 3 + src/MiniFB_common.c | 51 ++++++++------- src/ios/iOSMiniFB.m | 20 +++--- src/macosx/MacMiniFB.m | 31 +++++---- src/wayland/WaylandMiniFB.c | 118 ++++++++++++++++----------------- src/windows/WinMiniFB.c | 126 +++++++++++++++++++++++++++--------- src/x11/X11MiniFB.c | 96 +++++++++++++-------------- tests/ios/AppDelegate.m | 10 +-- 9 files changed, 265 insertions(+), 192 deletions(-) diff --git a/README.md b/README.md index 114f20e..51c7903 100644 --- a/README.md +++ b/README.md @@ -232,6 +232,8 @@ int mfb_get_mouse_x(struct mfb_window *window); // L int mfb_get_mouse_y(struct mfb_window *window); // Last mouse pos Y // Not working on Linux (X11 nor Wayland) +void mfb_get_monitor_scale(struct mfb_window *window, float *scale_x, float *scale_y) +// [Deprecated] Use mfb_get_monitor_scale instead void mfb_get_monitor_dpi(struct mfb_window *window, float *dpi_x, float *dpi_y) ``` diff --git a/include/MiniFB.h b/include/MiniFB.h index 0b1f2c3..b87338f 100644 --- a/include/MiniFB.h +++ b/include/MiniFB.h @@ -39,7 +39,10 @@ void * mfb_get_user_data(struct mfb_window *window); bool mfb_set_viewport(struct mfb_window *window, unsigned offset_x, unsigned offset_y, unsigned width, unsigned height); // DPI +// [Deprecated]: Probably a better name will be mfb_get_monitor_scale void mfb_get_monitor_dpi(struct mfb_window *window, float *dpi_x, float *dpi_y); +// Use this instead +void mfb_get_monitor_scale(struct mfb_window *window, float *scale_x, float *scale_y); // Callbacks void mfb_set_active_callback(struct mfb_window *window, mfb_active_func callback); diff --git a/src/MiniFB_common.c b/src/MiniFB_common.c index 390596d..c442832 100755 --- a/src/MiniFB_common.c +++ b/src/MiniFB_common.c @@ -13,7 +13,7 @@ mfb_open(const char *title, unsigned width, unsigned height) { } //------------------------------------- -mfb_update_state +mfb_update_state mfb_update(struct mfb_window *window, void *buffer) { if (window == 0x0) { return STATE_INVALID_WINDOW; @@ -25,7 +25,7 @@ mfb_update(struct mfb_window *window, void *buffer) { } //------------------------------------- -void +void mfb_set_active_callback(struct mfb_window *window, mfb_active_func callback) { if(window != 0x0) { SWindowData *window_data = (SWindowData *) window; @@ -34,7 +34,7 @@ mfb_set_active_callback(struct mfb_window *window, mfb_active_func callback) { } //------------------------------------- -void +void mfb_set_resize_callback(struct mfb_window *window, mfb_resize_func callback) { if(window != 0x0) { SWindowData *window_data = (SWindowData *) window; @@ -43,7 +43,7 @@ mfb_set_resize_callback(struct mfb_window *window, mfb_resize_func callback) { } //------------------------------------- -void +void mfb_set_keyboard_callback(struct mfb_window *window, mfb_keyboard_func callback) { if(window != 0x0) { SWindowData *window_data = (SWindowData *) window; @@ -52,7 +52,7 @@ mfb_set_keyboard_callback(struct mfb_window *window, mfb_keyboard_func callback) } //------------------------------------- -void +void mfb_set_char_input_callback(struct mfb_window *window, mfb_char_input_func callback) { if(window != 0x0) { SWindowData *window_data = (SWindowData *) window; @@ -61,7 +61,7 @@ mfb_set_char_input_callback(struct mfb_window *window, mfb_char_input_func callb } //------------------------------------- -void +void mfb_set_mouse_button_callback(struct mfb_window *window, mfb_mouse_button_func callback) { if(window != 0x0) { SWindowData *window_data = (SWindowData *) window; @@ -70,7 +70,7 @@ mfb_set_mouse_button_callback(struct mfb_window *window, mfb_mouse_button_func c } //------------------------------------- -void +void mfb_set_mouse_move_callback(struct mfb_window *window, mfb_mouse_move_func callback) { if(window != 0x0) { SWindowData *window_data = (SWindowData *) window; @@ -79,7 +79,7 @@ mfb_set_mouse_move_callback(struct mfb_window *window, mfb_mouse_move_func callb } //------------------------------------- -void +void mfb_set_mouse_scroll_callback(struct mfb_window *window, mfb_mouse_scroll_func callback) { if(window != 0x0) { SWindowData *window_data = (SWindowData *) window; @@ -88,7 +88,7 @@ mfb_set_mouse_scroll_callback(struct mfb_window *window, mfb_mouse_scroll_func c } //------------------------------------- -void +void mfb_set_user_data(struct mfb_window *window, void *user_data) { if(window != 0x0) { SWindowData *window_data = (SWindowData *) window; @@ -107,8 +107,15 @@ mfb_get_user_data(struct mfb_window *window) { return 0x0; } +// [Deprecated] //------------------------------------- -void +void +mfb_get_monitor_dpi(struct mfb_window *window, float *dpi_x, float *dpi_y) { + mfb_get_monitor_scale(window, dpi_x, dpi_y); +} + +//------------------------------------- +void mfb_close(struct mfb_window *window) { if(window != 0x0) { SWindowData *window_data = (SWindowData *) window; @@ -117,7 +124,7 @@ mfb_close(struct mfb_window *window) { } //------------------------------------- -void +void keyboard_default(struct mfb_window *window, mfb_key key, mfb_key_mod mod, bool isPressed) { kUnused(mod); kUnused(isPressed); @@ -128,7 +135,7 @@ keyboard_default(struct mfb_window *window, mfb_key key, mfb_key_mod mod, bool i } //------------------------------------- -bool +bool mfb_is_window_active(struct mfb_window *window) { if(window != 0x0) { SWindowData *window_data = (SWindowData *) window; @@ -138,7 +145,7 @@ mfb_is_window_active(struct mfb_window *window) { } //------------------------------------- -unsigned +unsigned mfb_get_window_width(struct mfb_window *window) { if(window != 0x0) { SWindowData *window_data = (SWindowData *) window; @@ -148,7 +155,7 @@ mfb_get_window_width(struct mfb_window *window) { } //------------------------------------- -unsigned +unsigned mfb_get_window_height(struct mfb_window *window) { if(window != 0x0) { SWindowData *window_data = (SWindowData *) window; @@ -158,7 +165,7 @@ mfb_get_window_height(struct mfb_window *window) { } //------------------------------------- -int +int mfb_get_mouse_x(struct mfb_window *window) { if(window != 0x0) { SWindowData *window_data = (SWindowData *) window; @@ -168,7 +175,7 @@ mfb_get_mouse_x(struct mfb_window *window) { } //------------------------------------- -int +int mfb_get_mouse_y(struct mfb_window *window) { if(window != 0x0) { SWindowData *window_data = (SWindowData *) window; @@ -178,7 +185,7 @@ mfb_get_mouse_y(struct mfb_window *window) { } //------------------------------------- -float +float mfb_get_mouse_scroll_x(struct mfb_window *window) { if(window != 0x0) { SWindowData *window_data = (SWindowData *) window; @@ -188,7 +195,7 @@ mfb_get_mouse_scroll_x(struct mfb_window *window) { } //------------------------------------- -float +float mfb_get_mouse_scroll_y(struct mfb_window *window) { if(window != 0x0) { SWindowData *window_data = (SWindowData *) window; @@ -198,7 +205,7 @@ mfb_get_mouse_scroll_y(struct mfb_window *window) { } //------------------------------------- -const uint8_t * +const uint8_t * mfb_get_mouse_button_buffer(struct mfb_window *window) { if(window != 0x0) { SWindowData *window_data = (SWindowData *) window; @@ -208,7 +215,7 @@ mfb_get_mouse_button_buffer(struct mfb_window *window) { } //------------------------------------- -const uint8_t * +const uint8_t * mfb_get_key_buffer(struct mfb_window *window) { if(window != 0x0) { SWindowData *window_data = (SWindowData *) window; @@ -218,7 +225,7 @@ mfb_get_key_buffer(struct mfb_window *window) { } //------------------------------------- -const char * +const char * mfb_get_key_name(mfb_key key) { switch (key) @@ -586,6 +593,6 @@ mfb_get_key_name(mfb_key key) { case KB_KEY_UNKNOWN: return "Unknown"; } - + return "Unknown"; } diff --git a/src/ios/iOSMiniFB.m b/src/ios/iOSMiniFB.m index cb5e4ea..9e85736 100644 --- a/src/ios/iOSMiniFB.m +++ b/src/ios/iOSMiniFB.m @@ -250,23 +250,23 @@ mfb_timer_init() { //------------------------------------- void -mfb_get_monitor_dpi(struct mfb_window *window, float *dpi_x, float *dpi_y) { +mfb_get_monitor_scale(struct mfb_window *window, float *scale_x, float *scale_y) { (void) window; float scale = 1.0f; scale = [[UIScreen mainScreen] scale]; - - if (dpi_x) { - *dpi_x = scale; - if(*dpi_x == 0) { - *dpi_x = 1; + + if (scale_x) { + *scale_x = scale; + if(*scale_x == 0) { + *scale_x = 1; } } - if (dpi_y) { - *dpi_y = scale; - if (*dpi_y == 0) { - *dpi_y = 1; + if (scale_y) { + *scale_y = scale; + if (*scale_y == 0) { + *scale_y = 1; } } } diff --git a/src/macosx/MacMiniFB.m b/src/macosx/MacMiniFB.m index 34c431b..c6dc272 100644 --- a/src/macosx/MacMiniFB.m +++ b/src/macosx/MacMiniFB.m @@ -161,7 +161,7 @@ mfb_open_ex(const char *title, unsigned width, unsigned height, unsigned flags) window_data->is_initialized = true; return (struct mfb_window *) window_data; - } + } } //------------------------------------- @@ -175,7 +175,7 @@ destroy_window_data(SWindowData *window_data) { if(window_data_osx != 0x0) { OSXWindow *window = window_data_osx->window; [window performClose:nil]; - + // Flush events! NSEvent* event; do { @@ -198,7 +198,7 @@ destroy_window_data(SWindowData *window_data) { window_data->draw_buffer = 0x0; } #endif - + memset(window_data, 0, sizeof(SWindowData)); free(window_data); } @@ -247,7 +247,7 @@ mfb_update_ex(struct mfb_window *window, void *buffer, unsigned width, unsigned [window_data_osx->viewController resizeTextures]; } - + memcpy(window_data->draw_buffer, buffer, window_data->buffer_stride * window_data->buffer_height); #else if(window_data->buffer_width != width || window_data->buffer_height != height) { @@ -255,7 +255,7 @@ mfb_update_ex(struct mfb_window *window, void *buffer, unsigned width, unsigned window_data->buffer_stride = width * 4; window_data->buffer_height = height; } - + window_data->draw_buffer = buffer; #endif @@ -553,7 +553,7 @@ mfb_timer_init() { //------------------------------------- void -mfb_get_monitor_dpi(struct mfb_window *window, float *dpi_x, float *dpi_y) { +mfb_get_monitor_scale(struct mfb_window *window, float *scale_x, float *scale_y) { float scale = 1.0f; if(window != 0x0) { @@ -565,19 +565,18 @@ mfb_get_monitor_dpi(struct mfb_window *window, float *dpi_x, float *dpi_y) { else { scale = [[NSScreen mainScreen] backingScaleFactor]; } - - if (dpi_x) { - *dpi_x = scale; - if(*dpi_x == 0) { - *dpi_x = 1; + + if (scale_x) { + *scale_x = scale; + if(*scale_x == 0) { + *scale_x = 1; } } - if (dpi_y) { - *dpi_y = scale; - if (*dpi_y == 0) { - *dpi_y = 1; + if (scale_y) { + *scale_y = scale; + if (*scale_y == 0) { + *scale_y = 1; } } } - diff --git a/src/wayland/WaylandMiniFB.c b/src/wayland/WaylandMiniFB.c index a7a4528..eb0a3a6 100644 --- a/src/wayland/WaylandMiniFB.c +++ b/src/wayland/WaylandMiniFB.c @@ -22,8 +22,8 @@ void init_keycodes(); -static void -destroy_window_data(SWindowData *window_data) +static void +destroy_window_data(SWindowData *window_data) { if(window_data == 0x0) return; @@ -38,12 +38,12 @@ destroy_window_data(SWindowData *window_data) free(window_data); } -static void +static void destroy(SWindowData *window_data) { if(window_data == 0x0) return; - + SWindowData_Way *window_data_way = (SWindowData_Way *) window_data->specific; if (window_data_way == 0x0 || window_data_way->display == 0x0) { destroy_window_data(window_data); @@ -79,7 +79,7 @@ destroy(SWindowData *window_data) close(window_data_way->fd); } -// This event provides a file descriptor to the client which can be memory-mapped +// This event provides a file descriptor to the client which can be memory-mapped // to provide a keyboard mapping description. // format: keymap format // fd: keymap file descriptor @@ -98,7 +98,7 @@ keyboard_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int f // serial: serial number of the enter event // surface: surface gaining keyboard focus // keys: the currently pressed keys -static void +static void keyboard_enter(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys) { kUnused(keyboard); @@ -114,7 +114,7 @@ keyboard_enter(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct // The leave notification is sent before the enter notification for the new focus. // serial: serial number of the leave event // surface: surface that lost keyboard focus -static void +static void keyboard_leave(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface) { kUnused(keyboard); @@ -126,13 +126,13 @@ keyboard_leave(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct kCall(active_func, false); } -// A key was pressed or released. The time argument is a timestamp with +// A key was pressed or released. The time argument is a timestamp with // millisecond granularity, with an undefined base. // serial: serial number of the key event // time: timestamp with millisecond granularity // key: key that produced the event // state: physical state of the key -static void +static void keyboard_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) { kUnused(keyboard); @@ -183,14 +183,14 @@ keyboard_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t } } -// Notifies clients that the modifier and/or group state has changed, +// Notifies clients that the modifier and/or group state has changed, // and it should update its local state. // serial: serial number of the modifiers event // mods_depressed: depressed modifiers // mods_latched: latched modifiers // mods_locked: locked modifiers // group: keyboard layout -static void +static void keyboard_modifiers(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) { kUnused(data); @@ -206,7 +206,7 @@ keyboard_modifiers(void *data, struct wl_keyboard *keyboard, uint32_t serial, ui // Informs the client about the keyboard's repeat rate and delay. // rate: the rate of repeating keys in characters per second // delay: delay in milliseconds since key down until repeating starts -static void +static void keyboard_repeat_info(void *data, struct wl_keyboard *keyboard, int32_t rate, int32_t delay) { kUnused(data); @@ -215,7 +215,7 @@ keyboard_repeat_info(void *data, struct wl_keyboard *keyboard, int32_t rate, int kUnused(delay); } -static const struct +static const struct wl_keyboard_listener keyboard_listener = { .keymap = keyboard_keymap, .enter = keyboard_enter, @@ -278,7 +278,7 @@ pointer_leave(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl //fprintf(stderr, "Pointer left surface %p\n", surface); } -// Notification of pointer location change. +// Notification of pointer location change. // // The arguments sx and sy are the location relative to the focused surface. // @@ -329,19 +329,19 @@ pointer_button(void *data, struct wl_pointer *pointer, uint32_t serial, uint32_t } // Scroll and other axis notifications. -// +// // For scroll events (vertical and horizontal scroll axes), the // value parameter is the length of a vector along the specified // axis in a coordinate space identical to those of motion events, // representing a relative movement along the specified axis. -// +// // For devices that support movements non-parallel to axes multiple // axis events will be emitted. -// +// // When applicable, for example for touch pads, the server can // choose to emit scroll events where the motion vector is // equivalent to a motion event vector. -// +// // When applicable, a client can transform its content relative to // the scroll distance. // @@ -365,20 +365,20 @@ pointer_axis(void *data, struct wl_pointer *pointer, uint32_t time, uint32_t axi } } -static void +static void frame(void *data, struct wl_pointer *pointer) { kUnused(data); kUnused(pointer); } -static void +static void axis_source(void *data, struct wl_pointer *pointer, uint32_t axis_source) { kUnused(data); kUnused(pointer); kUnused(axis_source); } -static void +static void axis_stop(void *data, struct wl_pointer *pointer, uint32_t time, uint32_t axis) { kUnused(data); kUnused(pointer); @@ -386,7 +386,7 @@ axis_stop(void *data, struct wl_pointer *pointer, uint32_t time, uint32_t axis) kUnused(axis); } -static void +static void axis_discrete(void *data, struct wl_pointer *pointer, uint32_t axis, int32_t discrete) { kUnused(data); kUnused(pointer); @@ -394,7 +394,7 @@ axis_discrete(void *data, struct wl_pointer *pointer, uint32_t axis, int32_t dis kUnused(discrete); } -static const struct +static const struct wl_pointer_listener pointer_listener = { .enter = pointer_enter, .leave = pointer_leave, @@ -409,7 +409,7 @@ wl_pointer_listener pointer_listener = { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -static void +static void seat_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps) { kUnused(data); @@ -427,28 +427,28 @@ seat_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps window_data_way->keyboard = 0x0; } - if ((caps & WL_SEAT_CAPABILITY_POINTER) && !window_data_way->pointer) + if ((caps & WL_SEAT_CAPABILITY_POINTER) && !window_data_way->pointer) { window_data_way->pointer = wl_seat_get_pointer(seat); wl_pointer_add_listener(window_data_way->pointer, &pointer_listener, window_data); - } - else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && window_data_way->pointer) + } + else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && window_data_way->pointer) { wl_pointer_destroy(window_data_way->pointer); window_data_way->pointer = 0x0; } } -static void +static void seat_name(void *data, struct wl_seat *seat, const char *name) { kUnused(data); kUnused(seat); printf("Seat '%s'n", name); } -static const struct +static const struct wl_seat_listener seat_listener = { - .capabilities = seat_capabilities, + .capabilities = seat_capabilities, .name = 0x0, }; @@ -460,7 +460,7 @@ wl_seat_listener seat_listener = { // for buffers. Known formats include argb8888 and xrgb8888. // // format: buffer pixel format -static void +static void shm_format(void *data, struct wl_shm *shm, uint32_t format) { kUnused(shm); @@ -472,7 +472,7 @@ shm_format(void *data, struct wl_shm *shm, uint32_t format) switch (format) { // We could do RGBA, but that would not be what is expected from minifb... - // case WL_SHM_FORMAT_ARGB8888: + // case WL_SHM_FORMAT_ARGB8888: case WL_SHM_FORMAT_XRGB8888: window_data_way->shm_format = format; break; @@ -483,14 +483,14 @@ shm_format(void *data, struct wl_shm *shm, uint32_t format) } } -static const struct +static const struct wl_shm_listener shm_listener = { .format = shm_format }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -static void +static void registry_global(void *data, struct wl_registry *registry, uint32_t id, char const *iface, uint32_t version) { kUnused(version); @@ -524,9 +524,9 @@ registry_global(void *data, struct wl_registry *registry, uint32_t id, char cons } } -static const struct +static const struct wl_registry_listener registry_listener = { - .global = registry_global, + .global = registry_global, .global_remove = 0x0, }; @@ -562,7 +562,7 @@ static const struct wl_shell_surface_listener shell_surface_listener = { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -struct mfb_window * +struct mfb_window * mfb_open_ex(const char *title, unsigned width, unsigned height, unsigned flags) { SWindowData *window_data = (SWindowData *) malloc(sizeof(SWindowData)); @@ -592,7 +592,7 @@ mfb_open_ex(const char *title, unsigned width, unsigned height, unsigned flags) init_keycodes(); - if (wl_display_dispatch(window_data_way->display) == -1 || + if (wl_display_dispatch(window_data_way->display) == -1 || wl_display_roundtrip(window_data_way->display) == -1) { return 0x0; } @@ -631,7 +631,7 @@ mfb_open_ex(const char *title, unsigned width, unsigned height, unsigned flags) calc_dst_factor(window_data, width, height); window_data_way->shm_pool = wl_shm_create_pool(window_data_way->shm, window_data_way->fd, length); - window_data->draw_buffer = wl_shm_pool_create_buffer(window_data_way->shm_pool, 0, + window_data->draw_buffer = wl_shm_pool_create_buffer(window_data_way->shm_pool, 0, window_data->buffer_width, window_data->buffer_height, window_data->buffer_stride, window_data_way->shm_format); @@ -680,7 +680,7 @@ out: // Notify the client when the related request is done. // // callback_data: request-specific data for the callback -static void +static void frame_done(void *data, struct wl_callback *callback, uint32_t cookie) { kUnused(cookie); @@ -689,14 +689,14 @@ frame_done(void *data, struct wl_callback *callback, uint32_t cookie) *(uint32_t *)data = 1; } -static const struct +static const struct wl_callback_listener frame_listener = { .done = frame_done, }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -mfb_update_state +mfb_update_state mfb_update_ex(struct mfb_window *window, void *buffer, unsigned width, unsigned height) { uint32_t done = 0; @@ -744,11 +744,11 @@ mfb_update_ex(struct mfb_window *window, void *buffer, unsigned width, unsigned resize_dst(window_data, width, height); wl_buffer_destroy(window_data->draw_buffer); - window_data->draw_buffer = wl_shm_pool_create_buffer(window_data_way->shm_pool, 0, + window_data->draw_buffer = wl_shm_pool_create_buffer(window_data_way->shm_pool, 0, window_data->buffer_width, window_data->buffer_height, window_data->buffer_stride, window_data_way->shm_format); } - + // update shm buffer memcpy(window_data_way->shm_ptr, buffer, window_data->buffer_stride * window_data->buffer_height); @@ -773,7 +773,7 @@ mfb_update_ex(struct mfb_window *window, void *buffer, unsigned width, unsigned /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -mfb_update_state +mfb_update_state mfb_update_events(struct mfb_window *window) { if(window == 0x0) { @@ -801,7 +801,7 @@ mfb_update_events(struct mfb_window *window) extern double g_time_for_frame; -bool +bool mfb_wait_sync(struct mfb_window *window) { if(window == 0x0) { return false; @@ -820,7 +820,7 @@ mfb_wait_sync(struct mfb_window *window) { if (wl_display_dispatch_pending(window_data_way->display) == -1) { return false; } - + if(window_data->close) { destroy_window_data(window_data); return false; @@ -846,11 +846,11 @@ mfb_wait_sync(struct mfb_window *window) { extern short int g_keycodes[512]; -void +void init_keycodes(void) { // Clear keys - for (size_t i = 0; i < sizeof(g_keycodes) / sizeof(g_keycodes[0]); ++i) + for (size_t i = 0; i < sizeof(g_keycodes) / sizeof(g_keycodes[0]); ++i) g_keycodes[i] = 0; g_keycodes[KEY_GRAVE] = KB_KEY_GRAVE_ACCENT; @@ -974,7 +974,7 @@ init_keycodes(void) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -bool +bool mfb_set_viewport(struct mfb_window *window, unsigned offset_x, unsigned offset_y, unsigned width, unsigned height) { SWindowData *window_data = (SWindowData *) window; @@ -999,7 +999,7 @@ mfb_set_viewport(struct mfb_window *window, unsigned offset_x, unsigned offset_y /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void -mfb_get_monitor_dpi(struct mfb_window *window, float *dpi_x, float *dpi_y) { +mfb_get_monitor_scale(struct mfb_window *window, float *scale_x, float *scale_y) { float x = 96.0, y = 96.0; if(window != 0x0) { @@ -1009,17 +1009,17 @@ mfb_get_monitor_dpi(struct mfb_window *window, float *dpi_x, float *dpi_y) { // I cannot find a way to get dpi under VirtualBox } - if (dpi_x) { - *dpi_x = x / 96.0f; - if(*dpi_x == 0) { - *dpi_x = 1.0f; + if (scale_x) { + *scale_x = x / 96.0f; + if(*scale_x == 0) { + *scale_x = 1.0f; } } - if (dpi_y) { - *dpi_y = y / 96.0f; - if (*dpi_y == 0) { - *dpi_y = 1.0f; + if (scale_y) { + *scale_y = y / 96.0f; + if (*scale_y == 0) { + *scale_y = 1.0f; } } } diff --git a/src/windows/WinMiniFB.c b/src/windows/WinMiniFB.c index f1a89bb..8f2d002 100644 --- a/src/windows/WinMiniFB.c +++ b/src/windows/WinMiniFB.c @@ -5,11 +5,8 @@ #if defined(USE_OPENGL_API) #include "gl/MiniFB_GL.h" #endif -#if defined(_DEBUG) || defined(DEBUG) - #include -#endif +#include #include - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Copied (and modified) from Windows Kit 10 to avoid setting _WIN32_WINNT to a higher version @@ -35,10 +32,14 @@ typedef enum mfb_MONITOR_DPI_TYPE { // user32.dll typedef BOOL(WINAPI *PFN_SetProcessDPIAware)(void); typedef BOOL(WINAPI *PFN_SetProcessDpiAwarenessContext)(HANDLE); +typedef UINT(WINAPI *PFN_GetDpiForWindow)(HWND); +typedef BOOL(WINAPI *PFN_EnableNonClientDpiScaling)(HWND); HMODULE mfb_user32_dll = 0x0; PFN_SetProcessDPIAware mfb_SetProcessDPIAware = 0x0; PFN_SetProcessDpiAwarenessContext mfb_SetProcessDpiAwarenessContext = 0x0; +PFN_GetDpiForWindow mfb_GetDpiForWindow = 0x0; +PFN_EnableNonClientDpiScaling mfb_EnableNonClientDpiScaling = 0x0; // shcore.dll typedef HRESULT(WINAPI *PFN_SetProcessDpiAwareness)(mfb_PROCESS_DPI_AWARENESS); @@ -56,6 +57,8 @@ load_functions() { if (mfb_user32_dll != 0x0) { mfb_SetProcessDPIAware = (PFN_SetProcessDPIAware) GetProcAddress(mfb_user32_dll, "SetProcessDPIAware"); mfb_SetProcessDpiAwarenessContext = (PFN_SetProcessDpiAwarenessContext) GetProcAddress(mfb_user32_dll, "SetProcessDpiAwarenessContext"); + mfb_GetDpiForWindow = (PFN_GetDpiForWindow) GetProcAddress(mfb_user32_dll, "GetDpiForWindow"); + mfb_EnableNonClientDpiScaling = (PFN_EnableNonClientDpiScaling) GetProcAddress(mfb_user32_dll, "EnableNonClientDpiScaling"); } } @@ -68,23 +71,56 @@ load_functions() { } } +//-- +// NOT Thread safe. Just convenient (Don't do this at home guys) +char * +GetErrorMessage() { + static char buffer[256]; + + buffer[0] = 0; + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, // Not used with FORMAT_MESSAGE_FROM_SYSTEM + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + buffer, + sizeof(buffer), + NULL); + + return buffer; +} + //-- void dpi_aware() { if (mfb_SetProcessDpiAwarenessContext != 0x0) { - mfb_SetProcessDpiAwarenessContext(mfb_DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); + if(mfb_SetProcessDpiAwarenessContext(mfb_DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) == false) { + uint32_t error = GetLastError(); + if(error == ERROR_INVALID_PARAMETER) { + error = NO_ERROR; + if(mfb_SetProcessDpiAwarenessContext(mfb_DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE) == false) { + error = GetLastError(); + } + } + if(error != NO_ERROR) { + fprintf(stderr, "Error (SetProcessDpiAwarenessContext): %s\n", GetErrorMessage()); + } + } } else if (mfb_SetProcessDpiAwareness != 0x0) { - mfb_SetProcessDpiAwareness(mfb_PROCESS_PER_MONITOR_DPI_AWARE); + if(mfb_SetProcessDpiAwareness(mfb_PROCESS_PER_MONITOR_DPI_AWARE) != S_OK) { + fprintf(stderr, "Error (SetProcessDpiAwareness): %s\n", GetErrorMessage()); + } } else if (mfb_SetProcessDPIAware != 0x0) { - mfb_SetProcessDPIAware(); + if(mfb_SetProcessDPIAware() == false) { + fprintf(stderr, "Error (SetProcessDPIAware): %s\n", GetErrorMessage()); + } } } //-- void -get_monitor_dpi(HWND hWnd, float *dpi_x, float *dpi_y) { +get_monitor_scale(HWND hWnd, float *scale_x, float *scale_y) { UINT x, y; if(mfb_GetDpiForMonitor != 0x0) { @@ -98,17 +134,17 @@ get_monitor_dpi(HWND hWnd, float *dpi_x, float *dpi_y) { ReleaseDC(NULL, dc); } - if (dpi_x) { - *dpi_x = x / (float) USER_DEFAULT_SCREEN_DPI; - if(*dpi_x == 0) { - *dpi_x = 1; + if (scale_x) { + *scale_x = x / (float) USER_DEFAULT_SCREEN_DPI; + if(*scale_x == 0) { + *scale_x = 1; } } - if (dpi_y) { - *dpi_y = y / (float) USER_DEFAULT_SCREEN_DPI; - if (*dpi_y == 0) { - *dpi_y = 1; + if (scale_y) { + *scale_y = y / (float) USER_DEFAULT_SCREEN_DPI; + if (*scale_y == 0) { + *scale_y = 1; } } } @@ -116,7 +152,7 @@ get_monitor_dpi(HWND hWnd, float *dpi_x, float *dpi_y) { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void -mfb_get_monitor_dpi(struct mfb_window *window, float *dpi_x, float *dpi_y) { +mfb_get_monitor_scale(struct mfb_window *window, float *scale_x, float *scale_y) { HWND hWnd = 0x0; if(window != 0x0) { @@ -124,7 +160,7 @@ mfb_get_monitor_dpi(struct mfb_window *window, float *dpi_x, float *dpi_y) { SWindowData_Win *window_data_win = (SWindowData_Win *) window_data->specific; hWnd = window_data_win->window; } - get_monitor_dpi(hWnd, dpi_x, dpi_y); + get_monitor_scale(hWnd, scale_x, scale_y); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -151,6 +187,31 @@ WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { + case WM_NCCREATE: + { + if(mfb_EnableNonClientDpiScaling) + mfb_EnableNonClientDpiScaling(hWnd); + + return DefWindowProc(hWnd, message, wParam, lParam);; + } + + // TODO + //case 0x02E4://WM_GETDPISCALEDSIZE: + //{ + // SIZE* size = (SIZE*) lParam; + // WORD dpi = LOWORD(wParam); + // return true; + // break; + //} + + // TODO + //case WM_DPICHANGED: + //{ + // const float xscale = HIWORD(wParam); + // const float yscale = LOWORD(wParam); + // break; + //} + #if !defined(USE_OPENGL_API) case WM_PAINT: { @@ -292,14 +353,14 @@ WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { case WM_SIZE: if (window_data) { - float scaleX, scaleY; + float scale_x, scale_y; uint32_t width, height; if(wParam == SIZE_MINIMIZED) { return res; } - get_monitor_dpi(hWnd, &scaleX, &scaleY); + get_monitor_scale(hWnd, &scale_x, &scale_y); window_data->window_width = LOWORD(lParam); window_data->window_height = HIWORD(lParam); resize_dst(window_data, window_data->window_width, window_data->window_height); @@ -310,8 +371,8 @@ WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { resize_GL(window_data); #endif if(window_data->window_width != 0 && window_data->window_height != 0) { - width = (uint32_t) (window_data->window_width / scaleX); - height = (uint32_t) (window_data->window_height / scaleY); + width = (uint32_t) (window_data->window_width / scale_x); + height = (uint32_t) (window_data->window_height / scale_y); kCall(resize_func, width, height); } } @@ -417,11 +478,12 @@ mfb_open_ex(const char *title, unsigned width, unsigned height, unsigned flags) } } else if (!(flags & WF_FULLSCREEN)) { - float dpi_x, dpi_y; - get_monitor_dpi(0, &dpi_x, &dpi_y); + float scale_x, scale_y; - rect.right = (LONG) (width * dpi_x); - rect.bottom = (LONG) (height * dpi_y); + get_monitor_scale(0, &scale_x, &scale_y); + + rect.right = (LONG) (width * scale_x); + rect.bottom = (LONG) (height * scale_y); AdjustWindowRect(&rect, s_window_style, 0); @@ -847,7 +909,7 @@ bool mfb_set_viewport(struct mfb_window *window, unsigned offset_x, unsigned offset_y, unsigned width, unsigned height) { SWindowData *window_data = (SWindowData *) window; SWindowData_Win *window_data_win = 0x0; - float scaleX, scaleY; + float scale_x, scale_y; if(window_data == 0x0) { return false; @@ -862,12 +924,12 @@ mfb_set_viewport(struct mfb_window *window, unsigned offset_x, unsigned offset_y window_data_win = (SWindowData_Win *) window_data->specific; - get_monitor_dpi(window_data_win->window, &scaleX, &scaleY); - window_data->dst_offset_x = (uint32_t) (offset_x * scaleX); - window_data->dst_offset_y = (uint32_t) (offset_y * scaleY); + get_monitor_scale(window_data_win->window, &scale_x, &scale_y); + window_data->dst_offset_x = (uint32_t) (offset_x * scale_x); + window_data->dst_offset_y = (uint32_t) (offset_y * scale_y); - window_data->dst_width = (uint32_t) (width * scaleX); - window_data->dst_height = (uint32_t) (height * scaleY); + window_data->dst_width = (uint32_t) (width * scale_x); + window_data->dst_height = (uint32_t) (height * scale_y); calc_dst_factor(window_data, window_data->window_width, window_data->window_height); diff --git a/src/x11/X11MiniFB.c b/src/x11/X11MiniFB.c index 6730ea0..4593c9b 100644 --- a/src/x11/X11MiniFB.c +++ b/src/x11/X11MiniFB.c @@ -26,7 +26,7 @@ void init_keycodes(SWindowData_X11 *window_data_x11); -extern void +extern void stretch_image(uint32_t *srcImage, uint32_t srcX, uint32_t srcY, uint32_t srcWidth, uint32_t srcHeight, uint32_t srcPitch, uint32_t *dstImage, uint32_t dstX, uint32_t dstY, uint32_t dstWidth, uint32_t dstHeight, uint32_t dstPitch); @@ -60,7 +60,7 @@ mfb_open_ex(const char *title, unsigned width, unsigned height, unsigned flags) free(window_data_x11); return 0x0; } - + init_keycodes(window_data_x11); window_data_x11->screen = DefaultScreen(window_data_x11->display); @@ -79,7 +79,7 @@ mfb_open_ex(const char *title, unsigned width, unsigned height, unsigned flags) break; } } - + XFree(formats); // We only support 32-bit right now @@ -120,23 +120,23 @@ mfb_open_ex(const char *title, unsigned width, unsigned height, unsigned flags) } window_data_x11->window = XCreateWindow( - window_data_x11->display, - defaultRootWindow, - posX, posY, - windowWidth, windowHeight, - 0, - depth, + window_data_x11->display, + defaultRootWindow, + posX, posY, + windowWidth, windowHeight, + 0, + depth, InputOutput, - visual, + visual, CWBackPixel | CWBorderPixel | CWBackingStore, &windowAttributes); if (!window_data_x11->window) return 0x0; - XSelectInput(window_data_x11->display, window_data_x11->window, - KeyPressMask | KeyReleaseMask - | ButtonPressMask | ButtonReleaseMask | PointerMotionMask - | StructureNotifyMask | ExposureMask + XSelectInput(window_data_x11->display, window_data_x11->window, + KeyPressMask | KeyReleaseMask + | ButtonPressMask | ButtonReleaseMask | PointerMotionMask + | StructureNotifyMask | ExposureMask | FocusChangeMask | EnterWindowMask | LeaveWindowMask ); @@ -219,11 +219,11 @@ int translate_key(int scancode); int translate_mod(int state); int translate_mod_ex(int key, int state, int is_pressed); -static void +static void processEvent(SWindowData *window_data, XEvent *event) { switch (event->type) { case KeyPress: - case KeyRelease: + case KeyRelease: { mfb_key key_code = (mfb_key) translate_key(event->xkey.keycode); int is_pressed = (event->type == KeyPress); @@ -274,10 +274,10 @@ processEvent(SWindowData *window_data, XEvent *event) { kCall(mouse_move_func, event->xmotion.x, event->xmotion.y); break; - case ConfigureNotify: + case ConfigureNotify: { window_data->window_width = event->xconfigure.width; - window_data->window_height = event->xconfigure.height; + window_data->window_height = event->xconfigure.height; resize_dst(window_data, event->xconfigure.width, event->xconfigure.height); #if defined(USE_OPENGL_API) @@ -292,7 +292,7 @@ processEvent(SWindowData *window_data, XEvent *event) { window_data_x11->image_scaler_height = 0; } XClearWindow(window_data_x11->display, window_data_x11->window); -#endif +#endif kCall(resize_func, window_data->window_width, window_data->window_height); } break; @@ -318,7 +318,7 @@ processEvent(SWindowData *window_data, XEvent *event) { } } -static void +static void processEvents(SWindowData *window_data) { XEvent event; SWindowData_X11 *window_data_x11 = (SWindowData_X11 *) window_data->specific; @@ -333,7 +333,7 @@ processEvents(SWindowData *window_data) { void destroy_window_data(SWindowData *window_data); -mfb_update_state +mfb_update_state mfb_update_ex(struct mfb_window *window, void *buffer, unsigned width, unsigned height) { if (window == 0x0) { return STATE_INVALID_WINDOW; @@ -387,7 +387,7 @@ mfb_update_ex(struct mfb_window *window, void *buffer, unsigned width, unsigned } if (window_data_x11->image_scaler != 0x0) { - stretch_image((uint32_t *) buffer, 0, 0, window_data->buffer_width, window_data->buffer_height, window_data->buffer_width, + stretch_image((uint32_t *) buffer, 0, 0, window_data->buffer_width, window_data->buffer_height, window_data->buffer_width, (uint32_t *) window_data_x11->image_buffer, 0, 0, window_data->dst_width, window_data->dst_height, window_data->dst_width); window_data_x11->image_scaler->data = (char *) window_data_x11->image_buffer; XPutImage(window_data_x11->display, window_data_x11->window, window_data_x11->gc, window_data_x11->image_scaler, 0, 0, window_data->dst_offset_x, window_data->dst_offset_y, window_data->dst_width, window_data->dst_height); @@ -405,13 +405,13 @@ mfb_update_ex(struct mfb_window *window, void *buffer, unsigned width, unsigned #endif processEvents(window_data); - + return STATE_OK; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -mfb_update_state +mfb_update_state mfb_update_events(struct mfb_window *window) { if (window == 0x0) { return STATE_INVALID_WINDOW; @@ -426,7 +426,7 @@ mfb_update_events(struct mfb_window *window) { SWindowData_X11 *window_data_x11 = (SWindowData_X11 *) window_data->specific; XFlush(window_data_x11->display); processEvents(window_data); - + return STATE_OK; } @@ -434,7 +434,7 @@ mfb_update_events(struct mfb_window *window) { extern double g_time_for_frame; -bool +bool mfb_wait_sync(struct mfb_window *window) { if (window == 0x0) { return STATE_INVALID_WINDOW; @@ -456,7 +456,7 @@ mfb_wait_sync(struct mfb_window *window) { XNextEvent(window_data_x11->display, &event); processEvent(window_data, &event); } - + if(window_data->close) { destroy_window_data(window_data); return false; @@ -474,19 +474,19 @@ mfb_wait_sync(struct mfb_window *window) { usleep(millis * 1000); //sched_yield(); } - + return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void +void destroy_window_data(SWindowData *window_data) { if (window_data != 0x0) { if (window_data->specific != 0x0) { SWindowData_X11 *window_data_x11 = (SWindowData_X11 *) window_data->specific; -#if defined(USE_OPENGL_API) +#if defined(USE_OPENGL_API) destroy_GL_context(window_data); #else if (window_data_x11->image != 0x0) { @@ -495,7 +495,7 @@ destroy_window_data(SWindowData *window_data) { XDestroyWindow(window_data_x11->display, window_data_x11->window); XCloseDisplay(window_data_x11->display); } -#endif +#endif mfb_timer_destroy(window_data_x11->timer); memset(window_data_x11, 0, sizeof(SWindowData_X11)); @@ -510,7 +510,7 @@ destroy_window_data(SWindowData *window_data) { extern short int g_keycodes[512]; -static int +static int translateKeyCodeB(int keySym) { switch (keySym) @@ -674,13 +674,13 @@ static int translateKeyCodeA(int keySym) { return KB_KEY_UNKNOWN; } -void +void init_keycodes(SWindowData_X11 *window_data_x11) { size_t i; int keySym; // Clear keys - for (i = 0; i < sizeof(g_keycodes) / sizeof(g_keycodes[0]); ++i) + for (i = 0; i < sizeof(g_keycodes) / sizeof(g_keycodes[0]); ++i) g_keycodes[i] = KB_KEY_UNKNOWN; // Valid key code range is [8,255], according to the Xlib manual @@ -697,7 +697,7 @@ init_keycodes(SWindowData_X11 *window_data_x11) { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -int +int translate_key(int scancode) { if (scancode < 0 || scancode > 255) return KB_KEY_UNKNOWN; @@ -707,7 +707,7 @@ translate_key(int scancode) { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -int +int translate_mod(int state) { int mod_keys = 0; @@ -729,7 +729,7 @@ translate_mod(int state) { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -int +int translate_mod_ex(int key, int state, int is_pressed) { int mod_keys = 0; @@ -775,7 +775,7 @@ translate_mod_ex(int key, int state, int is_pressed) { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -bool +bool mfb_set_viewport(struct mfb_window *window, unsigned offset_x, unsigned offset_y, unsigned width, unsigned height) { SWindowData *window_data = (SWindowData *) window; @@ -791,14 +791,14 @@ mfb_set_viewport(struct mfb_window *window, unsigned offset_x, unsigned offset_y window_data->dst_width = width; window_data->dst_height = height; calc_dst_factor(window_data, window_data->window_width, window_data->window_height); - + return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void -mfb_get_monitor_dpi(struct mfb_window *window, float *dpi_x, float *dpi_y) { +mfb_get_monitor_scale(struct mfb_window *window, float *scale_x, float *scale_y) { float x = 96.0, y = 96.0; if(window != 0x0) { @@ -812,17 +812,17 @@ mfb_get_monitor_dpi(struct mfb_window *window, float *dpi_x, float *dpi_y) { // All returning invalid values or 0 } - if (dpi_x) { - *dpi_x = x / 96.0f; - if(*dpi_x == 0) { - *dpi_x = 1.0f; + if (scale_x) { + *scale_x = x / 96.0f; + if(*scale_x == 0) { + *scale_x = 1.0f; } } - if (dpi_y) { - *dpi_y = y / 96.0f; - if (*dpi_y == 0) { - *dpi_y = 1.0f; + if (scale_y) { + *scale_y = y / 96.0f; + if (*scale_y == 0) { + *scale_y = 1.0f; } } } diff --git a/tests/ios/AppDelegate.m b/tests/ios/AppDelegate.m index 380a89b..824b650 100644 --- a/tests/ios/AppDelegate.m +++ b/tests/ios/AppDelegate.m @@ -74,7 +74,7 @@ resize(struct mfb_window *window, int width, int height) { dis ^= 0x01; } } - + mfb_update_state state = mfb_update_ex(g_window, g_buffer, g_width, g_height); if (state != STATE_OK) { free(g_buffer); @@ -89,9 +89,9 @@ resize(struct mfb_window *window, int width, int height) { // Override point for customization after application launch. kUnused(application); kUnused(launchOptions); - + if(g_window == 0x0) { - mfb_get_monitor_dpi(0x0, &g_scale, 0x0); + mfb_get_monitor_scale(0x0, &g_scale, 0x0); //g_scale = [UIScreen mainScreen].scale; g_width = [UIScreen mainScreen].bounds.size.width * g_scale; g_height = [UIScreen mainScreen].bounds.size.height * g_scale; @@ -135,7 +135,7 @@ resize(struct mfb_window *window, int width, int height) { - (void)applicationDidBecomeActive:(UIApplication *)application { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. kUnused(application); - + mDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(OnUpdateFrame)]; [mDisplayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; } @@ -144,7 +144,7 @@ resize(struct mfb_window *window, int width, int height) { - (void)applicationWillTerminate:(UIApplication *)application { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. kUnused(application); - + [mDisplayLink invalidate]; mfb_close(g_window); }