From f40a97a1c562c2c6c2215c31b3cf8be2e12aecc8 Mon Sep 17 00:00:00 2001 From: chaosddp Date: Sun, 25 Feb 2018 02:51:58 +0800 Subject: [PATCH 01/57] list of supported resolutions and other display info of monitor --- defos/src/defos.cpp | 36 ++++++++++++++++++++++++++++++++++++ defos/src/defos_private.h | 9 +++++++++ defos/src/defos_win.cpp | 19 +++++++++++++++++++ example/example.gui_script | 9 +++++++++ 4 files changed, 73 insertions(+) diff --git a/defos/src/defos.cpp b/defos/src/defos.cpp index a77fb7e..aa3601b 100644 --- a/defos/src/defos.cpp +++ b/defos/src/defos.cpp @@ -278,6 +278,41 @@ static int reset_cursor(lua_State *L) return 0; } +// get a list of available display info +static int get_display_list(lua_State *L) +{ + // final result + lua_newtable(L); + + #ifdef DM_PLATFORM_WINDOWS + int i=0; + DisplayInfo display = {0}; + + for(;defos_get_display_info(i, &display);i++) + { + // each display info as a table + lua_newtable(L); + lua_pushnumber(L, display.w); + lua_setfield(L, -2, "w"); + + lua_pushnumber(L, display.h); + lua_setfield(L, -2, "h"); + + lua_pushnumber(L, display.frequency); + lua_setfield(L, -2, "frequency"); + + lua_pushnumber(L, display.bitsPerPixel); + lua_setfield(L, -2, "bits_per_pixel"); + + lua_rawseti(L, 1, i+1); + } + #else + dmLogError("Not support on this platform."); + #endif + + return 1; +} + // Events static void set_event_handler(lua_State *L, int index, DefosEvent event) @@ -401,6 +436,7 @@ static const luaL_reg Module_methods[] = {"get_view_size", get_view_size}, {"set_cursor", set_cursor}, {"reset_cursor", reset_cursor}, + {"get_display_list", get_display_list}, {0, 0}}; static void LuaInit(lua_State *L) diff --git a/defos/src/defos_private.h b/defos/src/defos_private.h index a902274..69d2ada 100644 --- a/defos/src/defos_private.h +++ b/defos/src/defos_private.h @@ -29,6 +29,13 @@ typedef enum { DEFOS_CURSOR_IBEAM, } DefosCursor; +struct DisplayInfo { + unsigned long w; + unsigned long h; + unsigned long bitsPerPixel; + unsigned long frequency; +}; + extern LuaCallbackInfo defos_event_handlers[]; extern void defos_emit_event(DefosEvent event); extern void defos_event_handler_was_set(DefosEvent event); @@ -76,3 +83,5 @@ extern void defos_set_custom_cursor_win(const char *filename); extern void defos_set_custom_cursor_mac(dmBuffer::HBuffer buffer, float hotSpotX, float hotSpotY); extern void defos_set_cursor(DefosCursor cursor); extern void defos_reset_cursor(); + +extern bool defos_get_display_info(int index, DisplayInfo* display); \ No newline at end of file diff --git a/defos/src/defos_win.cpp b/defos/src/defos_win.cpp index 4a9080f..99fc562 100644 --- a/defos/src/defos_win.cpp +++ b/defos/src/defos_win.cpp @@ -339,6 +339,25 @@ void defos_reset_cursor() is_custom_cursor_loaded = false; } +bool defos_get_display_info(int index, DisplayInfo* display){ + DEVMODE dm = {0}; + dm.dmSize = sizeof(dm); + + BOOL result = EnumDisplaySettings(NULL, index, &dm); + + if(result == 0){ + return false; + } + + display->w = dm.dmPelsWidth; + display->h = dm.dmPelsHeight; + display->frequency = dm.dmDisplayFrequency; + display->bitsPerPixel = dm.dmBitsPerPel; + + + return true; +} + /******************** * internal functions ********************/ diff --git a/example/example.gui_script b/example/example.gui_script index 6741156..91cd157 100644 --- a/example/example.gui_script +++ b/example/example.gui_script @@ -112,6 +112,15 @@ function init(self) defos.set_console_visible(not defos.is_console_visible()) end + local display_list = defos.get_display_list() + + for i, d in ipairs(display_list) do + -- filter by frequency + if d.frequency == 60 or d.frequency == 75 then + print("resolution: "..d.w.."*"..d.h.." frequency: "..d.frequency.." bitsPerPixel: "..d.bits_per_pixel) + end + end + window.set_listener(window_callback) end From 3fc940c4d83ba3be353a09c5088c2eb6eca463de Mon Sep 17 00:00:00 2001 From: chaosddp Date: Thu, 1 Mar 2018 00:08:42 +0800 Subject: [PATCH 02/57] using bundle_resources instead of resource copying to load cursor for example project --- cursors/x86-win32/cursor_01.ani | Bin 0 -> 30182 bytes cursors/x86-win32/cursor_02.ani | Bin 0 -> 25880 bytes cursors/x86_64-win32/cursor_01.ani | Bin 0 -> 30182 bytes cursors/x86_64-win32/cursor_02.ani | Bin 0 -> 25880 bytes example/example.gui_script | 11 ----------- game.project | 1 + 6 files changed, 1 insertion(+), 11 deletions(-) create mode 100644 cursors/x86-win32/cursor_01.ani create mode 100644 cursors/x86-win32/cursor_02.ani create mode 100644 cursors/x86_64-win32/cursor_01.ani create mode 100644 cursors/x86_64-win32/cursor_02.ani diff --git a/cursors/x86-win32/cursor_01.ani b/cursors/x86-win32/cursor_01.ani new file mode 100644 index 0000000000000000000000000000000000000000..4708c49ab23dd6b4094dbf1266e1eaea05305086 GIT binary patch literal 30182 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 literal 0 HcmV?d00001 diff --git a/cursors/x86_64-win32/cursor_01.ani b/cursors/x86_64-win32/cursor_01.ani new file mode 100644 index 0000000000000000000000000000000000000000..4708c49ab23dd6b4094dbf1266e1eaea05305086 GIT binary patch literal 30182 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 literal 0 HcmV?d00001 diff --git a/example/example.gui_script b/example/example.gui_script index 6741156..8945b7d 100644 --- a/example/example.gui_script +++ b/example/example.gui_script @@ -44,17 +44,6 @@ function init(self) if system_name == "Windows" then for i, v in ipairs({ "cursor_01.ani", "cursor_02.ani" }) do - -- load source file and write them to save folder, so that we can access them with fullpath - local cursor_resource = resource.load("/resources/"..v) - local raw_bytes = buffer.get_bytes(cursor_resource, hash("data")) - - local cursor_path = sys.get_save_file(appname, v) - local f = io.open(cursor_path, "wb") - f:write(raw_bytes) - f:flush() - f:close() - - print(cursor_path) table.insert(self.cursors, cursor_path) end end diff --git a/game.project b/game.project index 36be68e..bf01ea1 100644 --- a/game.project +++ b/game.project @@ -3,6 +3,7 @@ title = DefOS version = 1.0.1 dependencies = https://github.com/andsve/dirtylarry/archive/master.zip custom_resources = resources/ +bundle_resources = /cursors [bootstrap] main_collection = /example/example.collectionc From 19b7852dd39a04401910aaa588ddd9f43ace5e54 Mon Sep 17 00:00:00 2001 From: chaosddp Date: Thu, 1 Mar 2018 00:13:07 +0800 Subject: [PATCH 03/57] update folder name --- game.project | 2 +- {cursors => icons}/x86-win32/cursor_01.ani | Bin {cursors => icons}/x86-win32/cursor_02.ani | Bin {cursors => icons}/x86_64-win32/cursor_01.ani | Bin {cursors => icons}/x86_64-win32/cursor_02.ani | Bin 5 files changed, 1 insertion(+), 1 deletion(-) rename {cursors => icons}/x86-win32/cursor_01.ani (100%) rename {cursors => icons}/x86-win32/cursor_02.ani (100%) rename {cursors => icons}/x86_64-win32/cursor_01.ani (100%) rename {cursors => icons}/x86_64-win32/cursor_02.ani (100%) diff --git a/game.project b/game.project index bf01ea1..eda529c 100644 --- a/game.project +++ b/game.project @@ -3,7 +3,7 @@ title = DefOS version = 1.0.1 dependencies = https://github.com/andsve/dirtylarry/archive/master.zip custom_resources = resources/ -bundle_resources = /cursors +bundle_resources = /icons [bootstrap] main_collection = /example/example.collectionc diff --git a/cursors/x86-win32/cursor_01.ani b/icons/x86-win32/cursor_01.ani similarity index 100% rename from cursors/x86-win32/cursor_01.ani rename to icons/x86-win32/cursor_01.ani diff --git a/cursors/x86-win32/cursor_02.ani b/icons/x86-win32/cursor_02.ani similarity index 100% rename from cursors/x86-win32/cursor_02.ani rename to icons/x86-win32/cursor_02.ani diff --git a/cursors/x86_64-win32/cursor_01.ani b/icons/x86_64-win32/cursor_01.ani similarity index 100% rename from cursors/x86_64-win32/cursor_01.ani rename to icons/x86_64-win32/cursor_01.ani diff --git a/cursors/x86_64-win32/cursor_02.ani b/icons/x86_64-win32/cursor_02.ani similarity index 100% rename from cursors/x86_64-win32/cursor_02.ani rename to icons/x86_64-win32/cursor_02.ani From 7cd1cb106f9e2ed926dcd611070bb150f0e93f53 Mon Sep 17 00:00:00 2001 From: chaosddp Date: Thu, 1 Mar 2018 00:16:45 +0800 Subject: [PATCH 04/57] move lisence --- {resources => icons}/Cursor_Lisence.txt | 0 resources/cursor_01.ani | Bin 30182 -> 0 bytes resources/cursor_02.ani | Bin 25880 -> 0 bytes 3 files changed, 0 insertions(+), 0 deletions(-) rename {resources => icons}/Cursor_Lisence.txt (100%) delete mode 100644 resources/cursor_01.ani delete mode 100644 resources/cursor_02.ani diff --git a/resources/Cursor_Lisence.txt b/icons/Cursor_Lisence.txt similarity index 100% rename from resources/Cursor_Lisence.txt rename to icons/Cursor_Lisence.txt diff --git a/resources/cursor_01.ani b/resources/cursor_01.ani deleted file mode 100644 index 4708c49ab23dd6b4094dbf1266e1eaea05305086..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30182 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 From 789e036d6258fbeb81074527e9577df708c152f7 Mon Sep 17 00:00:00 2001 From: chaosddp Date: Thu, 1 Mar 2018 00:22:52 +0800 Subject: [PATCH 05/57] fix path issue --- example/example.gui_script | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/example.gui_script b/example/example.gui_script index 8945b7d..ea3c440 100644 --- a/example/example.gui_script +++ b/example/example.gui_script @@ -44,7 +44,7 @@ function init(self) if system_name == "Windows" then for i, v in ipairs({ "cursor_01.ani", "cursor_02.ani" }) do - table.insert(self.cursors, cursor_path) + table.insert(self.cursors, v) end end From 13a9f28e9a0d8ee69cfdb9ae88dbbf34e7184e13 Mon Sep 17 00:00:00 2001 From: Alexey Gulev Date: Tue, 6 Mar 2018 11:44:55 +0300 Subject: [PATCH 06/57] added mac support --- defos/src/defos.cpp | 2 +- defos/src/defos_mac.mm | 57 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/defos/src/defos.cpp b/defos/src/defos.cpp index aa3601b..de6811a 100644 --- a/defos/src/defos.cpp +++ b/defos/src/defos.cpp @@ -284,7 +284,7 @@ static int get_display_list(lua_State *L) // final result lua_newtable(L); - #ifdef DM_PLATFORM_WINDOWS + #if defined(DM_PLATFORM_WINDOWS) || defined(DM_PLATFORM_OSX) int i=0; DisplayInfo display = {0}; diff --git a/defos/src/defos_mac.mm b/defos/src/defos_mac.mm index eb5f005..85568e6 100644 --- a/defos/src/defos_mac.mm +++ b/defos/src/defos_mac.mm @@ -6,11 +6,18 @@ #include "defos_private.h" #include #include +#include static NSWindow* window = nil; static NSCursor* current_cursor = nil; static NSCursor* default_cursor = nil; +#define MAX_DISPLAYS 32 +static CFArrayRef modeList; +uint32_t numDisplays; +CGDirectDisplayID displays[MAX_DISPLAYS]; +CVDisplayLinkRef dispLink; + static bool is_maximized = false; static bool is_mouse_in_view = false; static bool is_cursor_visible = true; @@ -21,6 +28,29 @@ static void enable_mouse_tracking(); static void disable_mouse_tracking(); +/* +* Convert the mode string to the more convinient bits per pixel value +*/ +static int getBPPFromModeString(CFStringRef mode) +{ + if ((CFStringCompare(mode, CFSTR(kIO30BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)) { + // This is a strange mode, where we using 10 bits per RGB component and pack it into 32 bits + // Java is not ready to work with this mode but we have to specify it as supported + return 30; + } + else if (CFStringCompare(mode, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) { + return 32; + } + else if (CFStringCompare(mode, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) { + return 16; + } + else if (CFStringCompare(mode, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) { + return 8; + } + + return 0; +} + void defos_init() { window = dmGraphics::GetNativeOSXNSWindow(); // [window disableCursorRects]; @@ -298,6 +328,33 @@ void defos_reset_cursor() { current_cursor = default_cursor; } +bool defos_get_display_info(int index, DisplayInfo* display){ + if (!modeList) { + CGGetActiveDisplayList (MAX_DISPLAYS, displays, &numDisplays); + modeList = CGDisplayCopyAllDisplayModes(displays[0], (__bridge CFDictionaryRef)@{ (__bridge NSString*)kCGDisplayShowDuplicateLowResolutionModes: @YES }); + CVDisplayLinkCreateWithCGDisplay(displays[0], &dispLink); + } + + if(index == [modeList count]){ + return false; + } + + CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modeList, index); + + display->w = CGDisplayModeGetWidth(mode); + display->h = CGDisplayModeGetHeight(mode); + display->frequency = CGDisplayModeGetRefreshRate(mode); + if (display->frequency== 0){ + const CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(dispLink); + if (!(time.flags & kCVTimeIsIndefinite)){ + display->frequency = (long) ((time.timeScale / (double) time.timeValue) + 0.5); + } + } + display->bitsPerPixel = getBPPFromModeString(CGDisplayModeCopyPixelEncoding(mode)); + + return true; +} + @interface DefOSMouseTracker : NSResponder @end @implementation DefOSMouseTracker From ec969c6847b8524d07fb6a7ea4c1235cd067e0da Mon Sep 17 00:00:00 2001 From: chaosddp Date: Tue, 6 Mar 2018 23:26:31 +0800 Subject: [PATCH 07/57] use dmArray to return resolution list --- defos/src/defos.cpp | 22 ++++++++++++---------- defos/src/defos_private.h | 2 +- defos/src/defos_win.cpp | 25 ++++++++++++------------- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/defos/src/defos.cpp b/defos/src/defos.cpp index de6811a..3b4da6a 100644 --- a/defos/src/defos.cpp +++ b/defos/src/defos.cpp @@ -284,25 +284,27 @@ static int get_display_list(lua_State *L) // final result lua_newtable(L); - #if defined(DM_PLATFORM_WINDOWS) || defined(DM_PLATFORM_OSX) - int i=0; - DisplayInfo display = {0}; - - for(;defos_get_display_info(i, &display);i++) + #if defined(DM_PLATFORM_WINDOWS) || defined(DM_PLATFORM_OSX) + dmArray displaylist; + defos_get_display_info(&displaylist); + + DisplayInfo disp; + for(int i=0;i* displist); \ No newline at end of file diff --git a/defos/src/defos_win.cpp b/defos/src/defos_win.cpp index 99fc562..1e8348a 100644 --- a/defos/src/defos_win.cpp +++ b/defos/src/defos_win.cpp @@ -339,23 +339,22 @@ void defos_reset_cursor() is_custom_cursor_loaded = false; } -bool defos_get_display_info(int index, DisplayInfo* display){ +void defos_get_display_info(dmArray* displist){ DEVMODE dm = {0}; dm.dmSize = sizeof(dm); - BOOL result = EnumDisplaySettings(NULL, index, &dm); - - if(result == 0){ - return false; + for(int i=0;EnumDisplaySettings(NULL, i, &dm)!=0;i++) + { + DisplayInfo display = { + dm.dmPelsWidth, + dm.dmPelsHeight, + dm.dmBitsPerPel, + dm.dmDisplayFrequency + }; + + displist->OffsetCapacity(1); + displist->Push(display); } - - display->w = dm.dmPelsWidth; - display->h = dm.dmPelsHeight; - display->frequency = dm.dmDisplayFrequency; - display->bitsPerPixel = dm.dmBitsPerPel; - - - return true; } /******************** From 1953c11c34945ae6280ccf94b27f48470f800159 Mon Sep 17 00:00:00 2001 From: chaosddp Date: Wed, 7 Mar 2018 00:21:44 +0800 Subject: [PATCH 08/57] delete dmarray before return --- defos/src/defos.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/defos/src/defos.cpp b/defos/src/defos.cpp index 3b4da6a..7a71fe0 100644 --- a/defos/src/defos.cpp +++ b/defos/src/defos.cpp @@ -4,6 +4,7 @@ #define DLIB_LOG_DOMAIN LIB_NAME #include +#include #if defined(DM_PLATFORM_OSX) || defined(DM_PLATFORM_WINDOWS) || defined(DM_PLATFORM_HTML5) @@ -285,13 +286,13 @@ static int get_display_list(lua_State *L) lua_newtable(L); #if defined(DM_PLATFORM_WINDOWS) || defined(DM_PLATFORM_OSX) - dmArray displaylist; - defos_get_display_info(&displaylist); + dmArray* displaylist = new dmArray(); + defos_get_display_info(displaylist); DisplayInfo disp; - for(int i=0;iSize();i++) { - disp = displaylist[i]; + disp = (*displaylist)[i]; // each display info as a table lua_newtable(L); lua_pushnumber(L, disp.w); @@ -308,6 +309,9 @@ static int get_display_list(lua_State *L) lua_rawseti(L, 1, i+1); } + + delete displaylist; + #else dmLogError("Not support on this platform."); #endif From a8fa61ff37536b3e19149092f95a0c75be5a003e Mon Sep 17 00:00:00 2001 From: Alexey Gulev Date: Tue, 6 Mar 2018 21:14:47 +0300 Subject: [PATCH 09/57] change macos code for working with dmArray --- defos/src/defos_mac.mm | 53 +++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/defos/src/defos_mac.mm b/defos/src/defos_mac.mm index 85568e6..c2529ad 100644 --- a/defos/src/defos_mac.mm +++ b/defos/src/defos_mac.mm @@ -13,10 +13,6 @@ static NSCursor* default_cursor = nil; #define MAX_DISPLAYS 32 -static CFArrayRef modeList; -uint32_t numDisplays; -CGDirectDisplayID displays[MAX_DISPLAYS]; -CVDisplayLinkRef dispLink; static bool is_maximized = false; static bool is_mouse_in_view = false; @@ -328,31 +324,34 @@ void defos_reset_cursor() { current_cursor = default_cursor; } -bool defos_get_display_info(int index, DisplayInfo* display){ - if (!modeList) { - CGGetActiveDisplayList (MAX_DISPLAYS, displays, &numDisplays); - modeList = CGDisplayCopyAllDisplayModes(displays[0], (__bridge CFDictionaryRef)@{ (__bridge NSString*)kCGDisplayShowDuplicateLowResolutionModes: @YES }); - CVDisplayLinkCreateWithCGDisplay(displays[0], &dispLink); - } - - if(index == [modeList count]){ - return false; - } +void defos_get_display_info(dmArray* displist){ + uint32_t numDisplays; + CGDirectDisplayID displays[MAX_DISPLAYS]; + CVDisplayLinkRef dispLink; + CGGetActiveDisplayList(MAX_DISPLAYS, displays, &numDisplays); + CFArrayRef modeList = CGDisplayCopyAllDisplayModes(displays[0], (__bridge CFDictionaryRef)@{ (__bridge NSString*)kCGDisplayShowDuplicateLowResolutionModes: @YES }); + CVDisplayLinkCreateWithCGDisplay(displays[0], &dispLink); - CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modeList, index); - - display->w = CGDisplayModeGetWidth(mode); - display->h = CGDisplayModeGetHeight(mode); - display->frequency = CGDisplayModeGetRefreshRate(mode); - if (display->frequency== 0){ - const CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(dispLink); - if (!(time.flags & kCVTimeIsIndefinite)){ - display->frequency = (long) ((time.timeScale / (double) time.timeValue) + 0.5); + for(int i = 0; i < [modeList count]; i++) + { + CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modeList, i); + DisplayInfo display = { + CGDisplayModeGetWidth(mode), + CGDisplayModeGetHeight(mode), + CGDisplayModeGetRefreshRate(mode), + getBPPFromModeString(CGDisplayModeCopyPixelEncoding(mode)) + }; + + if (display.frequency == 0){ + const CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(dispLink); + if (!(time.flags & kCVTimeIsIndefinite)){ + display.frequency = (long) ((time.timeScale / (double) time.timeValue) + 0.5); + } } - } - display->bitsPerPixel = getBPPFromModeString(CGDisplayModeCopyPixelEncoding(mode)); - - return true; + + displist->OffsetCapacity(1); + displist->Push(display); + } } @interface DefOSMouseTracker : NSResponder From a7974ba8a55a80809f0d4ecd959b9baa4cf44096 Mon Sep 17 00:00:00 2001 From: chaosddp Date: Mon, 7 May 2018 17:45:56 +0800 Subject: [PATCH 10/57] add support for linux, but with limitation --- defos/include/Xrandr.h | 590 +++++++++++++++++++++++++++++ defos/include/randr.h | 200 ++++++++++ defos/lib/x86_64-linux/libXrandr.a | Bin 0 -> 65022 bytes defos/src/defos.cpp | 2 +- defos/src/defos_linux.cpp | 202 ++++++---- 5 files changed, 915 insertions(+), 79 deletions(-) create mode 100644 defos/include/Xrandr.h create mode 100644 defos/include/randr.h create mode 100644 defos/lib/x86_64-linux/libXrandr.a diff --git a/defos/include/Xrandr.h b/defos/include/Xrandr.h new file mode 100644 index 0000000..d12f732 --- /dev/null +++ b/defos/include/Xrandr.h @@ -0,0 +1,590 @@ +/* + * Copyright © 2000 Compaq Computer Corporation, Inc. + * Copyright © 2002 Hewlett-Packard Company, Inc. + * Copyright © 2006 Intel Corporation + * Copyright © 2008 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + * + * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc. + * Keith Packard, Intel Corporation + */ +#if defined(DM_PLATFORM_LINUX) + +#ifndef _XRANDR_H_ +#define _XRANDR_H_ + +#include +#include + +#include + +_XFUNCPROTOBEGIN + +typedef XID RROutput; +typedef XID RRCrtc; +typedef XID RRMode; +typedef XID RRProvider; + +typedef struct { + int width, height; + int mwidth, mheight; +} XRRScreenSize; + +/* + * Events. + */ + +typedef struct { + int type; /* event base */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window which selected for this event */ + Window root; /* Root window for changed screen */ + Time timestamp; /* when the screen change occurred */ + Time config_timestamp; /* when the last configuration change */ + SizeID size_index; + SubpixelOrder subpixel_order; + Rotation rotation; + int width; + int height; + int mwidth; + int mheight; +} XRRScreenChangeNotifyEvent; + +typedef struct { + int type; /* event base */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window which selected for this event */ + int subtype; /* RRNotify_ subtype */ +} XRRNotifyEvent; + +typedef struct { + int type; /* event base */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window which selected for this event */ + int subtype; /* RRNotify_OutputChange */ + RROutput output; /* affected output */ + RRCrtc crtc; /* current crtc (or None) */ + RRMode mode; /* current mode (or None) */ + Rotation rotation; /* current rotation of associated crtc */ + Connection connection; /* current connection status */ + SubpixelOrder subpixel_order; +} XRROutputChangeNotifyEvent; + +typedef struct { + int type; /* event base */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window which selected for this event */ + int subtype; /* RRNotify_CrtcChange */ + RRCrtc crtc; /* current crtc (or None) */ + RRMode mode; /* current mode (or None) */ + Rotation rotation; /* current rotation of associated crtc */ + int x, y; /* position */ + unsigned int width, height; /* size */ +} XRRCrtcChangeNotifyEvent; + +typedef struct { + int type; /* event base */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window which selected for this event */ + int subtype; /* RRNotify_OutputProperty */ + RROutput output; /* related output */ + Atom property; /* changed property */ + Time timestamp; /* time of change */ + int state; /* NewValue, Deleted */ +} XRROutputPropertyNotifyEvent; + +typedef struct { + int type; /* event base */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window which selected for this event */ + int subtype; /* RRNotify_ProviderChange */ + RRProvider provider; /* current provider (or None) */ + Time timestamp; /* time of change */ + unsigned int current_role; +} XRRProviderChangeNotifyEvent; + +typedef struct { + int type; /* event base */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window which selected for this event */ + int subtype; /* RRNotify_ProviderProperty */ + RRProvider provider; /* related provider */ + Atom property; /* changed property */ + Time timestamp; /* time of change */ + int state; /* NewValue, Deleted */ +} XRRProviderPropertyNotifyEvent; + +typedef struct { + int type; /* event base */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window which selected for this event */ + int subtype; /* RRNotify_ResourceChange */ + Time timestamp; /* time of change */ +} XRRResourceChangeNotifyEvent; + +/* internal representation is private to the library */ +typedef struct _XRRScreenConfiguration XRRScreenConfiguration; + +Bool XRRQueryExtension (Display *dpy, + int *event_base_return, + int *error_base_return); +Status XRRQueryVersion (Display *dpy, + int *major_version_return, + int *minor_version_return); + +XRRScreenConfiguration *XRRGetScreenInfo (Display *dpy, + Window window); + +void XRRFreeScreenConfigInfo (XRRScreenConfiguration *config); + +/* + * Note that screen configuration changes are only permitted if the client can + * prove it has up to date configuration information. We are trying to + * insist that it become possible for screens to change dynamically, so + * we want to ensure the client knows what it is talking about when requesting + * changes. + */ +Status XRRSetScreenConfig (Display *dpy, + XRRScreenConfiguration *config, + Drawable draw, + int size_index, + Rotation rotation, + Time timestamp); + +/* added in v1.1, sorry for the lame name */ +Status XRRSetScreenConfigAndRate (Display *dpy, + XRRScreenConfiguration *config, + Drawable draw, + int size_index, + Rotation rotation, + short rate, + Time timestamp); + + +Rotation XRRConfigRotations(XRRScreenConfiguration *config, Rotation *current_rotation); + +Time XRRConfigTimes (XRRScreenConfiguration *config, Time *config_timestamp); + +XRRScreenSize *XRRConfigSizes(XRRScreenConfiguration *config, int *nsizes); + +short *XRRConfigRates (XRRScreenConfiguration *config, int sizeID, int *nrates); + +SizeID XRRConfigCurrentConfiguration (XRRScreenConfiguration *config, + Rotation *rotation); + +short XRRConfigCurrentRate (XRRScreenConfiguration *config); + +int XRRRootToScreen(Display *dpy, Window root); + +/* + * returns the screen configuration for the specified screen; does a lazy + * evalution to delay getting the information, and caches the result. + * These routines should be used in preference to XRRGetScreenInfo + * to avoid unneeded round trips to the X server. These are new + * in protocol version 0.1. + */ + + +void XRRSelectInput(Display *dpy, Window window, int mask); + +/* + * the following are always safe to call, even if RandR is not implemented + * on a screen + */ + + +Rotation XRRRotations(Display *dpy, int screen, Rotation *current_rotation); +XRRScreenSize *XRRSizes(Display *dpy, int screen, int *nsizes); +short *XRRRates (Display *dpy, int screen, int sizeID, int *nrates); +Time XRRTimes (Display *dpy, int screen, Time *config_timestamp); + + +/* Version 1.2 additions */ + +/* despite returning a Status, this returns 1 for success */ +Status +XRRGetScreenSizeRange (Display *dpy, Window window, + int *minWidth, int *minHeight, + int *maxWidth, int *maxHeight); + +void +XRRSetScreenSize (Display *dpy, Window window, + int width, int height, + int mmWidth, int mmHeight); + +typedef unsigned long XRRModeFlags; + +typedef struct _XRRModeInfo { + RRMode id; + unsigned int width; + unsigned int height; + unsigned long dotClock; + unsigned int hSyncStart; + unsigned int hSyncEnd; + unsigned int hTotal; + unsigned int hSkew; + unsigned int vSyncStart; + unsigned int vSyncEnd; + unsigned int vTotal; + char *name; + unsigned int nameLength; + XRRModeFlags modeFlags; +} XRRModeInfo; + +typedef struct _XRRScreenResources { + Time timestamp; + Time configTimestamp; + int ncrtc; + RRCrtc *crtcs; + int noutput; + RROutput *outputs; + int nmode; + XRRModeInfo *modes; +} XRRScreenResources; + +XRRScreenResources * +XRRGetScreenResources (Display *dpy, Window window); + +void +XRRFreeScreenResources (XRRScreenResources *resources); + +typedef struct _XRROutputInfo { + Time timestamp; + RRCrtc crtc; + char *name; + int nameLen; + unsigned long mm_width; + unsigned long mm_height; + Connection connection; + SubpixelOrder subpixel_order; + int ncrtc; + RRCrtc *crtcs; + int nclone; + RROutput *clones; + int nmode; + int npreferred; + RRMode *modes; +} XRROutputInfo; + +XRROutputInfo * +XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, RROutput output); + +void +XRRFreeOutputInfo (XRROutputInfo *outputInfo); + +Atom * +XRRListOutputProperties (Display *dpy, RROutput output, int *nprop); + +typedef struct { + Bool pending; + Bool range; + Bool immutable; + int num_values; + long *values; +} XRRPropertyInfo; + +XRRPropertyInfo * +XRRQueryOutputProperty (Display *dpy, RROutput output, Atom property); + +void +XRRConfigureOutputProperty (Display *dpy, RROutput output, Atom property, + Bool pending, Bool range, int num_values, + long *values); + +void +XRRChangeOutputProperty (Display *dpy, RROutput output, + Atom property, Atom type, + int format, int mode, + _Xconst unsigned char *data, int nelements); + +void +XRRDeleteOutputProperty (Display *dpy, RROutput output, Atom property); + +int +XRRGetOutputProperty (Display *dpy, RROutput output, + Atom property, long offset, long length, + Bool _delete, Bool pending, Atom req_type, + Atom *actual_type, int *actual_format, + unsigned long *nitems, unsigned long *bytes_after, + unsigned char **prop); + +XRRModeInfo * +XRRAllocModeInfo (_Xconst char *name, int nameLength); + +RRMode +XRRCreateMode (Display *dpy, Window window, XRRModeInfo *modeInfo); + +void +XRRDestroyMode (Display *dpy, RRMode mode); + +void +XRRAddOutputMode (Display *dpy, RROutput output, RRMode mode); + +void +XRRDeleteOutputMode (Display *dpy, RROutput output, RRMode mode); + +void +XRRFreeModeInfo (XRRModeInfo *modeInfo); + +typedef struct _XRRCrtcInfo { + Time timestamp; + int x, y; + unsigned int width, height; + RRMode mode; + Rotation rotation; + int noutput; + RROutput *outputs; + Rotation rotations; + int npossible; + RROutput *possible; +} XRRCrtcInfo; + +XRRCrtcInfo * +XRRGetCrtcInfo (Display *dpy, XRRScreenResources *resources, RRCrtc crtc); + +void +XRRFreeCrtcInfo (XRRCrtcInfo *crtcInfo); + +Status +XRRSetCrtcConfig (Display *dpy, + XRRScreenResources *resources, + RRCrtc crtc, + Time timestamp, + int x, int y, + RRMode mode, + Rotation rotation, + RROutput *outputs, + int noutputs); + +int +XRRGetCrtcGammaSize (Display *dpy, RRCrtc crtc); + +typedef struct _XRRCrtcGamma { + int size; + unsigned short *red; + unsigned short *green; + unsigned short *blue; +} XRRCrtcGamma; + +XRRCrtcGamma * +XRRGetCrtcGamma (Display *dpy, RRCrtc crtc); + +XRRCrtcGamma * +XRRAllocGamma (int size); + +void +XRRSetCrtcGamma (Display *dpy, RRCrtc crtc, XRRCrtcGamma *gamma); + +void +XRRFreeGamma (XRRCrtcGamma *gamma); + +/* Version 1.3 additions */ + +XRRScreenResources * +XRRGetScreenResourcesCurrent (Display *dpy, Window window); + +void +XRRSetCrtcTransform (Display *dpy, + RRCrtc crtc, + XTransform *transform, + _Xconst char *filter, + XFixed *params, + int nparams); + +typedef struct _XRRCrtcTransformAttributes { + XTransform pendingTransform; + char *pendingFilter; + int pendingNparams; + XFixed *pendingParams; + XTransform currentTransform; + char *currentFilter; + int currentNparams; + XFixed *currentParams; +} XRRCrtcTransformAttributes; + +/* + * Get current crtc transforms and filters. + * Pass *attributes to XFree to free + */ +Status +XRRGetCrtcTransform (Display *dpy, + RRCrtc crtc, + XRRCrtcTransformAttributes **attributes); + +/* + * intended to take RRScreenChangeNotify, or + * ConfigureNotify (on the root window) + * returns 1 if it is an event type it understands, 0 if not + */ +int XRRUpdateConfiguration(XEvent *event); + +typedef struct _XRRPanning { + Time timestamp; + unsigned int left; + unsigned int top; + unsigned int width; + unsigned int height; + unsigned int track_left; + unsigned int track_top; + unsigned int track_width; + unsigned int track_height; + int border_left; + int border_top; + int border_right; + int border_bottom; +} XRRPanning; + +XRRPanning * +XRRGetPanning (Display *dpy, XRRScreenResources *resources, RRCrtc crtc); + +void +XRRFreePanning (XRRPanning *panning); + +Status +XRRSetPanning (Display *dpy, + XRRScreenResources *resources, + RRCrtc crtc, + XRRPanning *panning); + +void +XRRSetOutputPrimary(Display *dpy, + Window window, + RROutput output); + +RROutput +XRRGetOutputPrimary(Display *dpy, + Window window); + +typedef struct _XRRProviderResources { + Time timestamp; + int nproviders; + RRProvider *providers; +} XRRProviderResources; + +XRRProviderResources * +XRRGetProviderResources(Display *dpy, Window window); + +void +XRRFreeProviderResources(XRRProviderResources *resources); + +typedef struct _XRRProviderInfo { + unsigned int capabilities; + int ncrtcs; + RRCrtc *crtcs; + int noutputs; + RROutput *outputs; + char *name; + int nassociatedproviders; + RRProvider *associated_providers; + unsigned int *associated_capability; + int nameLen; +} XRRProviderInfo; + +XRRProviderInfo * +XRRGetProviderInfo(Display *dpy, XRRScreenResources *resources, RRProvider provider); + +void +XRRFreeProviderInfo(XRRProviderInfo *provider); + +int +XRRSetProviderOutputSource(Display *dpy, XID provider, XID source_provider); + +int +XRRSetProviderOffloadSink(Display *dpy, XID provider, XID sink_provider); + +Atom * +XRRListProviderProperties (Display *dpy, RRProvider provider, int *nprop); + +XRRPropertyInfo * +XRRQueryProviderProperty (Display *dpy, RRProvider provider, Atom property); + +void +XRRConfigureProviderProperty (Display *dpy, RRProvider provider, Atom property, + Bool pending, Bool range, int num_values, + long *values); + +void +XRRChangeProviderProperty (Display *dpy, RRProvider provider, + Atom property, Atom type, + int format, int mode, + _Xconst unsigned char *data, int nelements); + +void +XRRDeleteProviderProperty (Display *dpy, RRProvider provider, Atom property); + +int +XRRGetProviderProperty (Display *dpy, RRProvider provider, + Atom property, long offset, long length, + Bool _delete, Bool pending, Atom req_type, + Atom *actual_type, int *actual_format, + unsigned long *nitems, unsigned long *bytes_after, + unsigned char **prop); + + +typedef struct _XRRMonitorInfo { + Atom name; + Bool primary; + Bool automatic; + int noutput; + int x; + int y; + int width; + int height; + int mwidth; + int mheight; + RROutput *outputs; +} XRRMonitorInfo; + +XRRMonitorInfo * +XRRAllocateMonitor(Display *dpy, int noutput); + +XRRMonitorInfo * +XRRGetMonitors(Display *dpy, Window window, Bool get_active, int *nmonitors); + +void +XRRSetMonitor(Display *dpy, Window window, XRRMonitorInfo *monitor); + +void +XRRDeleteMonitor(Display *dpy, Window window, Atom name); + +void +XRRFreeMonitors(XRRMonitorInfo *monitors); + +_XFUNCPROTOEND + +#endif /* _XRANDR_H_ */ + +#endif \ No newline at end of file diff --git a/defos/include/randr.h b/defos/include/randr.h new file mode 100644 index 0000000..956ab8c --- /dev/null +++ b/defos/include/randr.h @@ -0,0 +1,200 @@ +/* + * Copyright © 2000 Compaq Computer Corporation + * Copyright © 2002 Hewlett Packard Company + * Copyright © 2006 Intel Corporation + * Copyright © 2008 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + * + * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc. + * Keith Packard, Intel Corporation + */ +#if defined(DM_PLATFORM_LINUX) + +#ifndef _RANDR_H_ +#define _RANDR_H_ + +typedef unsigned short Rotation; +typedef unsigned short SizeID; +typedef unsigned short SubpixelOrder; +typedef unsigned short Connection; +typedef unsigned short XRandrRotation; +typedef unsigned short XRandrSizeID; +typedef unsigned short XRandrSubpixelOrder; +typedef unsigned long XRandrModeFlags; + +#define RANDR_NAME "RANDR" +#define RANDR_MAJOR 1 +#define RANDR_MINOR 5 + +#define RRNumberErrors 4 +#define RRNumberEvents 2 +#define RRNumberRequests 45 + +#define X_RRQueryVersion 0 +/* we skip 1 to make old clients fail pretty immediately */ +#define X_RROldGetScreenInfo 1 +#define X_RR1_0SetScreenConfig 2 +/* V1.0 apps share the same set screen config request id */ +#define X_RRSetScreenConfig 2 +#define X_RROldScreenChangeSelectInput 3 +/* 3 used to be ScreenChangeSelectInput; deprecated */ +#define X_RRSelectInput 4 +#define X_RRGetScreenInfo 5 + +/* V1.2 additions */ +#define X_RRGetScreenSizeRange 6 +#define X_RRSetScreenSize 7 +#define X_RRGetScreenResources 8 +#define X_RRGetOutputInfo 9 +#define X_RRListOutputProperties 10 +#define X_RRQueryOutputProperty 11 +#define X_RRConfigureOutputProperty 12 +#define X_RRChangeOutputProperty 13 +#define X_RRDeleteOutputProperty 14 +#define X_RRGetOutputProperty 15 +#define X_RRCreateMode 16 +#define X_RRDestroyMode 17 +#define X_RRAddOutputMode 18 +#define X_RRDeleteOutputMode 19 +#define X_RRGetCrtcInfo 20 +#define X_RRSetCrtcConfig 21 +#define X_RRGetCrtcGammaSize 22 +#define X_RRGetCrtcGamma 23 +#define X_RRSetCrtcGamma 24 + +/* V1.3 additions */ +#define X_RRGetScreenResourcesCurrent 25 +#define X_RRSetCrtcTransform 26 +#define X_RRGetCrtcTransform 27 +#define X_RRGetPanning 28 +#define X_RRSetPanning 29 +#define X_RRSetOutputPrimary 30 +#define X_RRGetOutputPrimary 31 + +#define RRTransformUnit (1L << 0) +#define RRTransformScaleUp (1L << 1) +#define RRTransformScaleDown (1L << 2) +#define RRTransformProjective (1L << 3) + +/* v1.4 */ +#define X_RRGetProviders 32 +#define X_RRGetProviderInfo 33 +#define X_RRSetProviderOffloadSink 34 +#define X_RRSetProviderOutputSource 35 +#define X_RRListProviderProperties 36 +#define X_RRQueryProviderProperty 37 +#define X_RRConfigureProviderProperty 38 +#define X_RRChangeProviderProperty 39 +#define X_RRDeleteProviderProperty 40 +#define X_RRGetProviderProperty 41 + +/* v1.5 */ +#define X_RRGetMonitors 42 +#define X_RRSetMonitor 43 +#define X_RRDeleteMonitor 44 + +/* Event selection bits */ +#define RRScreenChangeNotifyMask (1L << 0) +/* V1.2 additions */ +#define RRCrtcChangeNotifyMask (1L << 1) +#define RROutputChangeNotifyMask (1L << 2) +#define RROutputPropertyNotifyMask (1L << 3) +/* V1.4 additions */ +#define RRProviderChangeNotifyMask (1L << 4) +#define RRProviderPropertyNotifyMask (1L << 5) +#define RRResourceChangeNotifyMask (1L << 6) + +/* Event codes */ +#define RRScreenChangeNotify 0 +/* V1.2 additions */ +#define RRNotify 1 +/* RRNotify Subcodes */ +#define RRNotify_CrtcChange 0 +#define RRNotify_OutputChange 1 +#define RRNotify_OutputProperty 2 +#define RRNotify_ProviderChange 3 +#define RRNotify_ProviderProperty 4 +#define RRNotify_ResourceChange 5 +/* used in the rotation field; rotation and reflection in 0.1 proto. */ +#define RR_Rotate_0 1 +#define RR_Rotate_90 2 +#define RR_Rotate_180 4 +#define RR_Rotate_270 8 + +/* new in 1.0 protocol, to allow reflection of screen */ + +#define RR_Reflect_X 16 +#define RR_Reflect_Y 32 + +#define RRSetConfigSuccess 0 +#define RRSetConfigInvalidConfigTime 1 +#define RRSetConfigInvalidTime 2 +#define RRSetConfigFailed 3 + +/* new in 1.2 protocol */ + +#define RR_HSyncPositive 0x00000001 +#define RR_HSyncNegative 0x00000002 +#define RR_VSyncPositive 0x00000004 +#define RR_VSyncNegative 0x00000008 +#define RR_Interlace 0x00000010 +#define RR_DoubleScan 0x00000020 +#define RR_CSync 0x00000040 +#define RR_CSyncPositive 0x00000080 +#define RR_CSyncNegative 0x00000100 +#define RR_HSkewPresent 0x00000200 +#define RR_BCast 0x00000400 +#define RR_PixelMultiplex 0x00000800 +#define RR_DoubleClock 0x00001000 +#define RR_ClockDivideBy2 0x00002000 + +#define RR_Connected 0 +#define RR_Disconnected 1 +#define RR_UnknownConnection 2 + +#define BadRROutput 0 +#define BadRRCrtc 1 +#define BadRRMode 2 +#define BadRRProvider 3 + +/* Conventional RandR output properties */ + +#define RR_PROPERTY_BACKLIGHT "Backlight" +#define RR_PROPERTY_RANDR_EDID "EDID" +#define RR_PROPERTY_SIGNAL_FORMAT "SignalFormat" +#define RR_PROPERTY_SIGNAL_PROPERTIES "SignalProperties" +#define RR_PROPERTY_CONNECTOR_TYPE "ConnectorType" +#define RR_PROPERTY_CONNECTOR_NUMBER "ConnectorNumber" +#define RR_PROPERTY_COMPATIBILITY_LIST "CompatibilityList" +#define RR_PROPERTY_CLONE_LIST "CloneList" +#define RR_PROPERTY_BORDER "Border" +#define RR_PROPERTY_BORDER_DIMENSIONS "BorderDimensions" +#define RR_PROPERTY_GUID "GUID" +#define RR_PROPERTY_RANDR_TILE "TILE" + +/* roles this device can carry out */ +#define RR_Capability_None 0 +#define RR_Capability_SourceOutput 1 +#define RR_Capability_SinkOutput 2 +#define RR_Capability_SourceOffload 4 +#define RR_Capability_SinkOffload 8 + +#endif /* _RANDR_H_ */ +#endif \ No newline at end of file diff --git a/defos/lib/x86_64-linux/libXrandr.a b/defos/lib/x86_64-linux/libXrandr.a new file mode 100644 index 0000000000000000000000000000000000000000..5c10a1d660518a3b38ca47456ec315ade6d0ba2b GIT binary patch literal 65022 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 displaylist = new dmArray(); defos_get_display_info(displaylist); diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index 9f0071c..a29aa3d 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -17,10 +17,11 @@ #include #include #include +#include //static GC gc; -#define _NET_WM_STATE_REMOVE 0 -#define _NET_WM_STATE_ADD 1 +#define _NET_WM_STATE_REMOVE 0 +#define _NET_WM_STATE_ADD 1 #define _NET_WM_STATE_TOGGLE 2 #define XATOM(name) XInternAtom(disp, name, False) @@ -42,12 +43,10 @@ static Atom NET_WM_ACTION_MINIMIZE; static bool is_maximized = false; static bool is_fullscreen = false; -static Cursor custom_cursor;// image cursor - +static Cursor custom_cursor; // image cursor static bool is_window_visible(Window window); -static void send_message(Window& window, Atom type, long a, long b, long c, long d,long e); - +static void send_message(Window &window, Atom type, long a, long b, long c, long d, long e); void defos_init() { @@ -67,16 +66,14 @@ void defos_init() void defos_final() { - if(custom_cursor==NULL) + if (custom_cursor == NULL) { XFreeCursor(disp, custom_cursor); } - } void defos_event_handler_was_set(DefosEvent event) { - } bool defos_is_fullscreen() @@ -121,26 +118,26 @@ bool defos_is_cursor_visible() void defos_toggle_fullscreen() { - if(!is_fullscreen) + if (!is_fullscreen) { send_message(win, - NET_WM_STATE, - _NET_WM_STATE_ADD, - NET_WM_STATE_FULLSCREEN, - 0, - 1, - 0); -; + NET_WM_STATE, + _NET_WM_STATE_ADD, + NET_WM_STATE_FULLSCREEN, + 0, + 1, + 0); + ; } else { send_message(win, - NET_WM_STATE, - _NET_WM_STATE_REMOVE, - NET_WM_STATE_FULLSCREEN, - 0, - 1, - 0); + NET_WM_STATE, + _NET_WM_STATE_REMOVE, + NET_WM_STATE_FULLSCREEN, + 0, + 1, + 0); } is_fullscreen = !is_fullscreen; @@ -149,25 +146,25 @@ void defos_toggle_fullscreen() void defos_toggle_maximized() { - if(!is_maximized) + if (!is_maximized) { - send_message(win, - NET_WM_STATE, - _NET_WM_STATE_ADD, - NET_WM_STATE_MAXIMIZED_VERT, - NET_WM_STATE_MAXIMIZED_HORZ, - 1, - 0); + send_message(win, + NET_WM_STATE, + _NET_WM_STATE_ADD, + NET_WM_STATE_MAXIMIZED_VERT, + NET_WM_STATE_MAXIMIZED_HORZ, + 1, + 0); } else { send_message(win, - NET_WM_STATE, - _NET_WM_STATE_REMOVE, - NET_WM_STATE_MAXIMIZED_VERT, - NET_WM_STATE_MAXIMIZED_HORZ, - 1, - 0); + NET_WM_STATE, + _NET_WM_STATE_REMOVE, + NET_WM_STATE_MAXIMIZED_VERT, + NET_WM_STATE_MAXIMIZED_HORZ, + 1, + 0); } is_maximized = !is_maximized; @@ -187,16 +184,17 @@ bool defos_is_console_visible() void defos_set_window_size(float x, float y, float w, float h) { // change size only if it is visible - if(is_window_visible(win)) + if (is_window_visible(win)) { - if(isnan(x) || isnan(y)){ + if (isnan(x) || isnan(y)) + { XWindowAttributes attributes; XGetWindowAttributes(disp, root, &attributes); - x = ((float)attributes.width - w)/2; - y = ((float)attributes.height - h)/2; + x = ((float)attributes.width - w) / 2; + y = ((float)attributes.height - h) / 2; } - + XMoveResizeWindow(disp, win, (int)x, (int)y, (unsigned int)w, (unsigned int)h); XFlush(disp); } @@ -209,14 +207,14 @@ void defos_set_view_size(float x, float y, float w, float h) changes.y = (int)y; changes.width = (int)w; changes.height = (int)h; - + XConfigureWindow(disp, win, CWX | CWY | CWWidth | CWHeight, &changes); XFlush(disp); } void defos_set_window_title(const char *title_lua) { - XChangeProperty(disp, win, NET_WM_NAME, UTF8_STRING, 8, PropModeReplace, (unsigned char*)title_lua, strlen(title_lua)); + XChangeProperty(disp, win, NET_WM_NAME, UTF8_STRING, 8, PropModeReplace, (unsigned char *)title_lua, strlen(title_lua)); XFlush(disp); // IMPORTANT: we have to flush, or nothing will be changed } @@ -228,7 +226,7 @@ WinRect defos_get_window_size() WinRect defos_get_view_size() { - int x,y; + int x, y; unsigned int w, h, bw, depth; Window dummy; @@ -247,20 +245,23 @@ void defos_set_cursor_pos(float x, float y) void defos_move_cursor_to(float x, float y) { - WinRect rect = defos_get_window_size(); - - int ix = (int)x; - int iy = (int)y; + WinRect rect = defos_get_window_size(); - // TODO: need this? - if(ix > rect.w) ix = rect.w; - if(ix < 0) ix = 0; - if(iy > rect.h) iy=rect.h; - if(iy < 0) iy = 0; + int ix = (int)x; + int iy = (int)y; + // TODO: need this? + if (ix > rect.w) + ix = rect.w; + if (ix < 0) + ix = 0; + if (iy > rect.h) + iy = rect.h; + if (iy < 0) + iy = 0; - XWarpPointer(disp, None, win, 0, 0, 0, 0, ix, iy); - XFlush(disp); + XWarpPointer(disp, None, win, 0, 0, 0, 0, ix, iy); + XFlush(disp); } void defos_set_cursor_clipped(bool clipped) @@ -283,8 +284,8 @@ bool defos_is_cursor_locked() return false; } -void defos_update() { - +void defos_update() +{ } void defos_set_custom_cursor_linux(const char *filename) @@ -307,27 +308,72 @@ void defos_reset_cursor() { XUndefineCursor(disp, win); - if(custom_cursor!=NULL) + if (custom_cursor != NULL) { XFreeCursor(disp, custom_cursor); custom_cursor = NULL; } } +static const XRRModeInfo* getModeInfo(const XRRScreenResources* sr, RRMode id){ + for(int i=0;inmode;i++){ + if(sr->modes[i].id == id){ + return sr->modes+i; + } + } + + return NULL; +} + +static long calculateRefreshRate(const XRRModeInfo* mi) +{ + if (!mi->hTotal || !mi->vTotal) + return 0; + + return (long) ((double) mi->dotClock / ((double) mi->hTotal * (double) mi->vTotal)); +} + +// NOTE: seems like this function only can query those that with 60 fraquency +void defos_get_display_info(dmArray *displist) +{ + RROutput output = XRRGetOutputPrimary(disp, win); + + XRRScreenResources *res = XRRGetScreenResourcesCurrent(disp, win); + XRROutputInfo *oi= XRRGetOutputInfo(disp, res, output); + long bpp = (long)DefaultDepth(disp, screen); + + for(int i=0;inmode;i++){ + const XRRModeInfo *mi = getModeInfo(res, oi->modes[i]); + + DisplayInfo info; + // TODO: add rotation detect + info.w = (long)mi->width; + info.h= (long)mi->height; + info.frequency = calculateRefreshRate(mi); + info.bitsPerPixel = bpp; + + displist->OffsetCapacity(1); + displist->Push(info); + } + + XRRFreeOutputInfo(oi); + XRRFreeScreenResources(res); +} + static unsigned int get_cursor(DefosCursor cursor) { - switch(cursor) + switch (cursor) { - case DEFOS_CURSOR_ARROW: - return XC_left_ptr; - case DEFOS_CURSOR_CROSSHAIR: - return XC_tcross; - case DEFOS_CURSOR_HAND: - return XC_hand2; - case DEFOS_CURSOR_IBEAM: - return XC_xterm; - default: - return XC_left_ptr; + case DEFOS_CURSOR_ARROW: + return XC_left_ptr; + case DEFOS_CURSOR_CROSSHAIR: + return XC_tcross; + case DEFOS_CURSOR_HAND: + return XC_hand2; + case DEFOS_CURSOR_IBEAM: + return XC_xterm; + default: + return XC_left_ptr; } } @@ -339,7 +385,7 @@ static bool is_window_visible(Window window) } //from glfw/x11_window.c -static void send_message(Window& window, Atom type, long a, long b, long c, long d,long e) +static void send_message(Window &window, Atom type, long a, long b, long c, long d, long e) { XEvent event; memset(&event, 0, sizeof(event)); @@ -348,13 +394,13 @@ static void send_message(Window& window, Atom type, long a, long b, long c, long event.xclient.window = window; event.xclient.format = 32; event.xclient.message_type = type; - event.xclient.data.l[0]=a; - event.xclient.data.l[1]=b; - event.xclient.data.l[2]=c; - event.xclient.data.l[3]=d; - event.xclient.data.l[4]=e; - - XSendEvent(disp, root, False, SubstructureNotifyMask|SubstructureRedirectMask, &event); + event.xclient.data.l[0] = a; + event.xclient.data.l[1] = b; + event.xclient.data.l[2] = c; + event.xclient.data.l[3] = d; + event.xclient.data.l[4] = e; + + XSendEvent(disp, root, False, SubstructureNotifyMask | SubstructureRedirectMask, &event); } #endif \ No newline at end of file From c14a1877d100b5a83407c195c6056195a467fb7c Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 01:02:20 +0300 Subject: [PATCH 11/57] Implement display queries on macOS --- defos/src/defos.cpp | 101 ++++++++++++++++++------- defos/src/defos_html5.cpp | 12 ++- defos/src/defos_linux.cpp | 2 +- defos/src/defos_mac.mm | 150 +++++++++++++++++++++++++++++++------ defos/src/defos_private.h | 22 ++++-- defos/src/defos_win.cpp | 2 +- example/example.gui_script | 24 ++++-- game.project | 1 + 8 files changed, 251 insertions(+), 63 deletions(-) diff --git a/defos/src/defos.cpp b/defos/src/defos.cpp index 8d832a7..7195e96 100644 --- a/defos/src/defos.cpp +++ b/defos/src/defos.cpp @@ -319,43 +319,92 @@ static int reset_cursor(lua_State *L) return 0; } -// get a list of available display info -static int get_display_list(lua_State *L) +// Displays + +static void push_display_mode(lua_State *L, const DisplayModeInfo &mode) { - // final result lua_newtable(L); + lua_pushnumber(L, mode.width); + lua_setfield(L, -2, "width"); + lua_pushnumber(L, mode.height); + lua_setfield(L, -2, "height"); + lua_pushnumber(L, mode.refresh_rate); + lua_setfield(L, -2, "refresh_rate"); + lua_pushnumber(L, mode.scaling_factor); + lua_setfield(L, -2, "scaling_factor"); + lua_pushnumber(L, mode.bits_per_pixel); + lua_setfield(L, -2, "bits_per_pixel"); +} - #if defined(DM_PLATFORM_WINDOWS) || defined(DM_PLATFORM_OSX) || defined(DM_PLATFORM_LINUX) - dmArray* displaylist = new dmArray(); - defos_get_display_info(displaylist); +static int get_displays(lua_State *L) +{ + dmArray displayList; + defos_get_displays(displayList); - DisplayInfo disp; - for(int i=0;iSize();i++) + lua_newtable(L); // Final result + for (int i = 0; i < displayList.Size(); i++) { - disp = (*displaylist)[i]; - // each display info as a table + DisplayInfo &display = displayList[i]; + lua_newtable(L); // The display info table + + lua_pushlightuserdata(L, display.id); + lua_pushvalue(L, -1); + lua_setfield(L, -3, "id"); + + // screen positioning bounds lua_newtable(L); - lua_pushnumber(L, disp.w); - lua_setfield(L, -2, "w"); + lua_pushnumber(L, display.bounds.x); + lua_setfield(L, -2, "x"); + lua_pushnumber(L, display.bounds.y); + lua_setfield(L, -2, "y"); + lua_pushnumber(L, display.bounds.w); + lua_setfield(L, -2, "width"); + lua_pushnumber(L, display.bounds.h); + lua_setfield(L, -2, "height"); + lua_setfield(L, -3, "bounds"); + + push_display_mode(L, display.mode); + lua_setfield(L, -3, "mode"); + + if (display.name) + { + lua_pushstring(L, display.name); + lua_setfield(L, -3, "name"); + free(display.name); + } + + // result[id] = display + lua_pushvalue(L, -2); + lua_settable(L, -4); + + // result[i + 1] = display + lua_rawseti(L, -2, i + 1); + } - lua_pushnumber(L, disp.h); - lua_setfield(L, -2, "h"); + return 1; +} - lua_pushnumber(L, disp.frequency); - lua_setfield(L, -2, "frequency"); +static int get_display_modes(lua_State *L) +{ + luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); + DisplayID displayID = lua_touserdata(L, 1); - lua_pushnumber(L, disp.bitsPerPixel); - lua_setfield(L, -2, "bits_per_pixel"); + dmArray modeList; + defos_get_display_modes(displayID, modeList); - lua_rawseti(L, 1, i+1); + lua_newtable(L); + for (int i = 0; i < modeList.Size(); i++) + { + push_display_mode(L, modeList[i]); + lua_rawseti(L, -2, i + 1); } - delete displaylist; - - #else - dmLogError("Not support on this platform."); - #endif + return 1; +} +static int get_current_display_id(lua_State *L) +{ + lua_pushlightuserdata(L, defos_get_current_display()); return 1; } @@ -482,7 +531,9 @@ static const luaL_reg Module_methods[] = {"get_view_size", get_view_size}, {"set_cursor", set_cursor}, {"reset_cursor", reset_cursor}, - {"get_display_list", get_display_list}, + {"get_displays", get_displays}, + {"get_display_modes", get_display_modes}, + {"get_current_display_id", get_current_display_id}, {"set_window_icon", set_window_icon}, {"get_bundle_root", get_bundle_root}, {"get_parameters", get_parameters}, diff --git a/defos/src/defos_html5.cpp b/defos/src/defos_html5.cpp index 36375aa..da21fa2 100644 --- a/defos/src/defos_html5.cpp +++ b/defos/src/defos_html5.cpp @@ -152,7 +152,7 @@ void defos_set_window_icon(const char *icon_path) if (oldLink) { document.head.removeChild(oldLink); } var link = document.createElement('link'); link.rel = 'shortcut icon'; - link.href = src; + link.href = src; document.head.appendChild(link); } changeFavicon(UTF8ToString($0)); @@ -334,4 +334,14 @@ void defos_reset_cursor() { } } +void defos_get_displays(dmArray &displayList) { +} + +void defos_get_display_modes(DisplayID displayID, dmArray &modeList) { +} + +DisplayID defos_get_current_display() { + return NULL; +} + #endif diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index a29aa3d..b51469e 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -334,7 +334,7 @@ static long calculateRefreshRate(const XRRModeInfo* mi) } // NOTE: seems like this function only can query those that with 60 fraquency -void defos_get_display_info(dmArray *displist) +void defos_get_displays(dmArray *displist) { RROutput output = XRRGetOutputPrimary(disp, win); diff --git a/defos/src/defos_mac.mm b/defos/src/defos_mac.mm index 6151a64..aa93723 100644 --- a/defos/src/defos_mac.mm +++ b/defos/src/defos_mac.mm @@ -352,34 +352,138 @@ void defos_reset_cursor() { current_cursor = default_cursor; } -void defos_get_display_info(dmArray* displist){ +static DisplayModeInfo parse_mode(CGDisplayModeRef mode, CVDisplayLinkRef displayLink) { + DisplayModeInfo mode_info; + mode_info.width = CGDisplayModeGetPixelWidth(mode); + mode_info.height = CGDisplayModeGetPixelHeight(mode); + mode_info.scaling_factor = (double)mode_info.width / (double)CGDisplayModeGetWidth(mode); + mode_info.refresh_rate = CGDisplayModeGetRefreshRate(mode); + + CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(mode); + mode_info.bits_per_pixel = getBPPFromModeString(pixelEncoding); + CFRelease(pixelEncoding); + + if (mode_info.refresh_rate == 0) { + const CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(displayLink); + if (!(time.flags & kCVTimeIsIndefinite)) { + mode_info.refresh_rate = (double)time.timeScale / (double)time.timeValue; + } + } + + return mode_info; +} + +void defos_get_displays(dmArray &displayList){ uint32_t numDisplays; CGDirectDisplayID displays[MAX_DISPLAYS]; - CVDisplayLinkRef dispLink; - CGGetActiveDisplayList(MAX_DISPLAYS, displays, &numDisplays); - CFArrayRef modeList = CGDisplayCopyAllDisplayModes(displays[0], (__bridge CFDictionaryRef)@{ (__bridge NSString*)kCGDisplayShowDuplicateLowResolutionModes: @YES }); - CVDisplayLinkCreateWithCGDisplay(displays[0], &dispLink); - - for(int i = 0; i < [modeList count]; i++) - { - CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modeList, i); - DisplayInfo display = { - CGDisplayModeGetWidth(mode), - CGDisplayModeGetHeight(mode), - CGDisplayModeGetRefreshRate(mode), - getBPPFromModeString(CGDisplayModeCopyPixelEncoding(mode)) - }; - - if (display.frequency == 0){ - const CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(dispLink); - if (!(time.flags & kCVTimeIsIndefinite)){ - display.frequency = (long) ((time.timeScale / (double) time.timeValue) + 0.5); + CGGetActiveDisplayList(MAX_DISPLAYS, displays, &numDisplays); + + displayList.OffsetCapacity(numDisplays); + for (int i = 0; i < numDisplays; i++) { + CGDirectDisplayID displayID = displays[i]; + + // We don't report mirrored displays + if (CGDisplayIsInMirrorSet(displayID) && CGDisplayPrimaryDisplay(displayID) != displayID) { + continue; + } + + DisplayInfo display; + display.id = (void*)(size_t)displayID; + + CGRect bounds = CGDisplayBounds(displayID); + display.bounds.x = bounds.origin.x; + display.bounds.y = bounds.origin.y; + display.bounds.w = bounds.size.width; + display.bounds.h = bounds.size.height; + + CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displayID); + CVDisplayLinkRef displayLink; + CVDisplayLinkCreateWithCGDisplay(displayID, &displayLink); + display.mode = parse_mode(mode, displayLink); + CVDisplayLinkRelease(displayLink); + CGDisplayModeRelease(mode); + + display.name = NULL; // TODO? Seems pretty complicated + + displayList.Push(display); + } +} + +void defos_get_display_modes(DisplayID displayID_, dmArray &modeList) { + CGDirectDisplayID displayID = (CGDirectDisplayID)(size_t)displayID_; + + NSDictionary *optDict = [[NSDictionary alloc] initWithObjectsAndKeys: + [NSNumber numberWithBool: YES], kCGDisplayShowDuplicateLowResolutionModes, nil + ]; + CFArrayRef modes = CGDisplayCopyAllDisplayModes(displayID, (__bridge CFDictionaryRef)optDict); + [optDict release]; + + // Prepend the current display mode + int modeCount = CFArrayGetCount(modes) + 1; + CGDisplayModeRef* allModes = new CGDisplayModeRef[modeCount]; + allModes[0] = CGDisplayCopyDisplayMode(displayID); + for (int i = 1; i < modeCount; i++) { + allModes[i] = (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i - 1); + } + + // Make a display link for refresh rate detection fallback + CVDisplayLinkRef displayLink; + CVDisplayLinkCreateWithCGDisplay(displayID, &displayLink); + + modeList.OffsetCapacity(modeCount); + for (int i = 0; i < modeCount; i++) { + CGDisplayModeRef mode = allModes[i]; + DisplayModeInfo modeInfo = parse_mode(mode, displayLink); + + // Remove duplicates + size_t width = CGDisplayModeGetWidth(mode); + size_t height = CGDisplayModeGetHeight(mode); + size_t pixelWidth = modeInfo.width; + size_t pixelHeight = modeInfo.height; + double refreshRate = CGDisplayModeGetRefreshRate(mode); + CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(mode); + + bool shouldAdd = true; + for (int j = 0; j < i; j++) { + CGDisplayModeRef otherMode = allModes[j]; + if (CFEqual(mode, otherMode)) { + shouldAdd = false; + break; + } + + size_t otherWidth = CGDisplayModeGetWidth(otherMode); + size_t otherHeight = CGDisplayModeGetHeight(otherMode); + size_t otherPixelWidth = CGDisplayModeGetPixelWidth(otherMode); + size_t otherPixelHeight = CGDisplayModeGetPixelHeight(otherMode); + double otherRefreshRate = CGDisplayModeGetRefreshRate(otherMode); + CFStringRef otherPixelEncoding = CGDisplayModeCopyPixelEncoding(otherMode); + + bool samePixelEncoding = (CFStringCompare(pixelEncoding, otherPixelEncoding, 0) == kCFCompareEqualTo); + CFRelease(pixelEncoding); + CFRelease(otherPixelEncoding); + + if (samePixelEncoding + && pixelWidth == otherPixelWidth + && pixelHeight == otherPixelHeight + && width == otherWidth + && height == otherHeight + && refreshRate == otherRefreshRate + ) { + shouldAdd = false; + break; } } - - displist->OffsetCapacity(1); - displist->Push(display); + + if (shouldAdd) { modeList.Push(modeInfo); } } + + CVDisplayLinkRelease(displayLink); + CGDisplayModeRelease(allModes[0]); + CFRelease(modes); +} + +DisplayID defos_get_current_display() { + return (void*)(size_t)[[[[window screen] deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue]; } @interface DefOSMouseTracker : NSResponder diff --git a/defos/src/defos_private.h b/defos/src/defos_private.h index 737419a..eb40f8f 100644 --- a/defos/src/defos_private.h +++ b/defos/src/defos_private.h @@ -29,11 +29,21 @@ typedef enum { DEFOS_CURSOR_IBEAM, } DefosCursor; +typedef void* DisplayID; + +struct DisplayModeInfo { + unsigned long width; + unsigned long height; + unsigned long bits_per_pixel; + double refresh_rate; + double scaling_factor; +}; + struct DisplayInfo { - unsigned long w; - unsigned long h; - unsigned long bitsPerPixel; - unsigned long frequency; + DisplayID id; + struct WinRect bounds; + struct DisplayModeInfo mode; + char * name; }; extern LuaCallbackInfo defos_event_handlers[]; @@ -88,4 +98,6 @@ extern void defos_set_custom_cursor_linux(const char *filename); extern void defos_set_cursor(DefosCursor cursor); extern void defos_reset_cursor(); -extern void defos_get_display_info(dmArray* displist); +extern void defos_get_displays(dmArray &displayList); +extern void defos_get_display_modes(DisplayID displayID, dmArray &modeList); +extern DisplayID defos_get_current_display(); diff --git a/defos/src/defos_win.cpp b/defos/src/defos_win.cpp index 57bf4b7..7cecb3e 100644 --- a/defos/src/defos_win.cpp +++ b/defos/src/defos_win.cpp @@ -387,7 +387,7 @@ void defos_reset_cursor() is_custom_cursor_loaded = false; } -void defos_get_display_info(dmArray* displist){ +void defos_get_displays(dmArray* displist){ DEVMODE dm = {0}; dm.dmSize = sizeof(dm); diff --git a/example/example.gui_script b/example/example.gui_script index 22dc160..683c92d 100644 --- a/example/example.gui_script +++ b/example/example.gui_script @@ -68,7 +68,7 @@ function init(self) -- NOTE: cursor should be normal x11 cursor file that type is: image/x-xcursor table.insert(self.cursors, extract_to_savefolder("cursor.xcur")) end - + if system_name == "Windows" then for i, v in ipairs({"cursor_01.ani", "cursor_02.ani" }) do -- load source file and write them to save folder, so that we can access them with fullpath, or you can use bundle_resource @@ -129,13 +129,23 @@ function init(self) defos.set_console_visible(not defos.is_console_visible()) end - local display_list = defos.get_display_list() + local displays = defos.get_displays() + print("Found " .. #displays .. " displays:") + for i, display in ipairs(displays) do + pprint(display) + end - for i, d in ipairs(display_list) do - -- filter by frequency - if d.frequency == 60 or d.frequency == 75 then - print("resolution: "..d.w.."*"..d.h.." frequency: "..d.frequency.." bitsPerPixel: "..d.bits_per_pixel) - end + local current_display_id = defos.get_current_display_id() + print("Current display id: ", current_display_id) + + local modes = defos.get_display_modes(current_display_id) + print("Found " .. #modes .. " modes for current display:") + for i, mode in ipairs(modes) do + print( + mode.width .. "x" .. mode.height .. " " .. + mode.bits_per_pixel .. "bit @" .. mode.refresh_rate .. "Hz x" .. + mode.scaling_factor + ) end window.set_listener(window_callback) diff --git a/game.project b/game.project index 57620fb..08cc8ce 100644 --- a/game.project +++ b/game.project @@ -15,6 +15,7 @@ game_binding = /input/game.input_bindingc [display] width = 1024 height = 768 +high_dpi = 1 [physics] scale = 0.02 From eee06804a925f158ab32da99f5ca413d964fd948 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 01:02:27 +0300 Subject: [PATCH 12/57] Fix some indentation --- defos/src/defos_mac.mm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/defos/src/defos_mac.mm b/defos/src/defos_mac.mm index aa93723..2020faf 100644 --- a/defos/src/defos_mac.mm +++ b/defos/src/defos_mac.mm @@ -225,14 +225,14 @@ void defos_set_cursor_visible(bool visible) { if (is_cursor_visible == visible) { return; } is_cursor_visible = visible; if (visible) { - [NSCursor unhide]; + [NSCursor unhide]; } else { - [NSCursor hide]; + [NSCursor hide]; } } bool defos_is_cursor_visible() { - return is_cursor_visible; + return is_cursor_visible; } bool defos_is_mouse_in_view() { @@ -242,7 +242,7 @@ bool defos_is_mouse_in_view() { void defos_set_cursor_pos(float x, float y) { CGWarpMouseCursorPosition(CGPointMake(x, y)); if (!is_cursor_locked) { - CGAssociateMouseAndMouseCursorPosition(true); // Prevents a delay after the Wrap call + CGAssociateMouseAndMouseCursorPosition(true); // Prevents a delay after the Wrap call } } From c0d7f4cc9abd044a9eb84b8cfcf02de2a59334f4 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 01:07:27 +0300 Subject: [PATCH 13/57] Bolden README section headers --- README.md | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 08b5710..d5e6fc9 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ https://github.com/subsoap/defos/archive/master.zip ## Methods -Customize title bar accessories and title. +**Customize title bar** accessories and title. ```lua defos.disable_maximize_button() @@ -21,7 +21,7 @@ defos.set_window_title("I set this title using Defos") --- -Toggle window maximize status. +**Toggle window maximize** status. ```lua defos.set_maximized(bool_value) @@ -31,7 +31,7 @@ bool_value = defos.is_maximized() --- -Toggle full screen. On HTML5, this only works from `defos.on_click()`. +**Toggle full screen**. On HTML5, this only works from `defos.on_click()`. ```lua defos.set_fullscreen(bool_value) @@ -41,7 +41,7 @@ bool_value = defos.is_fullscreen() --- -Get/set the window's size and position in screen coordinates. The window area +**Get/set the window's size and position** in screen coordinates. The window area includes the title bar, so the actual contained game view area might be smaller than the given metrics. @@ -57,7 +57,7 @@ defos.set_window_size(x, y, w, h) --- -Get/set the game view size and position in screen coordinates. This adjusts +**Get/set the game view size and position** in screen coordinates. This adjusts the window so that its containing game view is at the desired size and position. The window will be larger than the given metrics because it includes the title bar. @@ -71,7 +71,7 @@ defos.set_view_size(x, y, w, h) --- -Show/hide the mouse cursor. +**Show/hide the mouse cursor.** ```lua defos.set_cursor_visible(bool_value) @@ -80,7 +80,7 @@ bool_value = defos.is_cursor_visible() --- -Respond to the mouse entering and leaving the game view area. +**Respond to the mouse entering and leaving** the game view area. ```lua bool_value = defos.is_mouse_in_view() @@ -94,7 +94,7 @@ end) --- -Move the cursor programatically. +**Move the cursor** programatically. ```lua defos.set_cursor_pos(x, y) -- In screen coordinates @@ -103,7 +103,7 @@ defos.move_cursor_to(x, y) -- In game view coordinates --- -Clip cursor to current game view area. Windows only. +**Clip cursor** to current game view area. ```lua defos.set_cursor_clipped(bool_value) @@ -112,7 +112,7 @@ bool_value = defos.is_cursor_clipped() --- -Lock cursor movement. On HTML5 this only works from `defos.on_click()`. +**Lock cursor movement**. On HTML5 this only works from `defos.on_click()`. ```lua defos.set_cursor_locked(bool_value) @@ -124,7 +124,7 @@ end) --- -Set custom hardware cursors. `cursor` can be one of the following: +**Set custom hardware cursors**. `cursor` can be one of the following: * `nil`: Resets the cursor to default. Equivalent to `defos.reset_cursor()`. * `defos.CURSOR_ARROW` * `defos.CURSOR_HAND` @@ -154,7 +154,7 @@ defos.reset_cursor() --- -On Windows only, show/hide the console window. Only works when not running +**Show/hide the console window** on Windows. Only works when not running from the Editor. ```lua @@ -164,7 +164,7 @@ bool_value = defos.is_console_visible() --- -On HTML5 only, get a synchronous event when the user clicks in the canvas. +On HTML5 only, **get a synchronous event when the user clicks** in the canvas. This is necessary because some HTML5 functions only work when called synchronously from an event handler. @@ -180,7 +180,7 @@ end) --- -Get the absolute path to the game's containing directory. On macOS this will be the path to the .app bundle +**Get the absolute path to the game's containing directory.** On macOS this will be the path to the .app bundle ```lua path = defos.get_bundle_root() @@ -188,15 +188,15 @@ path = defos.get_bundle_root() --- -The system path separator. `"\\"` on Windows, `"/"` everywhere else. +**The system path separator.** `"\\"` on Windows, `"/"` everywhere else. ```lua defos.PATH_SEP -``` +``` --- -Change the game's icon at runtime. +**Change the game's icon** at runtime. ```lua defos.set_window_icon(path_to_icon) @@ -204,7 +204,7 @@ defos.set_window_icon(path_to_icon) --- -Returns a table of command line arguments used to run the app. On HTML5, returns a table with a single string: the query string part of the URL (eg. `{ "?param1=foo¶m2=bar" }`). +**Returns a table of command line arguments** used to run the app. On HTML5, returns a table with a single string: the query string part of the URL (eg. `{ "?param1=foo¶m2=bar" }`). ```lua arguments = defos.get_parameters() From 275248b14130d5405cc85124ad854fa4892a057f Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 01:30:12 +0300 Subject: [PATCH 14/57] Document display queries --- README.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/README.md b/README.md index d5e6fc9..040d82e 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,64 @@ defos.set_view_size(x, y, w, h) --- +**Query displays**. + +`defos.get_displays()` returns a table which can be indexed with either number +indices (like an array), either with display `id`s. + +```lua +displays = defos.get_displays() +pprint(displays[1]) -- Print info about the main display +current_display_id = defos.get_current_display_id() -- Get the ID of the game's current display +pprint(displays[current_display_id]) -- Print info about the game's current display +``` + +A display info table has the following format: +```lua +{ + id = , + bounds = { -- This is the position and size in screen coordinates of the + x = 0, -- display (relative to the top-left corner of the main display) + y = 0, + width = 1440, + height = 900, + } + mode = { -- The current resolution mode of the display + width = 2880, + height = 1800, + scaling_factor = 2, + refresh_rate = 60, + bits_per_pixel = 32, + }, + name = "Built-in Retina Display", +} +``` + +--- + +**Query display modes** for a display. + +Returns a table with all the resolution modes a display supports. + +```lua +display_id = defos.get_current_display_id() +modes = defos.get_display_modes(display_id) +pprint(modes[1]) -- Print information about the first available resolution mode +``` + +A resolution mode has the following format: +```lua +{ + width = 2880, -- Full width/height in pixels (not points) + height = 1800, + scaling_factor = 2, -- Hi-DPI scaling factor + refresh_rate = 60, + bits_per_pixel = 32, +} +``` + +--- + **Show/hide the mouse cursor.** ```lua From cf8c55fe94c02204d771f3c91963ca5393ecd514 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 01:54:31 +0300 Subject: [PATCH 15/57] Query display name --- defos/src/defos_mac.mm | 81 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/defos/src/defos_mac.mm b/defos/src/defos_mac.mm index 2020faf..bcb85e9 100644 --- a/defos/src/defos_mac.mm +++ b/defos/src/defos_mac.mm @@ -5,6 +5,7 @@ #include "defos_private.h" #include +#include #include #include @@ -373,6 +374,84 @@ static DisplayModeInfo parse_mode(CGDisplayModeRef mode, CVDisplayLinkRef displa return mode_info; } +static io_service_t IOServicePortFromCGDisplayID(CGDirectDisplayID displayID) { + io_iterator_t iter; + io_service_t serv, servicePort = 0; + + CFMutableDictionaryRef matching = IOServiceMatching("IODisplayConnect"); + + // releases matching for us + kern_return_t err = IOServiceGetMatchingServices(kIOMasterPortDefault, matching, &iter); + if (err) { return 0; } + + while ((serv = IOIteratorNext(iter)) != 0) { + CFDictionaryRef displayInfo; + CFNumberRef vendorIDRef; + CFNumberRef productIDRef; + CFNumberRef serialNumberRef; + + displayInfo = IODisplayCreateInfoDictionary(serv, kIODisplayOnlyPreferredName); + + Boolean success; + success = CFDictionaryGetValueIfPresent(displayInfo, CFSTR(kDisplayVendorID), (const void**)&vendorIDRef); + success &= CFDictionaryGetValueIfPresent(displayInfo, CFSTR(kDisplayProductID), (const void**)&productIDRef); + + if (!success) { + CFRelease(displayInfo); + continue; + } + + SInt32 vendorID; + CFNumberGetValue(vendorIDRef, kCFNumberSInt32Type, &vendorID); + SInt32 productID; + CFNumberGetValue(productIDRef, kCFNumberSInt32Type, &productID); + + // If a serial number is found, use it. + // Otherwise serial number will be nil (= 0) which will match with the output of 'CGDisplaySerialNumber' + SInt32 serialNumber = 0; + if (CFDictionaryGetValueIfPresent(displayInfo, CFSTR(kDisplaySerialNumber), (const void**)&serialNumberRef)) { + CFNumberGetValue(serialNumberRef, kCFNumberSInt32Type, &serialNumber); + } + + // If the vendor and product id along with the serial don't match + // then we are not looking at the correct monitor. + // NOTE: The serial number is important in cases where two monitors + // are the exact same. + if (CGDisplayVendorNumber(displayID) != vendorID || + CGDisplayModelNumber(displayID) != productID || + CGDisplaySerialNumber(displayID) != serialNumber ) { + CFRelease(displayInfo); + continue; + } + + servicePort = serv; + CFRelease(displayInfo); + break; + } + + IOObjectRelease(iter); + return servicePort; +} + +static char* get_display_name(CGDirectDisplayID displayID) { + NSString *screenName = nil; + + NSDictionary *deviceInfo = (NSDictionary *)IODisplayCreateInfoDictionary(IOServicePortFromCGDisplayID(displayID), kIODisplayOnlyPreferredName); + NSDictionary *localizedNames = [deviceInfo objectForKey:[NSString stringWithUTF8String:kDisplayProductName]]; + + if ([localizedNames count] > 0) { + NSString *screenName = [localizedNames objectForKey:[[localizedNames allKeys] objectAtIndex:0]]; + size_t nameLength = [screenName lengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 1; + char *name = (char*)malloc(nameLength); + [screenName getCString:name maxLength:nameLength encoding:NSUTF8StringEncoding]; + [deviceInfo release]; + return name; + } + + [deviceInfo release]; + return NULL; +} + void defos_get_displays(dmArray &displayList){ uint32_t numDisplays; CGDirectDisplayID displays[MAX_DISPLAYS]; @@ -403,7 +482,7 @@ void defos_get_displays(dmArray &displayList){ CVDisplayLinkRelease(displayLink); CGDisplayModeRelease(mode); - display.name = NULL; // TODO? Seems pretty complicated + display.name = get_display_name(displayID); displayList.Push(display); } From c732a678e7f18076863a1faa14bce02847ceca48 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 11:34:11 +0300 Subject: [PATCH 16/57] Fix cursor memory leaks --- defos/src/defos_linux.cpp | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index b51469e..9617166 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -44,6 +44,7 @@ static bool is_maximized = false; static bool is_fullscreen = false; static Cursor custom_cursor; // image cursor +static bool has_custom_cursor = false; static bool is_window_visible(Window window); static void send_message(Window &window, Atom type, long a, long b, long c, long d, long e); @@ -66,9 +67,10 @@ void defos_init() void defos_final() { - if (custom_cursor == NULL) + if (has_custom_cursor) { XFreeCursor(disp, custom_cursor); + has_custom_cursor = false; } } @@ -290,28 +292,31 @@ void defos_update() void defos_set_custom_cursor_linux(const char *filename) { - custom_cursor = XcursorFilenameLoadCursor(disp, filename); - XDefineCursor(disp, win, custom_cursor); + Cursor cursor = XcursorFilenameLoadCursor(disp, filename); + XDefineCursor(disp, win, cursor); + if (has_custom_cursor) { XFreeCursor(disp, custom_cursor); } + custom_cursor = cursor; + has_custom_cursor = true; } static unsigned int get_cursor(DefosCursor cursor); -void defos_set_cursor(DefosCursor cursor) +void defos_set_cursor(DefosCursor cursor_type) { - // TODO: X11 support change the cursor color, add it later - defos_reset_cursor(); - custom_cursor = XCreateFontCursor(disp, get_cursor(cursor)); - XDefineCursor(disp, win, custom_cursor); + Cursor cursor = XCreateFontCursor(disp, get_cursor(cursor_type)); + XDefineCursor(disp, win, cursor); + if (has_custom_cursor) { XFreeCursor(disp, custom_cursor); } + custom_cursor = cursor; + has_custom_cursor = true; } void defos_reset_cursor() { - XUndefineCursor(disp, win); - - if (custom_cursor != NULL) + if (has_custom_cursor) { + XUndefineCursor(disp, win); XFreeCursor(disp, custom_cursor); - custom_cursor = NULL; + has_custom_cursor = false; } } From bdb1cc8e5b33c11d5945988baa602fd9abc2f589 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 11:40:07 +0300 Subject: [PATCH 17/57] Use reference instead of pointer for get_parameters returned array --- defos/src/defos.cpp | 9 ++++----- defos/src/defos_html5.cpp | 8 ++++---- defos/src/defos_mac.mm | 9 +++++---- defos/src/defos_private.h | 2 +- defos/src/defos_win.cpp | 6 +++--- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/defos/src/defos.cpp b/defos/src/defos.cpp index 7195e96..ef8ec84 100644 --- a/defos/src/defos.cpp +++ b/defos/src/defos.cpp @@ -161,17 +161,16 @@ static int get_bundle_root(lua_State *L) static int get_parameters(lua_State *L) { - dmArray* parameters = new dmArray(); + dmArray parameters; defos_get_parameters(parameters); lua_newtable(L); - for(int i = 0; i < parameters->Size(); i++) + for (unsigned int i = 0; i < parameters.Size(); i++) { - char* param = (*parameters)[i]; + char* param = parameters[i]; lua_pushstring(L, param); lua_rawseti(L, 1, i+1); free(param); } - delete parameters; return 1; } @@ -602,4 +601,4 @@ dmExtension::Result FinalizeDefos(dmExtension::Params *params) } DM_DECLARE_EXTENSION(EXTENSION_NAME, LIB_NAME, 0, 0, InitializeDefos, 0, 0, FinalizeDefos) -#endif \ No newline at end of file +#endif diff --git a/defos/src/defos_html5.cpp b/defos/src/defos_html5.cpp index da21fa2..638c6b3 100644 --- a/defos/src/defos_html5.cpp +++ b/defos/src/defos_html5.cpp @@ -170,16 +170,16 @@ char* defos_get_bundle_root() { return bundlePath; } -void defos_get_parameters(dmArray* parameters) { - char*param = (char*)EM_ASM_INT({ +void defos_get_parameters(dmArray ¶meters) { + char *param = (char*)EM_ASM_INT({ var jsString = window.location.search; var lengthBytes = lengthBytesUTF8(jsString) + 1; var stringOnWasmHeap = _malloc(lengthBytes); stringToUTF8(jsString, stringOnWasmHeap, lengthBytes+1); return stringOnWasmHeap; },0); - parameters->OffsetCapacity(1); - parameters->Push(param); + parameters.OffsetCapacity(1); + parameters.Push(param); } void defos_set_window_size(float x, float y, float w, float h) { diff --git a/defos/src/defos_mac.mm b/defos/src/defos_mac.mm index bcb85e9..07e229a 100644 --- a/defos/src/defos_mac.mm +++ b/defos/src/defos_mac.mm @@ -137,14 +137,15 @@ void defos_set_window_icon(const char *icon_path){ return bundlePath_lua; } -void defos_get_parameters(dmArray* parameters) { +void defos_get_parameters(dmArray ¶meters) { NSArray *args = [[NSProcessInfo processInfo] arguments]; - for (int i = 0; i < [args count]; i++){ + int argCount = [args count]; + parameters.OffsetCapacity(argCount); + for (int i = 0; i < argCount; i++){ const char *param = [args[i] UTF8String]; char* lua_param = (char*)malloc(strlen(param) + 1); strcpy(lua_param, param); - parameters->OffsetCapacity(1); - parameters->Push(lua_param); + parameters.Push(lua_param); } } diff --git a/defos/src/defos_private.h b/defos/src/defos_private.h index eb40f8f..e26e44f 100644 --- a/defos/src/defos_private.h +++ b/defos/src/defos_private.h @@ -69,7 +69,7 @@ extern bool defos_is_maximized(); extern void defos_set_window_title(const char* title_lua); extern void defos_set_window_icon(const char *icon_path); extern char* defos_get_bundle_root(); -extern void defos_get_parameters(dmArray* parameters); +extern void defos_get_parameters(dmArray ¶meters); extern void defos_set_window_size(float x, float y, float w, float h); extern WinRect defos_get_window_size(); diff --git a/defos/src/defos_win.cpp b/defos/src/defos_win.cpp index 7cecb3e..134c9ba 100644 --- a/defos/src/defos_win.cpp +++ b/defos/src/defos_win.cpp @@ -235,19 +235,19 @@ char* defos_get_bundle_root() { return bundlePath; } -void defos_get_parameters(dmArray* parameters) { +void defos_get_parameters(dmArray ¶meters) { LPWSTR *szArglist; int nArgs; int i; szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs); if( NULL != szArglist ){ + parameters.OffsetCapacity(nArgs); for( i=0; iOffsetCapacity(1); - parameters->Push(lua_param); + parameters.Push(lua_param); } } LocalFree(szArglist); From 011252bb783e141f965d00a3f097a4645baa32d7 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 11:56:29 +0300 Subject: [PATCH 18/57] Fix Linux build --- defos/src/defos_linux.cpp | 122 ++++++++++++++++++++++++-------------- 1 file changed, 76 insertions(+), 46 deletions(-) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index 9617166..b10c3b3 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -18,6 +18,7 @@ #include #include #include +#include //static GC gc; #define _NET_WM_STATE_REMOVE 0 @@ -320,51 +321,6 @@ void defos_reset_cursor() } } -static const XRRModeInfo* getModeInfo(const XRRScreenResources* sr, RRMode id){ - for(int i=0;inmode;i++){ - if(sr->modes[i].id == id){ - return sr->modes+i; - } - } - - return NULL; -} - -static long calculateRefreshRate(const XRRModeInfo* mi) -{ - if (!mi->hTotal || !mi->vTotal) - return 0; - - return (long) ((double) mi->dotClock / ((double) mi->hTotal * (double) mi->vTotal)); -} - -// NOTE: seems like this function only can query those that with 60 fraquency -void defos_get_displays(dmArray *displist) -{ - RROutput output = XRRGetOutputPrimary(disp, win); - - XRRScreenResources *res = XRRGetScreenResourcesCurrent(disp, win); - XRROutputInfo *oi= XRRGetOutputInfo(disp, res, output); - long bpp = (long)DefaultDepth(disp, screen); - - for(int i=0;inmode;i++){ - const XRRModeInfo *mi = getModeInfo(res, oi->modes[i]); - - DisplayInfo info; - // TODO: add rotation detect - info.w = (long)mi->width; - info.h= (long)mi->height; - info.frequency = calculateRefreshRate(mi); - info.bitsPerPixel = bpp; - - displist->OffsetCapacity(1); - displist->Push(info); - } - - XRRFreeOutputInfo(oi); - XRRFreeScreenResources(res); -} - static unsigned int get_cursor(DefosCursor cursor) { switch (cursor) @@ -389,6 +345,80 @@ static bool is_window_visible(Window window) return attributes.map_state == IsViewable; } +extern void defos_get_displays(dmArray &displayList) +{ +} + +extern void defos_get_display_modes(DisplayID displayID, dmArray &modeList) +{ +} + +extern DisplayID defos_get_current_display() +{ + return (DisplayID)XRRGetOutputPrimary(disp, win); +} + +// static const XRRModeInfo* getModeInfo(const XRRScreenResources* sr, RRMode id){ +// for(int i=0;inmode;i++){ +// if(sr->modes[i].id == id){ +// return sr->modes+i; +// } +// } +// +// return NULL; +// } +// +// static long calculateRefreshRate(const XRRModeInfo* mi) +// { +// if (!mi->hTotal || !mi->vTotal) +// return 0; +// +// return (long) ((double) mi->dotClock / ((double) mi->hTotal * (double) mi->vTotal)); +// } +// +// // NOTE: seems like this function only can query those that with 60 fraquency +// void defos_get_displays(dmArray *displist) +// { +// RROutput output = XRRGetOutputPrimary(disp, win); +// +// XRRScreenResources *res = XRRGetScreenResourcesCurrent(disp, win); +// XRROutputInfo *oi= XRRGetOutputInfo(disp, res, output); +// long bpp = (long)DefaultDepth(disp, screen); +// +// for(int i=0;inmode;i++){ +// const XRRModeInfo *mi = getModeInfo(res, oi->modes[i]); +// +// DisplayInfo info; +// // TODO: add rotation detect +// info.w = (long)mi->width; +// info.h= (long)mi->height; +// info.frequency = calculateRefreshRate(mi); +// info.bitsPerPixel = bpp; +// +// displist->OffsetCapacity(1); +// displist->Push(info); +// } +// +// XRRFreeOutputInfo(oi); +// XRRFreeScreenResources(res); +// } + +extern void defos_set_window_icon(const char *icon_path) +{ +} + +extern char* defos_get_bundle_root() +{ + const char *path = "."; + char *result = (char*)malloc(strlen(path) + 1); + strcpy(result, path); + return result; +} + +extern void defos_get_parameters(dmArray ¶meters) +{ +} + //from glfw/x11_window.c static void send_message(Window &window, Atom type, long a, long b, long c, long d, long e) { @@ -408,4 +438,4 @@ static void send_message(Window &window, Atom type, long a, long b, long c, long XSendEvent(disp, root, False, SubstructureNotifyMask | SubstructureRedirectMask, &event); } -#endif \ No newline at end of file +#endif From 8706fb415073575c9948941e5ac04aec49d936bd Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 12:56:13 +0300 Subject: [PATCH 19/57] Implement display mode query on Linux --- defos/src/defos_linux.cpp | 86 +++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 45 deletions(-) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index b10c3b3..a6270c7 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -349,8 +349,49 @@ extern void defos_get_displays(dmArray &displayList) { } +static const XRRModeInfo* get_mode_info(const XRRScreenResources* screenResources, RRMode id){ + for (int i = 0; i < screenResources->nmode; i++){ + if (screenResources->modes[i].id == id){ + return screenResources->modes + i; + } + } + return NULL; +} + +static double compute_refresh_rate(const XRRModeInfo* modeInfo) +{ + if (!modeInfo->hTotal || !modeInfo->vTotal) { + return 0; + } + return ((double)modeInfo->dotClock / ((double)modeInfo->hTotal * (double)modeInfo->vTotal)); +} + extern void defos_get_display_modes(DisplayID displayID, dmArray &modeList) { + RROutput output = (RROutput)displayID; + + XRRScreenResources *screenResources = XRRGetScreenResourcesCurrent(disp, win); + XRROutputInfo *outputInfo = XRRGetOutputInfo(disp, screenResources, output); + + unsigned long bpp = (long)DefaultDepth(disp, screen); + double scaling_factor = 1.0; // TODO: Get scaling factor + + modeList.OffsetCapacity(outputInfo->nmode); + for (int i = 0; i < outputInfo->nmode; i++){ + const XRRModeInfo *modeInfo = get_mode_info(screenResources, outputInfo->modes[i]); + + DisplayModeInfo mode; + mode.width = modeInfo->width; + mode.height = modeInfo->height; + mode.refresh_rate = compute_refresh_rate(modeInfo); + mode.bits_per_pixel = bpp; + mode.scaling_factor = scaling_factor; + + modeList.Push(mode); + } + + XRRFreeOutputInfo(outputInfo); + XRRFreeScreenResources(screenResources); } extern DisplayID defos_get_current_display() @@ -358,51 +399,6 @@ extern DisplayID defos_get_current_display() return (DisplayID)XRRGetOutputPrimary(disp, win); } -// static const XRRModeInfo* getModeInfo(const XRRScreenResources* sr, RRMode id){ -// for(int i=0;inmode;i++){ -// if(sr->modes[i].id == id){ -// return sr->modes+i; -// } -// } -// -// return NULL; -// } -// -// static long calculateRefreshRate(const XRRModeInfo* mi) -// { -// if (!mi->hTotal || !mi->vTotal) -// return 0; -// -// return (long) ((double) mi->dotClock / ((double) mi->hTotal * (double) mi->vTotal)); -// } -// -// // NOTE: seems like this function only can query those that with 60 fraquency -// void defos_get_displays(dmArray *displist) -// { -// RROutput output = XRRGetOutputPrimary(disp, win); -// -// XRRScreenResources *res = XRRGetScreenResourcesCurrent(disp, win); -// XRROutputInfo *oi= XRRGetOutputInfo(disp, res, output); -// long bpp = (long)DefaultDepth(disp, screen); -// -// for(int i=0;inmode;i++){ -// const XRRModeInfo *mi = getModeInfo(res, oi->modes[i]); -// -// DisplayInfo info; -// // TODO: add rotation detect -// info.w = (long)mi->width; -// info.h= (long)mi->height; -// info.frequency = calculateRefreshRate(mi); -// info.bitsPerPixel = bpp; -// -// displist->OffsetCapacity(1); -// displist->Push(info); -// } -// -// XRRFreeOutputInfo(oi); -// XRRFreeScreenResources(res); -// } - extern void defos_set_window_icon(const char *icon_path) { } From 73316da891d0d3db9096b957ac618bd234bb6bfb Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 13:55:45 +0300 Subject: [PATCH 20/57] Implement display query on Linux --- defos/src/defos_linux.cpp | 55 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index a6270c7..57ec0cd 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -345,10 +345,6 @@ static bool is_window_visible(Window window) return attributes.map_state == IsViewable; } -extern void defos_get_displays(dmArray &displayList) -{ -} - static const XRRModeInfo* get_mode_info(const XRRScreenResources* screenResources, RRMode id){ for (int i = 0; i < screenResources->nmode; i++){ if (screenResources->modes[i].id == id){ @@ -366,6 +362,57 @@ static double compute_refresh_rate(const XRRModeInfo* modeInfo) return ((double)modeInfo->dotClock / ((double)modeInfo->hTotal * (double)modeInfo->vTotal)); } +extern void defos_get_displays(dmArray &displayList) +{ + XRRScreenResources *screenResources = XRRGetScreenResourcesCurrent(disp, win); + unsigned long bpp = (long)DefaultDepth(disp, screen); + + displayList.OffsetCapacity(screenResources->ncrtc); + for (int i = 0; i < screenResources->ncrtc; i++) + { + RRCrtc crtc = screenResources->crtcs[i]; + DisplayInfo display; + + XRRCrtcInfo *crtcInfo = XRRGetCrtcInfo(disp, screenResources, crtc); + const XRRModeInfo * modeInfo = get_mode_info(screenResources, crtcInfo->mode); + + if (!modeInfo) + { + XRRFreeCrtcInfo(crtcInfo); + continue; + } + + display.id = (DisplayID)crtc; + display.bounds.x = crtcInfo->x; + display.bounds.y = crtcInfo->y; + display.bounds.w = crtcInfo->width; + display.bounds.h = crtcInfo->height; + display.mode.width = modeInfo->width; + display.mode.height = modeInfo->height; + display.mode.refresh_rate = compute_refresh_rate(modeInfo); + display.mode.bits_per_pixel = bpp; + display.mode.scaling_factor = (double)display.mode.width / (double)display.bounds.w; + display.name = NULL; + + if (crtcInfo->noutput > 0) + { + XRROutputInfo *outputInfo = XRRGetOutputInfo(disp, screenResources, crtcInfo->outputs[0]); + if (outputInfo->name) + { + display.name = (char*)malloc(outputInfo->nameLen + 1); + strcpy(display.name, outputInfo->name); + } + XRRFreeOutputInfo(outputInfo); + } + + displayList.Push(display); + + XRRFreeCrtcInfo(crtcInfo); + } + + XRRFreeScreenResources(screenResources); +} + extern void defos_get_display_modes(DisplayID displayID, dmArray &modeList) { RROutput output = (RROutput)displayID; From be94b64cee5b53b7222f83998207007e4d07656d Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 14:22:27 +0300 Subject: [PATCH 21/57] Stick to DisplayID == RRCrtc convention --- defos/src/defos_linux.cpp | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index 57ec0cd..4539858 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -415,13 +415,25 @@ extern void defos_get_displays(dmArray &displayList) extern void defos_get_display_modes(DisplayID displayID, dmArray &modeList) { - RROutput output = (RROutput)displayID; + RRCrtc crtc = (RRCrtc)displayID; XRRScreenResources *screenResources = XRRGetScreenResourcesCurrent(disp, win); + XRRCrtcInfo *crtcInfo = XRRGetCrtcInfo(disp, screenResources, crtc); + + if (crtcInfo->noutput <= 0) + { + XRRFreeCrtcInfo(crtcInfo); + XRRFreeScreenResources(screenResources); + return; + } + + RROutput output = crtcInfo->outputs[0]; XRROutputInfo *outputInfo = XRRGetOutputInfo(disp, screenResources, output); unsigned long bpp = (long)DefaultDepth(disp, screen); - double scaling_factor = 1.0; // TODO: Get scaling factor + + const XRRModeInfo *currentModeInfo = get_mode_info(screenResources, crtcInfo->mode); + double scaling_factor = (double)currentModeInfo->width / (double)crtcInfo->width; modeList.OffsetCapacity(outputInfo->nmode); for (int i = 0; i < outputInfo->nmode; i++){ @@ -443,7 +455,17 @@ extern void defos_get_display_modes(DisplayID displayID, dmArraycrtc; + + XRRFreeOutputInfo(outputInfo); + XRRFreeScreenResources(screenResources); + + return (DisplayID)crtc; } extern void defos_set_window_icon(const char *icon_path) From 2c71b00c65e0ff33e11c5fb4d37a936986fbeb4f Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 14:25:22 +0300 Subject: [PATCH 22/57] Ignore duplicate displays when mirroring --- defos/src/defos_linux.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index 4539858..598202f 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -382,6 +382,26 @@ extern void defos_get_displays(dmArray &displayList) continue; } + bool isMirror = false; + for (int j = 0; j < displayList.Size(); j++) + { + DisplayInfo &otherDisplay = displayList[j]; + if (otherDisplay.bounds.x == crtcInfo->x + && otherDisplay.bounds.y == crtcInfo->y + && otherDisplay.bounds.w == crtcInfo->width + && otherDisplay.bounds.h == crtcInfo->height) + { + isMirror = true; + break; + } + } + + if (isMirror) + { + XRRFreeCrtcInfo(crtcInfo); + continue; + } + display.id = (DisplayID)crtc; display.bounds.x = crtcInfo->x; display.bounds.y = crtcInfo->y; From b666ffd69e3e4542500d170a7cfaa50b2f2b028d Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 14:26:49 +0300 Subject: [PATCH 23/57] Fix some indentation --- defos/src/defos_linux.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index 598202f..9c758d2 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -346,8 +346,10 @@ static bool is_window_visible(Window window) } static const XRRModeInfo* get_mode_info(const XRRScreenResources* screenResources, RRMode id){ - for (int i = 0; i < screenResources->nmode; i++){ - if (screenResources->modes[i].id == id){ + for (int i = 0; i < screenResources->nmode; i++) + { + if (screenResources->modes[i].id == id) + { return screenResources->modes + i; } } @@ -356,7 +358,8 @@ static const XRRModeInfo* get_mode_info(const XRRScreenResources* screenResource static double compute_refresh_rate(const XRRModeInfo* modeInfo) { - if (!modeInfo->hTotal || !modeInfo->vTotal) { + if (!modeInfo->hTotal || !modeInfo->vTotal) + { return 0; } return ((double)modeInfo->dotClock / ((double)modeInfo->hTotal * (double)modeInfo->vTotal)); @@ -456,7 +459,8 @@ extern void defos_get_display_modes(DisplayID displayID, dmArraywidth / (double)crtcInfo->width; modeList.OffsetCapacity(outputInfo->nmode); - for (int i = 0; i < outputInfo->nmode; i++){ + for (int i = 0; i < outputInfo->nmode; i++) + { const XRRModeInfo *modeInfo = get_mode_info(screenResources, outputInfo->modes[i]); DisplayModeInfo mode; From 9a60cc014be622684180c34ea6ea05659f2a0cfc Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 14:42:39 +0300 Subject: [PATCH 24/57] Account for screen rotation --- defos/src/defos_linux.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index 9c758d2..b33773f 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -365,6 +365,11 @@ static double compute_refresh_rate(const XRRModeInfo* modeInfo) return ((double)modeInfo->dotClock / ((double)modeInfo->hTotal * (double)modeInfo->vTotal)); } +static bool axis_flipped(Rotation rotation) +{ + return !!(rotation & (RR_Rotate_90 | RR_Rotate_270)); +} + extern void defos_get_displays(dmArray &displayList) { XRRScreenResources *screenResources = XRRGetScreenResourcesCurrent(disp, win); @@ -414,7 +419,9 @@ extern void defos_get_displays(dmArray &displayList) display.mode.height = modeInfo->height; display.mode.refresh_rate = compute_refresh_rate(modeInfo); display.mode.bits_per_pixel = bpp; - display.mode.scaling_factor = (double)display.mode.width / (double)display.bounds.w; + display.mode.scaling_factor = (double)display.mode.width / (double)( + axis_flipped(crtcInfo->rotation) ? crtcInfo->height : crtcInfo->width + ); display.name = NULL; if (crtcInfo->noutput > 0) @@ -456,7 +463,9 @@ extern void defos_get_display_modes(DisplayID displayID, dmArraymode); - double scaling_factor = (double)currentModeInfo->width / (double)crtcInfo->width; + double scaling_factor = (double)currentModeInfo->width / (double)( + axis_flipped(crtcInfo->rotation) ? crtcInfo->height : crtcInfo->width + ); modeList.OffsetCapacity(outputInfo->nmode); for (int i = 0; i < outputInfo->nmode; i++) From ec7ba99d48ce0cdd64c605cf2183985c6969d143 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 16:36:02 +0300 Subject: [PATCH 25/57] Implement get_window_size on Linux --- defos/src/defos_linux.cpp | 62 +++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index b33773f..f3ee7e9 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -39,6 +39,7 @@ static Atom NET_WM_STATE_FULLSCREEN; static Atom NET_WM_STATE_MAXIMIZED_VERT; static Atom NET_WM_STATE_MAXIMIZED_HORZ; static Atom NET_WM_ACTION_MINIMIZE; +static Atom NET_FRAME_EXTENTS; // TODO: should query state from system static bool is_maximized = false; @@ -64,6 +65,7 @@ void defos_init() NET_WM_STATE_FULLSCREEN = XATOM("_NET_WM_STATE_FULLSCREEN"); NET_WM_STATE_MAXIMIZED_VERT = XATOM("_NET_WM_STATE_MAXIMIZED_VERT"); NET_WM_STATE_MAXIMIZED_HORZ = XATOM("_NET_WM_STATE_MAXIMIZED_HORZ"); + NET_FRAME_EXTENTS = XATOM("_NET_FRAME_EXTENTS"); } void defos_final() @@ -184,6 +186,36 @@ bool defos_is_console_visible() return false; } +typedef struct { + long left, right, top, bottom; +} WindowExtents; + +static WindowExtents get_window_extents() +{ + Atom actualType; + int actualFormat; + unsigned long nitems, bytesAfter; + long* extents = NULL; + XEvent event; + while (XGetWindowProperty(disp, win, NET_FRAME_EXTENTS, + 0, 4, False, AnyPropertyType, + &actualType, &actualFormat, + &nitems, &bytesAfter, (unsigned char**)&extents) != Success || bytesAfter != 0 + ) { + XNextEvent(disp, &event); + } + + if (!extents || nitems != 4) { + WindowExtents result = { 0, 0, 0, 0 }; + if (extents) { XFree(extents); } + return result; + } + + WindowExtents result = { extents[0], extents[1], extents[2], extents[3] }; + if (extents) { XFree(extents); } + return result; +} + void defos_set_window_size(float x, float y, float w, float h) { // change size only if it is visible @@ -223,8 +255,15 @@ void defos_set_window_title(const char *title_lua) WinRect defos_get_window_size() { - WinRect r = {0.0f, 0.0f, 0.0f, 0.0f}; - return r; + WindowExtents extents = get_window_extents(); + WinRect size = defos_get_view_size(); + + size.w += extents.left + extents.right; + size.h += extents.top + extents.bottom; + size.x -= extents.left; + size.y -= extents.top; + + return size; } WinRect defos_get_view_size() @@ -234,7 +273,7 @@ WinRect defos_get_view_size() Window dummy; XGetGeometry(disp, win, &dummy, &x, &y, &w, &h, &bw, &depth); - XTranslateCoordinates(disp, win, root, x, y, &x, &y, &dummy); + XTranslateCoordinates(disp, win, root, 0, 0, &x, &y, &dummy); WinRect r = {(float)x, (float)y, (float)w, (float)h}; return r; @@ -248,22 +287,7 @@ void defos_set_cursor_pos(float x, float y) void defos_move_cursor_to(float x, float y) { - WinRect rect = defos_get_window_size(); - - int ix = (int)x; - int iy = (int)y; - - // TODO: need this? - if (ix > rect.w) - ix = rect.w; - if (ix < 0) - ix = 0; - if (iy > rect.h) - iy = rect.h; - if (iy < 0) - iy = 0; - - XWarpPointer(disp, None, win, 0, 0, 0, 0, ix, iy); + XWarpPointer(disp, None, win, 0, 0, 0, 0, (int)x, (int)y); XFlush(disp); } From 9219d65127e9744906bd319e1a2eab57cd3be552 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 16:36:30 +0300 Subject: [PATCH 26/57] Implement get_current_screen_id correctly on Linux --- defos/src/defos_linux.cpp | 56 ++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index f3ee7e9..d22fed9 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -415,7 +415,7 @@ extern void defos_get_displays(dmArray &displayList) } bool isMirror = false; - for (int j = 0; j < displayList.Size(); j++) + for (unsigned int j = 0; j < displayList.Size(); j++) { DisplayInfo &otherDisplay = displayList[j]; if (otherDisplay.bounds.x == crtcInfo->x @@ -510,19 +510,61 @@ extern void defos_get_display_modes(DisplayID displayID, dmArrayncrtc; i++) + { + RRCrtc crtc = screenResources->crtcs[i]; + XRRCrtcInfo *crtcInfo = XRRGetCrtcInfo(disp, screenResources, crtc); + WinRect crtcBounds = { (float)crtcInfo->x, (float)crtcInfo->y, (float)crtcInfo->width, (float)crtcInfo->height }; + XRRFreeCrtcInfo(crtcInfo); - RRCrtc crtc = outputInfo->crtc; + if (!crtcBounds.w || !crtcBounds.h) { continue; } - XRRFreeOutputInfo(outputInfo); + WinRect clip = viewBounds; + if (crtcBounds.x > clip.x) + { + clip.w -= crtcBounds.x - clip.x; + clip.x = crtcBounds.x; + } + if (crtcBounds.y > clip.y) + { + clip.h -= crtcBounds.y - clip.y; + clip.y = crtcBounds.y; + } + if (crtcBounds.x + crtcBounds.w < clip.x + clip.w) + { + clip.w = crtcBounds.x + crtcBounds.w - clip.x; + } + if (crtcBounds.y + crtcBounds.h < clip.y + clip.h) + { + clip.h = crtcBounds.y + crtcBounds.h - clip.y; + } + + float area = (clip.w > 0 && clip.h > 0) ? clip.w * clip.h : 0.0f; + if (area > bestArea) + { + bestCrtc = crtc; + bestBounds = crtcBounds; + bestArea = area; + } + } XRRFreeScreenResources(screenResources); - return (DisplayID)crtc; + bounds = bestBounds; + return bestCrtc; +} + +extern DisplayID defos_get_current_display() +{ + WinRect bounds; + return (DisplayID)get_current_crtc(bounds); } extern void defos_set_window_icon(const char *icon_path) From 0ce309f7d2ce04986d39505c0b41dce75189c3df Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 16:48:32 +0300 Subject: [PATCH 27/57] Center window on current display in set_view_size and set_window_size --- defos/src/defos_linux.cpp | 37 +++++++++++++++++++++++++------------ example/example.gui_script | 3 +-- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index d22fed9..326b5d5 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -216,6 +216,8 @@ static WindowExtents get_window_extents() return result; } +static RRCrtc get_current_crtc(WinRect &bounds); + void defos_set_window_size(float x, float y, float w, float h) { // change size only if it is visible @@ -223,13 +225,18 @@ void defos_set_window_size(float x, float y, float w, float h) { if (isnan(x) || isnan(y)) { - XWindowAttributes attributes; - XGetWindowAttributes(disp, root, &attributes); - - x = ((float)attributes.width - w) / 2; - y = ((float)attributes.height - h) / 2; + WinRect screenBounds; + get_current_crtc(screenBounds); + x = screenBounds.x + ((float)screenBounds.w - w) / 2; + y = screenBounds.y + ((float)screenBounds.h - h) / 2; } + WindowExtents extents = get_window_extents(); + w -= extents.left + extents.right; + h -= extents.top + extents.bottom; + x += extents.left; + y += extents.top; + XMoveResizeWindow(disp, win, (int)x, (int)y, (unsigned int)w, (unsigned int)h); XFlush(disp); } @@ -237,14 +244,20 @@ void defos_set_window_size(float x, float y, float w, float h) void defos_set_view_size(float x, float y, float w, float h) { - XWindowChanges changes; - changes.x = (int)x; - changes.y = (int)y; - changes.width = (int)w; - changes.height = (int)h; + // change size only if it is visible + if (is_window_visible(win)) + { + if (isnan(x) || isnan(y)) + { + WinRect screenBounds; + get_current_crtc(screenBounds); + x = screenBounds.x + ((float)screenBounds.w - w) / 2; + y = screenBounds.y + ((float)screenBounds.h - h) / 2; + } - XConfigureWindow(disp, win, CWX | CWY | CWWidth | CWHeight, &changes); - XFlush(disp); + XMoveResizeWindow(disp, win, (int)x, (int)y, (unsigned int)w, (unsigned int)h); + XFlush(disp); + } } void defos_set_window_title(const char *title_lua) diff --git a/example/example.gui_script b/example/example.gui_script index 683c92d..3656864 100644 --- a/example/example.gui_script +++ b/example/example.gui_script @@ -201,8 +201,7 @@ function on_input(self, action_id, action) end) dirtylarry:button("set_window_size", action_id, action, function () - defos.set_window_size(nil, nil, 1024, 768) - --defos.set_view_size(0, 0, 800, 600) + defos.set_view_size(nil, nil, 1024, 768) end) dirtylarry:button("toggle_fullscreen", action_id, action, function () From 30ee2164d5c74254407fbe615dc11baf6b01e5e5 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 17:28:33 +0300 Subject: [PATCH 28/57] Query window hint state from system --- defos/src/defos_linux.cpp | 100 ++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 53 deletions(-) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index 326b5d5..8e3f975 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -38,13 +38,8 @@ static Atom NET_WM_STATE; static Atom NET_WM_STATE_FULLSCREEN; static Atom NET_WM_STATE_MAXIMIZED_VERT; static Atom NET_WM_STATE_MAXIMIZED_HORZ; -static Atom NET_WM_ACTION_MINIMIZE; static Atom NET_FRAME_EXTENTS; -// TODO: should query state from system -static bool is_maximized = false; -static bool is_fullscreen = false; - static Cursor custom_cursor; // image cursor static bool has_custom_cursor = false; @@ -81,14 +76,42 @@ void defos_event_handler_was_set(DefosEvent event) { } +static bool hint_state_contains_atom(Atom atom) +{ + Atom actualType; + int actualFormat; + unsigned long nItems, bytesAfter; + long* data = NULL; + XEvent event; + while (XGetWindowProperty(disp, win, NET_WM_STATE, + 0, (~0L), False, AnyPropertyType, + &actualType, &actualFormat, + &nItems, &bytesAfter, (unsigned char**)&data) == Success && bytesAfter != 0 + ) { + XNextEvent(disp, &event); + } + + if (data) { + for (unsigned int i = 0; i < nItems; i++) { + if (data[i] == atom) { + XFree(data); + return true; + } + } + XFree(data); + } + + return false; +} + bool defos_is_fullscreen() { - return is_fullscreen; + return hint_state_contains_atom(NET_WM_STATE_FULLSCREEN); } bool defos_is_maximized() { - return is_maximized; + return hint_state_contains_atom(NET_WM_STATE_MAXIMIZED_VERT); } bool defos_is_mouse_in_view() @@ -123,56 +146,27 @@ bool defos_is_cursor_visible() void defos_toggle_fullscreen() { - if (!is_fullscreen) - { - send_message(win, - NET_WM_STATE, - _NET_WM_STATE_ADD, - NET_WM_STATE_FULLSCREEN, - 0, - 1, - 0); - ; - } - else - { - send_message(win, - NET_WM_STATE, - _NET_WM_STATE_REMOVE, - NET_WM_STATE_FULLSCREEN, - 0, - 1, - 0); - } - - is_fullscreen = !is_fullscreen; + send_message(win, + NET_WM_STATE, + _NET_WM_STATE_TOGGLE, + NET_WM_STATE_FULLSCREEN, + 0, + 1, + 0 + ); XFlush(disp); } void defos_toggle_maximized() { - if (!is_maximized) - { - send_message(win, - NET_WM_STATE, - _NET_WM_STATE_ADD, - NET_WM_STATE_MAXIMIZED_VERT, - NET_WM_STATE_MAXIMIZED_HORZ, - 1, - 0); - } - else - { - send_message(win, - NET_WM_STATE, - _NET_WM_STATE_REMOVE, - NET_WM_STATE_MAXIMIZED_VERT, - NET_WM_STATE_MAXIMIZED_HORZ, - 1, - 0); - } - - is_maximized = !is_maximized; + send_message(win, + NET_WM_STATE, + _NET_WM_STATE_TOGGLE, + NET_WM_STATE_MAXIMIZED_VERT, + NET_WM_STATE_MAXIMIZED_HORZ, + 1, + 0 + ); XFlush(disp); } @@ -200,7 +194,7 @@ static WindowExtents get_window_extents() while (XGetWindowProperty(disp, win, NET_FRAME_EXTENTS, 0, 4, False, AnyPropertyType, &actualType, &actualFormat, - &nitems, &bytesAfter, (unsigned char**)&extents) != Success || bytesAfter != 0 + &nitems, &bytesAfter, (unsigned char**)&extents) == Success && bytesAfter != 0 ) { XNextEvent(disp, &event); } From 3b61b9c64bb54cf5d025c8b628db1cab9ed2eaae Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 17:44:21 +0300 Subject: [PATCH 29/57] Implement get_bundle_root for Linux --- defos/src/defos_linux.cpp | 44 +++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index 8e3f975..9736a7c 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -18,7 +18,12 @@ #include #include #include + #include +#include +#include +#include +#include //static GC gc; #define _NET_WM_STATE_REMOVE 0 @@ -401,7 +406,7 @@ static bool axis_flipped(Rotation rotation) return !!(rotation & (RR_Rotate_90 | RR_Rotate_270)); } -extern void defos_get_displays(dmArray &displayList) +void defos_get_displays(dmArray &displayList) { XRRScreenResources *screenResources = XRRGetScreenResourcesCurrent(disp, win); unsigned long bpp = (long)DefaultDepth(disp, screen); @@ -474,7 +479,7 @@ extern void defos_get_displays(dmArray &displayList) XRRFreeScreenResources(screenResources); } -extern void defos_get_display_modes(DisplayID displayID, dmArray &modeList) +void defos_get_display_modes(DisplayID displayID, dmArray &modeList) { RRCrtc crtc = (RRCrtc)displayID; @@ -568,25 +573,46 @@ static RRCrtc get_current_crtc(WinRect &bounds) return bestCrtc; } -extern DisplayID defos_get_current_display() +DisplayID defos_get_current_display() { WinRect bounds; return (DisplayID)get_current_crtc(bounds); } -extern void defos_set_window_icon(const char *icon_path) +void defos_set_window_icon(const char *icon_path) +{ + dmLogInfo("Method 'defos_set_window_icon' is not supported on Linux"); +} + +static char* copy_string(const char * s) { + char *newString = (char*)malloc(strlen(s) + 1); + strcpy(newString, s); + return newString; } -extern char* defos_get_bundle_root() +char* defos_get_bundle_root() { - const char *path = "."; - char *result = (char*)malloc(strlen(path) + 1); - strcpy(result, path); + char* result; + char* path = (char*)malloc(PATH_MAX + 2); + ssize_t ret = readlink("/proc/self/exe", path, PATH_MAX + 2); + if (ret >= 0 && ret <= PATH_MAX + 1) { + result = copy_string(dirname(path)); + } else { + const char* path2 = (const char*)getauxval(AT_EXECFN); + if (!path2) { + result = copy_string("."); + } else if (!realpath(path2, path)) { + result = copy_string("."); + } else { + result = copy_string(dirname(path)); + } + } + free(path); return result; } -extern void defos_get_parameters(dmArray ¶meters) +void defos_get_parameters(dmArray ¶meters) { } From b052993d4cf86076f04218af094a6a7b20530374 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 17:56:35 +0300 Subject: [PATCH 30/57] Implement is_mouse_in_view() on Linux --- defos/src/defos_linux.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index 9736a7c..38fc255 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -86,7 +86,7 @@ static bool hint_state_contains_atom(Atom atom) Atom actualType; int actualFormat; unsigned long nItems, bytesAfter; - long* data = NULL; + Atom* data = NULL; XEvent event; while (XGetWindowProperty(disp, win, NET_WM_STATE, 0, (~0L), False, AnyPropertyType, @@ -121,7 +121,18 @@ bool defos_is_maximized() bool defos_is_mouse_in_view() { - return false; + Window d1, d2; + int x, y, d3, d4; + unsigned int d5; + if (!XQueryPointer(disp, win, &d1, &d2, &d3, &d4, &x, &y, &d5)) { return false; } + + if (x < 0 || y < 0) { return false; } + + unsigned int w, h, d6; + XGetGeometry(disp, win, &d1, &d3, &d4, &w, &h, &d5, &d6); + + if (x >= w || y >= h) { return false; } + return true; } void defos_disable_maximize_button() From 7739f1956e965a5788f29126648a6211c387a259 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 18:39:48 +0300 Subject: [PATCH 31/57] Implement disable_window_resize() on Linux --- defos/src/defos_linux.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index 38fc255..0082785 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -47,6 +47,7 @@ static Atom NET_FRAME_EXTENTS; static Cursor custom_cursor; // image cursor static bool has_custom_cursor = false; +static bool resize_locked = false; static bool is_window_visible(Window window); static void send_message(Window &window, Atom type, long a, long b, long c, long d, long e); @@ -66,6 +67,8 @@ void defos_init() NET_WM_STATE_MAXIMIZED_VERT = XATOM("_NET_WM_STATE_MAXIMIZED_VERT"); NET_WM_STATE_MAXIMIZED_HORZ = XATOM("_NET_WM_STATE_MAXIMIZED_HORZ"); NET_FRAME_EXTENTS = XATOM("_NET_FRAME_EXTENTS"); + + resize_locked = false; } void defos_final() @@ -145,9 +148,30 @@ void defos_disable_minimize_button() dmLogInfo("Method 'defos_disable_minimize_button' is not supported in Linux"); } +static void lock_resize(int width, int height) +{ + XSizeHints *sizeHints = XAllocSizeHints(); + sizeHints->flags = PMinSize | PMaxSize; + sizeHints->min_width = width; + sizeHints->min_height = height; + sizeHints->max_width = width; + sizeHints->max_height = height; + + XSetWMNormalHints(disp, win, sizeHints); + XFree(sizeHints); + + resize_locked = true; +} + void defos_disable_window_resize() { - dmLogInfo("Method 'defos_disable_window_resize' is not supported in Linux"); + int x, y; + unsigned int w, h, bw, depth; + + Window dummy; + XGetGeometry(disp, win, &dummy, &x, &y, &w, &h, &bw, &depth); + + lock_resize(w, h); } void defos_set_cursor_visible(bool visible) @@ -247,6 +271,7 @@ void defos_set_window_size(float x, float y, float w, float h) x += extents.left; y += extents.top; + if (resize_locked) { lock_resize(w, h); } XMoveResizeWindow(disp, win, (int)x, (int)y, (unsigned int)w, (unsigned int)h); XFlush(disp); } @@ -265,6 +290,7 @@ void defos_set_view_size(float x, float y, float w, float h) y = screenBounds.y + ((float)screenBounds.h - h) / 2; } + if (resize_locked) { lock_resize(w, h); } XMoveResizeWindow(disp, win, (int)x, (int)y, (unsigned int)w, (unsigned int)h); XFlush(disp); } From acb33688baaf67535a8cdab344263bce1364763d Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 19:18:37 +0300 Subject: [PATCH 32/57] Implement disable_minimize_button and disable_maximize_button on Linux (providing the window manager supports it) --- defos/src/defos_linux.cpp | 58 +++++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index 0082785..fac86d2 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -43,6 +43,10 @@ static Atom NET_WM_STATE; static Atom NET_WM_STATE_FULLSCREEN; static Atom NET_WM_STATE_MAXIMIZED_VERT; static Atom NET_WM_STATE_MAXIMIZED_HORZ; +static Atom NET_WM_ALLOWED_ACTIONS; +static Atom NET_WM_ACTION_MAXIMIZE_HORZ; +static Atom NET_WM_ACTION_MAXIMIZE_VERT; +static Atom NET_WM_ACTION_MINIMIZE; static Atom NET_FRAME_EXTENTS; static Cursor custom_cursor; // image cursor @@ -66,6 +70,10 @@ void defos_init() NET_WM_STATE_FULLSCREEN = XATOM("_NET_WM_STATE_FULLSCREEN"); NET_WM_STATE_MAXIMIZED_VERT = XATOM("_NET_WM_STATE_MAXIMIZED_VERT"); NET_WM_STATE_MAXIMIZED_HORZ = XATOM("_NET_WM_STATE_MAXIMIZED_HORZ"); + NET_WM_ALLOWED_ACTIONS = XATOM("_NET_WM_ALLOWED_ACTIONS"); + NET_WM_ACTION_MINIMIZE = XATOM("_NET_WM_ACTION_MINIMIZE"); + NET_WM_ACTION_MAXIMIZE_HORZ = XATOM("_NET_WM_ACTION_MAXIMIZE_HORZ"); + NET_WM_ACTION_MAXIMIZE_VERT = XATOM("_NET_WM_ACTION_MAXIMIZE_VERT"); NET_FRAME_EXTENTS = XATOM("_NET_FRAME_EXTENTS"); resize_locked = false; @@ -84,14 +92,14 @@ void defos_event_handler_was_set(DefosEvent event) { } -static bool hint_state_contains_atom(Atom atom) +static Atom* get_atom_list(Atom property, unsigned long &nItems) { Atom actualType; int actualFormat; - unsigned long nItems, bytesAfter; + unsigned long bytesAfter; Atom* data = NULL; XEvent event; - while (XGetWindowProperty(disp, win, NET_WM_STATE, + while (XGetWindowProperty(disp, win, property, 0, (~0L), False, AnyPropertyType, &actualType, &actualFormat, &nItems, &bytesAfter, (unsigned char**)&data) == Success && bytesAfter != 0 @@ -99,6 +107,14 @@ static bool hint_state_contains_atom(Atom atom) XNextEvent(disp, &event); } + return data; +} + +static bool hint_state_contains_atom(Atom atom) +{ + unsigned long nItems; + Atom* data = get_atom_list(NET_WM_STATE, nItems); + if (data) { for (unsigned int i = 0; i < nItems; i++) { if (data[i] == atom) { @@ -134,18 +150,48 @@ bool defos_is_mouse_in_view() unsigned int w, h, d6; XGetGeometry(disp, win, &d1, &d3, &d4, &w, &h, &d5, &d6); - if (x >= w || y >= h) { return false; } + if ((unsigned)x >= w || (unsigned)y >= h) { return false; } return true; } void defos_disable_maximize_button() { - dmLogInfo("Method 'defos_disable_maximize_button' is not supported in Linux"); + unsigned long nItems; + Atom* data = get_atom_list(NET_WM_ALLOWED_ACTIONS, nItems); + + if (!data) { return; } + + // Filter the allowed actions list + Atom* newList = (Atom*)malloc(sizeof(Atom) * nItems); + unsigned long newNItems = 0; + for (unsigned long i = 0; i < nItems; i++) { + if (data[i] == NET_WM_ACTION_MAXIMIZE_HORZ || data[i] == NET_WM_ACTION_MAXIMIZE_VERT) { continue; } + newList[newNItems++] = data[i]; + } + XFree(data); + + XChangeProperty(disp, win, NET_WM_ALLOWED_ACTIONS, XA_ATOM, 32, PropModeReplace, (unsigned char*)newList, newNItems); + free(newList); } void defos_disable_minimize_button() { - dmLogInfo("Method 'defos_disable_minimize_button' is not supported in Linux"); + unsigned long nItems; + Atom* data = get_atom_list(NET_WM_ALLOWED_ACTIONS, nItems); + + if (!data) { return; } + + // Filter the allowed actions list + Atom* newList = (Atom*)malloc(sizeof(Atom) * nItems); + unsigned long newNItems = 0; + for (unsigned long i = 0; i < nItems; i++) { + if (data[i] == NET_WM_ACTION_MINIMIZE) { return; } + newList[newNItems++] = data[i]; + } + XFree(data); + + XChangeProperty(disp, win, NET_WM_ALLOWED_ACTIONS, XA_ATOM, 32, PropModeReplace, (unsigned char*)newList, newNItems); + free(newList); } static void lock_resize(int width, int height) From fb238ad1141a8d4d096a95805af09fbf1ea87fe3 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 19:32:20 +0300 Subject: [PATCH 33/57] Implement cursor hiding on Linux --- defos/src/defos_linux.cpp | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index fac86d2..b50a60f 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -51,6 +51,8 @@ static Atom NET_FRAME_EXTENTS; static Cursor custom_cursor; // image cursor static bool has_custom_cursor = false; +static Cursor invisible_cursor; +static bool is_cursor_visible = true; static bool resize_locked = false; static bool is_window_visible(Window window); @@ -77,6 +79,18 @@ void defos_init() NET_FRAME_EXTENTS = XATOM("_NET_FRAME_EXTENTS"); resize_locked = false; + + // Create invisible cursor + Pixmap bitmapNoData; + XColor black; + static char noData[] = { 0,0,0,0,0,0,0,0 }; + black.red = black.green = black.blue = 0; + + bitmapNoData = XCreateBitmapFromData(disp, win, noData, 8, 8); + invisible_cursor = XCreatePixmapCursor(disp, bitmapNoData, bitmapNoData, &black, &black, 0, 0); + XFreePixmap(disp, bitmapNoData); + + is_cursor_visible = true; } void defos_final() @@ -86,6 +100,7 @@ void defos_final() XFreeCursor(disp, custom_cursor); has_custom_cursor = false; } + XFreeCursor(disp, invisible_cursor); } void defos_event_handler_was_set(DefosEvent event) @@ -222,12 +237,19 @@ void defos_disable_window_resize() void defos_set_cursor_visible(bool visible) { - dmLogInfo("Method 'defos_set_cursor_visible' is not supported in Linux"); + if (visible == is_cursor_visible) { return; } + is_cursor_visible = visible; + if (visible) + { + XDefineCursor(disp, win, has_custom_cursor ? custom_cursor : None); + } else { + XDefineCursor(disp, win, invisible_cursor); + } } bool defos_is_cursor_visible() { - return false; + return is_cursor_visible; } void defos_toggle_fullscreen() @@ -413,7 +435,7 @@ void defos_update() void defos_set_custom_cursor_linux(const char *filename) { Cursor cursor = XcursorFilenameLoadCursor(disp, filename); - XDefineCursor(disp, win, cursor); + if (is_cursor_visible) { XDefineCursor(disp, win, cursor); } if (has_custom_cursor) { XFreeCursor(disp, custom_cursor); } custom_cursor = cursor; has_custom_cursor = true; @@ -424,7 +446,7 @@ static unsigned int get_cursor(DefosCursor cursor); void defos_set_cursor(DefosCursor cursor_type) { Cursor cursor = XCreateFontCursor(disp, get_cursor(cursor_type)); - XDefineCursor(disp, win, cursor); + if (is_cursor_visible) { XDefineCursor(disp, win, cursor); } if (has_custom_cursor) { XFreeCursor(disp, custom_cursor); } custom_cursor = cursor; has_custom_cursor = true; @@ -434,7 +456,7 @@ void defos_reset_cursor() { if (has_custom_cursor) { - XUndefineCursor(disp, win); + if (is_cursor_visible) { XUndefineCursor(disp, win); } XFreeCursor(disp, custom_cursor); has_custom_cursor = false; } From f48d069a7ad36353a68e8b4bf700da654d9af2af Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 20:17:49 +0300 Subject: [PATCH 34/57] Add missing Linux features TODO list --- defos/src/defos_linux.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index b50a60f..fcf0bc7 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -10,6 +10,14 @@ 3. https://github.com/yetanothergeek/xctrl/blob/master/src/xctrl.c */ +/* TODO: + 1. ON_MOUSE_ENTER / ON_MOUSE_LEAVE + 2. cursor locking + 3. cursor clipping + 4. getting arguments + 5. setting the window icon +*/ + #include "defos_private.h" #include #include From fc390911c7a903b1f8b01239e83dd7387fb79dfd Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sat, 20 Oct 2018 20:18:08 +0300 Subject: [PATCH 35/57] Add missing XFlush() calls --- defos/src/defos_linux.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index fcf0bc7..c4478f7 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -194,6 +194,7 @@ void defos_disable_maximize_button() XFree(data); XChangeProperty(disp, win, NET_WM_ALLOWED_ACTIONS, XA_ATOM, 32, PropModeReplace, (unsigned char*)newList, newNItems); + XFlush(disp); free(newList); } @@ -214,6 +215,7 @@ void defos_disable_minimize_button() XFree(data); XChangeProperty(disp, win, NET_WM_ALLOWED_ACTIONS, XA_ATOM, 32, PropModeReplace, (unsigned char*)newList, newNItems); + XFlush(disp); free(newList); } @@ -227,6 +229,7 @@ static void lock_resize(int width, int height) sizeHints->max_height = height; XSetWMNormalHints(disp, win, sizeHints); + XFlush(disp); XFree(sizeHints); resize_locked = true; From 22dcad083a39a1ced7851b956e6288525b2bff0a Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sun, 21 Oct 2018 18:17:24 +0300 Subject: [PATCH 36/57] Implement display functions on Windows --- defos/src/defos.cpp | 19 ++++++- defos/src/defos_private.h | 4 ++ defos/src/defos_win.cpp | 104 ++++++++++++++++++++++++++++++++------ 3 files changed, 111 insertions(+), 16 deletions(-) diff --git a/defos/src/defos.cpp b/defos/src/defos.cpp index ef8ec84..cc1baa7 100644 --- a/defos/src/defos.cpp +++ b/defos/src/defos.cpp @@ -346,7 +346,12 @@ static int get_displays(lua_State *L) DisplayInfo &display = displayList[i]; lua_newtable(L); // The display info table + #ifdef DM_PLATFORM_WINDOWS + lua_pushstring(L, display.id); + free(const_cast(display.id)); + #else lua_pushlightuserdata(L, display.id); + #endif lua_pushvalue(L, -1); lua_setfield(L, -3, "id"); @@ -385,8 +390,12 @@ static int get_displays(lua_State *L) static int get_display_modes(lua_State *L) { + #ifdef DM_PLATFORM_WINDOWS + DisplayID displayID = luaL_checkstring(L, 1); + #else luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); DisplayID displayID = lua_touserdata(L, 1); + #endif dmArray modeList; defos_get_display_modes(displayID, modeList); @@ -403,7 +412,15 @@ static int get_display_modes(lua_State *L) static int get_current_display_id(lua_State *L) { - lua_pushlightuserdata(L, defos_get_current_display()); + DisplayID displayID = defos_get_current_display(); + + #ifdef DM_PLATFORM_WINDOWS + lua_pushstring(L, displayID); + free(const_cast(displayID)); + #else + lua_pushlightuserdata(L, displayID); + #endif + return 1; } diff --git a/defos/src/defos_private.h b/defos/src/defos_private.h index e26e44f..1ba46cd 100644 --- a/defos/src/defos_private.h +++ b/defos/src/defos_private.h @@ -29,7 +29,11 @@ typedef enum { DEFOS_CURSOR_IBEAM, } DefosCursor; +#ifdef DM_PLATFORM_WINDOWS +typedef const char* DisplayID; +#else typedef void* DisplayID; +#endif struct DisplayModeInfo { unsigned long width; diff --git a/defos/src/defos_win.cpp b/defos/src/defos_win.cpp index 134c9ba..bc8f265 100644 --- a/defos/src/defos_win.cpp +++ b/defos/src/defos_win.cpp @@ -387,24 +387,98 @@ void defos_reset_cursor() is_custom_cursor_loaded = false; } -void defos_get_displays(dmArray* displist){ - DEVMODE dm = {0}; - dm.dmSize = sizeof(dm); - - for(int i=0;EnumDisplaySettings(NULL, i, &dm)!=0;i++) - { - DisplayInfo display = { - dm.dmPelsWidth, - dm.dmPelsHeight, - dm.dmBitsPerPel, - dm.dmDisplayFrequency - }; - - displist->OffsetCapacity(1); - displist->Push(display); +static char* copy_string(const char *s) +{ + char *buffer = (char*)malloc(strlen(s) + 1); + strcpy(buffer, s); + return buffer; +} + +static void parse_display_mode(const DEVMODE &devMode, DisplayModeInfo &mode) +{ + mode.width = devMode.dmPelsWidth; + mode.height = devMode.dmPelsHeight; + mode.bits_per_pixel = devMode.dmBitsPerPel; + mode.refresh_rate = devMode.dmDisplayFrequency; + mode.scaling_factor = 1.0; +} + +BOOL CALLBACK monitor_enum_callback(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData) +{ + MONITORINFOEX monitorInfo; + monitorInfo.cbSize = sizeof(monitorInfo); + if (!GetMonitorInfo(hMonitor, &monitorInfo)) { return TRUE; } + + DisplayInfo display; + display.id = copy_string(monitorInfo.szDevice); + display.bounds.x = monitorInfo.rcMonitor.left; + display.bounds.y = monitorInfo.rcMonitor.top; + display.bounds.w = monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left; + display.bounds.h = monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top; + + DEVMODE devMode; + devMode.dmSize = sizeof(devMode); + EnumDisplaySettings(monitorInfo.szDevice, ENUM_CURRENT_SETTINGS, &devMode); + parse_display_mode(devMode, display.mode); + display.mode.scaling_factor = (double)devMode.dmPelsWidth / (double)(monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left); + + DISPLAY_DEVICE displayDevice; + displayDevice.cb = sizeof(displayDevice); + EnumDisplayDevices(monitorInfo.szDevice, 0, &displayDevice, 0); + display.name = copy_string(displayDevice.DeviceString); + + dmArray *displayList = reinterpret_cast*>(dwData); + displayList->OffsetCapacity(1); + displayList->Push(display); + + return TRUE; +} + +void defos_get_displays(dmArray &displayList) +{ + EnumDisplayMonitors(NULL, NULL, monitor_enum_callback, reinterpret_cast(&displayList)); +} + +void defos_get_display_modes(DisplayID displayID, dmArray &modeList) +{ + DEVMODE devMode = {}; + devMode.dmSize = sizeof(devMode); + + for (int i = 0; EnumDisplaySettings(displayID, i, &devMode) != 0; i++) + { + DisplayModeInfo mode; + parse_display_mode(devMode, mode); + + bool isDuplicate = false; + for (int j = (int)modeList.Size() - 1; j >= 0; j--) + { + DisplayModeInfo &otherMode = modeList[j]; + if (mode.width == otherMode.width + && mode.height == otherMode.height + && mode.bits_per_pixel == otherMode.bits_per_pixel + && mode.refresh_rate == otherMode.refresh_rate + ) { + isDuplicate = true; + break; + } + } + + if (isDuplicate) { continue; } + modeList.OffsetCapacity(1); + modeList.Push(mode); } } +DisplayID defos_get_current_display() +{ + HWND window = dmGraphics::GetNativeWindowsHWND(); + HMONITOR hMonitor = MonitorFromWindow(window, MONITOR_DEFAULTTONEAREST); + MONITORINFOEX monitorInfo; + monitorInfo.cbSize = sizeof(monitorInfo); + GetMonitorInfo(hMonitor, &monitorInfo); + return copy_string(monitorInfo.szDevice); +} + /******************** * internal functions ********************/ From 70604608e02d4aded2b52a3e8ce64fffd0f0ea54 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sun, 21 Oct 2018 19:26:54 +0300 Subject: [PATCH 37/57] Fix defos.get_window_size() reporting wrongly when window is maximixed Closes #68 --- defos/src/defos_win.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/defos/src/defos_win.cpp b/defos/src/defos_win.cpp index bc8f265..c080c5d 100644 --- a/defos/src/defos_win.cpp +++ b/defos/src/defos_win.cpp @@ -256,14 +256,15 @@ void defos_get_parameters(dmArray ¶meters) { WinRect defos_get_window_size() { HWND window = dmGraphics::GetNativeWindowsHWND(); - WINDOWPLACEMENT frame = {sizeof(placement)}; - GetWindowPlacement(window, &frame); - WinRect rect; - rect.x = (float)frame.rcNormalPosition.left; - rect.y = (float)frame.rcNormalPosition.top; - rect.w = (float)(frame.rcNormalPosition.right - frame.rcNormalPosition.left); - rect.h = (float)(frame.rcNormalPosition.bottom - frame.rcNormalPosition.top); - return rect; + RECT rect; + GetWindowRect(window, &rect); + WinRect result = { + .x = rect.left, + .y = rect.top, + .w = rect.right - rect.left, + .h = rect.bottom - rect.top, + }; + return result; } WinRect defos_get_view_size() @@ -276,13 +277,12 @@ WinRect defos_get_view_size() POINT pos = {wrect.left, wrect.top}; ClientToScreen(window, &pos); - WINDOWPLACEMENT frame = {sizeof(placement)}; - GetWindowPlacement(window, &frame); - WinRect rect; - rect.x = (float)pos.x; - rect.y = (float)pos.y; - rect.w = (float)(wrect.right - wrect.left); - rect.h = (float)(wrect.bottom - wrect.top); + WinRect rect = { + .x = pos.x, + .y = pos.y, + .w = wrect.right - wrect.left, + .h = wrect.bottom - wrect.top, + }; return rect; } From 52026b22675a2eae5405eea3861be53b4120d79e Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sun, 21 Oct 2018 19:49:02 +0300 Subject: [PATCH 38/57] Restore clipping and locking when window is not focused on Windows Closes #80 --- defos/src/defos_win.cpp | 14 +++++++++----- example/example.gui_script | 21 +-------------------- 2 files changed, 10 insertions(+), 25 deletions(-) diff --git a/defos/src/defos_win.cpp b/defos/src/defos_win.cpp index c080c5d..42c4144 100644 --- a/defos/src/defos_win.cpp +++ b/defos/src/defos_win.cpp @@ -23,6 +23,7 @@ static bool is_cursor_clipped = false; static POINT lock_point; static bool is_cursor_locked = false; +static bool is_window_active = true; static bool is_cursor_visible = true; static bool is_custom_cursor_loaded; static HCURSOR custom_cursor; @@ -41,6 +42,7 @@ void subclass_window(); void defos_init() { + is_window_active = true; is_mouse_inside = false; is_cursor_clipped = false; GetClipCursor(&originalRect); // keep the original clip for restore @@ -357,7 +359,7 @@ bool defos_is_cursor_locked() } void defos_update() { - if (is_cursor_locked) { + if (is_cursor_locked && is_window_active) { SetCursorPos(lock_point.x, lock_point.y); } } @@ -570,12 +572,14 @@ static LRESULT __stdcall custom_wndproc(HWND hwnd, UINT umsg, WPARAM wp, LPARAM } break; - case WM_SIZE: - if (is_cursor_locked) + case WM_ACTIVATE: + if (wp != WA_INACTIVE) { - defos_set_cursor_locked(true); + is_window_active = true; + if (is_cursor_clipped) { defos_set_cursor_clipped(true); } + } else { + is_window_active = false; } - break; } if (originalProc != NULL) diff --git a/example/example.gui_script b/example/example.gui_script index 3656864..46bbfb0 100644 --- a/example/example.gui_script +++ b/example/example.gui_script @@ -11,25 +11,6 @@ local ICON_NAMES = { ["Darwin"] = "mac.png" } -function window_callback(self, event, data) - if event == window.WINDOW_EVENT_FOCUS_LOST then - -- though after lost focus cursor clipping will restore, we should restore it - if self.cursor_clipped then - defos.set_cursor_clipped(false) - end - if self.cursor_locked then - defos.set_cursor_locked(false) - end - elseif event == window.WINDOW_EVENT_FOCUS_GAINED then - if self.cursor_clipped then - defos.set_cursor_clipped(true) - end - if self.cursor_locked then - defos.set_cursor_locked(true) - end - end -end - function toggle_cursor_lock(self) self.cursor_locked = not self.cursor_locked defos.set_cursor_locked(self.cursor_locked) @@ -148,7 +129,7 @@ function init(self) ) end - window.set_listener(window_callback) + print("App command line arguments:") pprint(defos.get_parameters()) end From ea93213949f4845b34d6d6d210620301d0306b12 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sun, 21 Oct 2018 19:53:31 +0300 Subject: [PATCH 39/57] Remove mouse dx/dy being printed out when cursor locked Let's not give library users ideas that don't work... --- example/example.gui_script | 4 ---- 1 file changed, 4 deletions(-) diff --git a/example/example.gui_script b/example/example.gui_script index 46bbfb0..e87bb32 100644 --- a/example/example.gui_script +++ b/example/example.gui_script @@ -235,8 +235,4 @@ function on_input(self, action_id, action) defos.set_cursor(self.cursors[self.current_cursor]) end) - - if self.cursor_locked and not action_id then - print("FPS mouse dx, dy: ", action.dx, action.dy) - end end From 82b7d20a532de01b031373df247e03e96095dda0 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sun, 21 Oct 2018 20:26:27 +0300 Subject: [PATCH 40/57] Implement minimize function Closes #86 --- README.md | 8 ++++++++ defos/src/defos.cpp | 7 +++++++ defos/src/defos_html5.cpp | 4 ++++ defos/src/defos_linux.cpp | 5 +++++ defos/src/defos_mac.mm | 4 ++++ defos/src/defos_private.h | 1 + defos/src/defos_win.cpp | 6 ++++++ 7 files changed, 35 insertions(+) diff --git a/README.md b/README.md index 040d82e..274531d 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,14 @@ bool_value = defos.is_fullscreen() --- +**Minimize window**. + +```lua +defos.minimize() +``` + +--- + **Get/set the window's size and position** in screen coordinates. The window area includes the title bar, so the actual contained game view area might be smaller than the given metrics. diff --git a/defos/src/defos.cpp b/defos/src/defos.cpp index cc1baa7..aad5f7f 100644 --- a/defos/src/defos.cpp +++ b/defos/src/defos.cpp @@ -144,6 +144,12 @@ static int is_maximized(lua_State *L) return 1; } +static int minimize(lua_State *L) +{ + defos_minimize(); + return 0; +} + static int set_window_icon(lua_State *L) { const char *icon_path = luaL_checkstring(L, 1); @@ -528,6 +534,7 @@ static const luaL_reg Module_methods[] = {"toggle_maximized", toggle_maximized}, {"set_maximized", set_maximized}, {"is_maximized", is_maximized}, + {"minimize", minimize}, {"set_console_visible", set_console_visible}, {"is_console_visible", is_console_visible}, {"set_cursor_visible", set_cursor_visible}, diff --git a/defos/src/defos_html5.cpp b/defos/src/defos_html5.cpp index 638c6b3..018ceff 100644 --- a/defos/src/defos_html5.cpp +++ b/defos/src/defos_html5.cpp @@ -111,6 +111,10 @@ void defos_disable_window_resize() { dmLogInfo("Method 'disable_window_resize' is not supported in html5"); } +void defos_minimize() { + dmLogInfo("Method 'minimize' is not supported in html5"); +} + void defos_toggle_fullscreen() { EM_ASM(Module.toggleFullscreen();); } diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index c4478f7..79f1866 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -289,6 +289,11 @@ void defos_toggle_maximized() XFlush(disp); } +void defos_minimize() +{ + XIconifyWindow(disp, win, screen); +} + void defos_set_console_visible(bool visible) { dmLogInfo("Method 'defos_set_console_visible' is not supported in Linux"); diff --git a/defos/src/defos_mac.mm b/defos/src/defos_mac.mm index 07e229a..80fdf80 100644 --- a/defos/src/defos_mac.mm +++ b/defos/src/defos_mac.mm @@ -115,6 +115,10 @@ bool defos_is_maximized() { return is_maximized; } +void defos_minimize() { + [window performMiniaturize: nil]; +} + void defos_set_window_title(const char* title_lua) { NSString* title = [NSString stringWithUTF8String:title_lua]; [window setTitle:title]; diff --git a/defos/src/defos_private.h b/defos/src/defos_private.h index 1ba46cd..af8c0d6 100644 --- a/defos/src/defos_private.h +++ b/defos/src/defos_private.h @@ -69,6 +69,7 @@ extern void defos_toggle_fullscreen(); extern void defos_toggle_maximized(); extern bool defos_is_fullscreen(); extern bool defos_is_maximized(); +extern void defos_minimize(); extern void defos_set_window_title(const char* title_lua); extern void defos_set_window_icon(const char *icon_path); diff --git a/defos/src/defos_win.cpp b/defos/src/defos_win.cpp index 42c4144..e9b83b1 100644 --- a/defos/src/defos_win.cpp +++ b/defos/src/defos_win.cpp @@ -155,6 +155,12 @@ void defos_toggle_maximized() } } +void defos_minimize() +{ + HWND window = dmGraphics::GetNativeWindowsHWND(); + ShowWindow(window, SW_MINIMIZE); +} + void defos_set_console_visible(bool visible) { ::ShowWindow(::GetConsoleWindow(), visible ? SW_SHOW : SW_HIDE); From 511fb7b2d8a580088b7fd7cb30c7bf2f3e7f660e Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sun, 21 Oct 2018 21:00:55 +0300 Subject: [PATCH 41/57] Implement keeping window always on top Closes #83 --- README.md | 10 ++++++++++ defos/src/defos.cpp | 23 +++++++++++++++++++++++ defos/src/defos_html5.cpp | 8 ++++++++ defos/src/defos_linux.cpp | 20 ++++++++++++++++++++ defos/src/defos_mac.mm | 8 ++++++++ defos/src/defos_private.h | 2 ++ defos/src/defos_win.cpp | 16 ++++++++++++++++ 7 files changed, 87 insertions(+) diff --git a/README.md b/README.md index 274531d..1d63f06 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,16 @@ bool_value = defos.is_fullscreen() --- +**Keep window on top**. + +```lua +defos.set_always_on_top(bool_value) +defos.toggle_always_on_top() +bool_value = defos.is_always_on_top() +``` + +--- + **Minimize window**. ```lua diff --git a/defos/src/defos.cpp b/defos/src/defos.cpp index aad5f7f..725a4e6 100644 --- a/defos/src/defos.cpp +++ b/defos/src/defos.cpp @@ -144,6 +144,26 @@ static int is_maximized(lua_State *L) return 1; } +static int toggle_always_on_top(lua_State *L) +{ + defos_toggle_always_on_top(); + return 0; +} + +static int set_always_on_top(lua_State *L) +{ + if (checkboolean(L, 1) != defos_is_always_on_top()) { + defos_toggle_always_on_top(); + } + return 0; +} + +static int is_always_on_top(lua_State *L) +{ + lua_pushboolean(L, defos_is_always_on_top()); + return 1; +} + static int minimize(lua_State *L) { defos_minimize(); @@ -530,6 +550,9 @@ static const luaL_reg Module_methods[] = {"toggle_fullscreen", toggle_fullscreen}, {"set_fullscreen", set_fullscreen}, {"is_fullscreen", is_fullscreen}, + {"toggle_always_on_top", toggle_always_on_top}, + {"set_always_on_top", set_always_on_top}, + {"is_always_on_top", is_always_on_top}, {"toggle_maximize", toggle_maximized}, // For backwards compatibility {"toggle_maximized", toggle_maximized}, {"set_maximized", set_maximized}, diff --git a/defos/src/defos_html5.cpp b/defos/src/defos_html5.cpp index 018ceff..8c81559 100644 --- a/defos/src/defos_html5.cpp +++ b/defos/src/defos_html5.cpp @@ -144,6 +144,14 @@ bool defos_is_maximized() { return is_maximized; } +void defos_toggle_always_on_top() { + dmLogInfo("Method 'toggle_always_on_top' is not supported in html5"); +} + +bool defos_is_always_on_top() { + return false; +} + void defos_set_window_title(const char* title_lua) { EM_ASM_({document.title = UTF8ToString($0)}, title_lua); } diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index 79f1866..ce2db90 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -51,6 +51,7 @@ static Atom NET_WM_STATE; static Atom NET_WM_STATE_FULLSCREEN; static Atom NET_WM_STATE_MAXIMIZED_VERT; static Atom NET_WM_STATE_MAXIMIZED_HORZ; +static Atom NET_WM_STATE_ABOVE; static Atom NET_WM_ALLOWED_ACTIONS; static Atom NET_WM_ACTION_MAXIMIZE_HORZ; static Atom NET_WM_ACTION_MAXIMIZE_VERT; @@ -80,6 +81,7 @@ void defos_init() NET_WM_STATE_FULLSCREEN = XATOM("_NET_WM_STATE_FULLSCREEN"); NET_WM_STATE_MAXIMIZED_VERT = XATOM("_NET_WM_STATE_MAXIMIZED_VERT"); NET_WM_STATE_MAXIMIZED_HORZ = XATOM("_NET_WM_STATE_MAXIMIZED_HORZ"); + NET_WM_STATE_ABOVE = XATOM("_NET_WM_STATE_ABOVE"); NET_WM_ALLOWED_ACTIONS = XATOM("_NET_WM_ALLOWED_ACTIONS"); NET_WM_ACTION_MINIMIZE = XATOM("_NET_WM_ACTION_MINIMIZE"); NET_WM_ACTION_MAXIMIZE_HORZ = XATOM("_NET_WM_ACTION_MAXIMIZE_HORZ"); @@ -161,6 +163,11 @@ bool defos_is_maximized() return hint_state_contains_atom(NET_WM_STATE_MAXIMIZED_VERT); } +bool defos_is_always_on_top() +{ + return hint_state_contains_atom(NET_WM_STATE_ABOVE); +} + bool defos_is_mouse_in_view() { Window d1, d2; @@ -289,6 +296,19 @@ void defos_toggle_maximized() XFlush(disp); } +void defos_toggle_always_on_top() +{ + send_message(win, + NET_WM_STATE, + _NET_WM_STATE_TOGGLE, + NET_WM_STATE_ABOVE, + 0, + 1, + 0 + ); + XFlush(disp); +} + void defos_minimize() { XIconifyWindow(disp, win, screen); diff --git a/defos/src/defos_mac.mm b/defos/src/defos_mac.mm index 80fdf80..2f67a3a 100644 --- a/defos/src/defos_mac.mm +++ b/defos/src/defos_mac.mm @@ -106,6 +106,10 @@ void defos_toggle_maximized() { } } +void defos_toggle_always_on_top() { + window.level = defos_is_always_on_top() ? NSNormalWindowLevel : NSFloatingWindowLevel; +} + bool defos_is_fullscreen() { BOOL fullscreen = (([window styleMask] & NSFullScreenWindowMask) == NSFullScreenWindowMask); return fullscreen == YES; @@ -115,6 +119,10 @@ bool defos_is_maximized() { return is_maximized; } +bool defos_is_always_on_top() { + return window.level == NSFloatingWindowLevel; +} + void defos_minimize() { [window performMiniaturize: nil]; } diff --git a/defos/src/defos_private.h b/defos/src/defos_private.h index af8c0d6..4cec73d 100644 --- a/defos/src/defos_private.h +++ b/defos/src/defos_private.h @@ -67,8 +67,10 @@ extern void defos_disable_window_resize(); extern void defos_toggle_fullscreen(); extern void defos_toggle_maximized(); +extern void defos_toggle_always_on_top(); extern bool defos_is_fullscreen(); extern bool defos_is_maximized(); +extern bool defos_is_always_on_top(); extern void defos_minimize(); extern void defos_set_window_title(const char* title_lua); diff --git a/defos/src/defos_win.cpp b/defos/src/defos_win.cpp index e9b83b1..8f3b26b 100644 --- a/defos/src/defos_win.cpp +++ b/defos/src/defos_win.cpp @@ -23,6 +23,7 @@ static bool is_cursor_clipped = false; static POINT lock_point; static bool is_cursor_locked = false; +static bool is_window_on_top = false; static bool is_window_active = true; static bool is_cursor_visible = true; static bool is_custom_cursor_loaded; @@ -43,6 +44,7 @@ void subclass_window(); void defos_init() { is_window_active = true; + is_window_on_top = false; is_mouse_inside = false; is_cursor_clipped = false; GetClipCursor(&originalRect); // keep the original clip for restore @@ -155,6 +157,20 @@ void defos_toggle_maximized() } } +void defos_toggle_always_on_top() +{ + is_window_on_top = !is_window_on_top; + HWND window = dmGraphics::GetNativeWindowsHWND(); + SetWindowPos(window, + is_window_on_top ? HWND_TOPMOST : HWND_NOTOPMOST, + 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE + ); +} + +bool defos_is_always_on_top() { + return is_window_on_top; +} + void defos_minimize() { HWND window = dmGraphics::GetNativeWindowsHWND(); From 3a227f5f05fe1dd23bfa45c887f89c859475e7c7 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sun, 21 Oct 2018 21:04:54 +0300 Subject: [PATCH 42/57] Rename move_cursor_to to set_cursor_pos_view --- README.md | 2 +- defos/src/defos.cpp | 7 ++++--- defos/src/defos_html5.cpp | 4 ++-- defos/src/defos_linux.cpp | 2 +- defos/src/defos_mac.mm | 4 ++-- defos/src/defos_private.h | 2 +- defos/src/defos_win.cpp | 2 +- example/example.gui_script | 2 +- 8 files changed, 13 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 1d63f06..aa46369 100644 --- a/README.md +++ b/README.md @@ -174,7 +174,7 @@ end) ```lua defos.set_cursor_pos(x, y) -- In screen coordinates -defos.move_cursor_to(x, y) -- In game view coordinates +defos.set_cursor_pos_view(x, y) -- In game view coordinates ``` --- diff --git a/defos/src/defos.cpp b/defos/src/defos.cpp index 725a4e6..a0d4bcd 100644 --- a/defos/src/defos.cpp +++ b/defos/src/defos.cpp @@ -241,11 +241,11 @@ static int set_cursor_pos(lua_State *L) defos_set_cursor_pos(x, y); return 0; } -static int move_cursor_to(lua_State *L) +static int set_cursor_pos_view(lua_State *L) { float x = luaL_checknumber(L, 1); float y = luaL_checknumber(L, 2); - defos_move_cursor_to(x, y); + defos_set_cursor_pos_view(x, y); return 0; } @@ -567,7 +567,8 @@ static const luaL_reg Module_methods[] = {"on_click", on_click}, {"is_mouse_in_view", is_mouse_in_view}, {"set_cursor_pos", set_cursor_pos}, - {"move_cursor_to", move_cursor_to}, + {"set_cursor_pos_view", set_cursor_pos_view}, + {"move_cursor_to", set_cursor_pos_view}, // For backwards compatibility {"set_cursor_clipped", set_cursor_clipped}, {"is_cursor_clipped", is_cursor_clipped}, {"set_cursor_locked", set_cursor_locked}, diff --git a/defos/src/defos_html5.cpp b/defos/src/defos_html5.cpp index 8c81559..d8f43e6 100644 --- a/defos/src/defos_html5.cpp +++ b/defos/src/defos_html5.cpp @@ -252,8 +252,8 @@ void defos_set_cursor_pos(float x, float y) { dmLogInfo("Method 'defos_set_cursor_pos' is not supported in html5"); } -void defos_move_cursor_to(float x, float y) { - dmLogInfo("Method 'defos_move_cursor_to' is not supported in html5"); +void defos_set_cursor_pos_view(float x, float y) { + dmLogInfo("Method 'defos_set_cursor_pos_view' is not supported in html5"); } void defos_set_cursor_clipped(bool clipped) { diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index ce2db90..a527e76 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -438,7 +438,7 @@ void defos_set_cursor_pos(float x, float y) XFlush(disp); } -void defos_move_cursor_to(float x, float y) +void defos_set_cursor_pos_view(float x, float y) { XWarpPointer(disp, None, win, 0, 0, 0, 0, (int)x, (int)y); XFlush(disp); diff --git a/defos/src/defos_mac.mm b/defos/src/defos_mac.mm index 2f67a3a..d192edc 100644 --- a/defos/src/defos_mac.mm +++ b/defos/src/defos_mac.mm @@ -260,7 +260,7 @@ void defos_set_cursor_pos(float x, float y) { } } -void defos_move_cursor_to(float x, float y) { +void defos_set_cursor_pos_view(float x, float y) { NSView* view = dmGraphics::GetNativeOSXNSView(); NSPoint pointInWindow = [view convertPoint: NSMakePoint(x, view.bounds.size.height - y) toView: nil]; NSPoint windowOrigin = window.frame.origin; @@ -302,7 +302,7 @@ static void clip_cursor(NSEvent * event) { } if (willClip) { - defos_move_cursor_to(mousePos.x, bounds.size.height - mousePos.y); + defos_set_cursor_pos_view(mousePos.x, bounds.size.height - mousePos.y); } } diff --git a/defos/src/defos_private.h b/defos/src/defos_private.h index 4cec73d..6f9bf95 100644 --- a/defos/src/defos_private.h +++ b/defos/src/defos_private.h @@ -91,7 +91,7 @@ extern bool defos_is_cursor_visible(); extern bool defos_is_mouse_in_view(); extern void defos_set_cursor_pos(float x, float y); -extern void defos_move_cursor_to(float x, float y); +extern void defos_set_cursor_pos_view(float x, float y); extern void defos_set_cursor_clipped(bool clipped); extern bool defos_is_cursor_clipped(); diff --git a/defos/src/defos_win.cpp b/defos/src/defos_win.cpp index 8f3b26b..502eba7 100644 --- a/defos/src/defos_win.cpp +++ b/defos/src/defos_win.cpp @@ -317,7 +317,7 @@ void defos_set_cursor_pos(float x, float y) // move cursor to pos relative to current window // top-left is (0, 0) -void defos_move_cursor_to(float x, float y) +void defos_set_cursor_pos_view(float x, float y) { HWND window = dmGraphics::GetNativeWindowsHWND(); diff --git a/example/example.gui_script b/example/example.gui_script index e87bb32..cfe9853 100644 --- a/example/example.gui_script +++ b/example/example.gui_script @@ -207,7 +207,7 @@ function on_input(self, action_id, action) dirtylarry:button("random_cursor_pos", action_id, action, function() local x = math.random(1,2000) local y = math.random(1,2000) - defos.move_cursor_to(x, y) + defos.set_cursor_pos_view(x, y) end) dirtylarry:button("clip_cursor", action_id, action, function() From 64a6579402860457460d59c0a9701c2f97fe4f44 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sun, 21 Oct 2018 22:08:59 +0300 Subject: [PATCH 43/57] Implement getters for the cursor position Closes #82 --- README.md | 10 +++++- defos/src/defos.cpp | 20 ++++++++++++ defos/src/defos_html5.cpp | 20 ++++++++++++ defos/src/defos_linux.cpp | 26 ++++++++++++++++ defos/src/defos_mac.mm | 17 +++++++++++ defos/src/defos_private.h | 8 ++++- defos/src/defos_win.cpp | 21 +++++++++++++ example/example.gui | 62 ++++++++++++++++++++++++++++++++++++++ example/example.gui_script | 3 ++ 9 files changed, 185 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index aa46369..3df6380 100644 --- a/README.md +++ b/README.md @@ -170,13 +170,21 @@ end) --- +**Get the cursor position**. + +```lua +x, y = defos.get_cursor_pos() -- In screen coordinates +x, y = defos.get_cursor_pos_view() -- In game view coordinates +``` + +--- + **Move the cursor** programatically. ```lua defos.set_cursor_pos(x, y) -- In screen coordinates defos.set_cursor_pos_view(x, y) -- In game view coordinates ``` - --- **Clip cursor** to current game view area. diff --git a/defos/src/defos.cpp b/defos/src/defos.cpp index a0d4bcd..1c5dde8 100644 --- a/defos/src/defos.cpp +++ b/defos/src/defos.cpp @@ -234,6 +234,24 @@ static int is_cursor_visible(lua_State *L) return 1; } +static int get_cursor_pos(lua_State *L) +{ + WinPoint point; + point = defos_get_cursor_pos(); + lua_pushnumber(L, point.x); + lua_pushnumber(L, point.y); + return 2; +} + +static int get_cursor_pos_view(lua_State *L) +{ + WinPoint point; + point = defos_get_cursor_pos_view(); + lua_pushnumber(L, point.x); + lua_pushnumber(L, point.y); + return 2; +} + static int set_cursor_pos(lua_State *L) { float x = luaL_checknumber(L, 1); @@ -566,6 +584,8 @@ static const luaL_reg Module_methods[] = {"on_mouse_leave", on_mouse_leave}, {"on_click", on_click}, {"is_mouse_in_view", is_mouse_in_view}, + {"get_cursor_pos", get_cursor_pos}, + {"get_cursor_pos_view", get_cursor_pos_view}, {"set_cursor_pos", set_cursor_pos}, {"set_cursor_pos_view", set_cursor_pos_view}, {"move_cursor_to", set_cursor_pos_view}, // For backwards compatibility diff --git a/defos/src/defos_html5.cpp b/defos/src/defos_html5.cpp index d8f43e6..f6c437a 100644 --- a/defos/src/defos_html5.cpp +++ b/defos/src/defos_html5.cpp @@ -49,9 +49,17 @@ void defos_init() { Module.__defosjs_click_listener = function () { _defos_emit_event_from_js($2); }; + Module.__defosjs_mousemove_listener = function (evt) { + var rect = Module.canvas.getBoundingClientRect(); + Module.__defosjs_mouse_x = evt.clientX - rect.left; + Module.__defosjs_mouse_y = evt.clientY - rect.top; + }; + Module.__defosjs_mouse_x = -1; + Module.__defosjs_mouse_y = -1; Module.canvas.addEventListener('mouseenter', Module.__defosjs_mouseenter_listener); Module.canvas.addEventListener('mouseleave', Module.__defosjs_mouseleave_listener); Module.canvas.addEventListener('click', Module.__defosjs_click_listener); + document.addEventListener('mousemove', Module.__defosjs_mousemove_listener); }, DEFOS_EVENT_MOUSE_ENTER, DEFOS_EVENT_MOUSE_LEAVE, DEFOS_EVENT_CLICK); EM_ASM_({ @@ -86,6 +94,7 @@ void defos_final() { Module.canvas.removeEventListener('mouseenter', Module.__defosjs_mouseenter_listener); Module.canvas.removeEventListener('mouseleave', Module.__defosjs_mouseleave_listener); Module.canvas.removeEventListener('click', Module.__defosjs_click_listener); + document.removeEventListener('mousemove', Module.__defosjs_mousemove_listener); document.removeEventListener('pointerlockchange', Module.__defosjs_pointerlockchange_listener); document.removeEventListener('mozpointerlockchange', Module.__defosjs_pointerlockchange_listener); document.removeEventListener('webkitpointerlockchange', Module.__defosjs_pointerlockchange_listener); @@ -248,6 +257,17 @@ bool defos_is_mouse_in_view() { return is_mouse_inside; } +WinPoint defos_get_cursor_pos() { + return defos_get_cursor_pos_view(); +} + +WinPoint defos_get_cursor_pos_view() { + WinPoint point; + point.x = (float)EM_ASM_DOUBLE({ return Module.__defosjs_mouse_x }, 0.0); + point.y = (float)EM_ASM_DOUBLE({ return Module.__defosjs_mouse_y }, 0.0); + return point; +} + void defos_set_cursor_pos(float x, float y) { dmLogInfo("Method 'defos_set_cursor_pos' is not supported in html5"); } diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index a527e76..f7a0ea5 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -432,6 +432,32 @@ WinRect defos_get_view_size() return r; } +WinPoint defos_get_cursor_pos() +{ + WinPoint point = { .x = -INFINITY, .y = -INFINITY }; + Window d1, d2; + int x, y, d3, d4; + unsigned int d5; + if (XQueryPointer(disp, root, &d1, &d2, &d3, &d4, &x, &y, &d5)) { + point.x = x; + point.y = y; + } + return point; +} + +WinPoint defos_get_cursor_pos_view() +{ + WinPoint point = { .x = -INFINITY, .y = -INFINITY }; + Window d1, d2; + int x, y, d3, d4; + unsigned int d5; + if (XQueryPointer(disp, win, &d1, &d2, &d3, &d4, &x, &y, &d5)) { + point.x = x; + point.y = y; + } + return point; +} + void defos_set_cursor_pos(float x, float y) { XWarpPointer(disp, None, root, 0, 0, 0, 0, (int)x, (int)y); diff --git a/defos/src/defos_mac.mm b/defos/src/defos_mac.mm index d192edc..f2b018a 100644 --- a/defos/src/defos_mac.mm +++ b/defos/src/defos_mac.mm @@ -253,6 +253,23 @@ bool defos_is_mouse_in_view() { return is_mouse_in_view; } +WinPoint defos_get_cursor_pos() { + NSPoint point = NSEvent.mouseLocation; + WinPoint result; + result.x = (float)point.x; + result.y = (float)NSMaxY(NSScreen.screens[0].frame) - point.y; + return result; +} + +WinPoint defos_get_cursor_pos_view() { + NSView* view = dmGraphics::GetNativeOSXNSView(); + NSPoint point = [view convertPoint: NSEvent.mouseLocation fromView: nil]; + WinPoint result; + result.x = (float)point.x; + result.y = (float)NSMaxY(NSScreen.screens[0].frame) - point.y; + return result; +} + void defos_set_cursor_pos(float x, float y) { CGWarpMouseCursorPosition(CGPointMake(x, y)); if (!is_cursor_locked) { diff --git a/defos/src/defos_private.h b/defos/src/defos_private.h index 6f9bf95..f149e56 100644 --- a/defos/src/defos_private.h +++ b/defos/src/defos_private.h @@ -4,7 +4,11 @@ #include struct WinRect { - float x,y,w,h; + float x, y, w, h; +}; + +struct WinPoint { + float x, y; }; struct LuaCallbackInfo { @@ -92,6 +96,8 @@ extern bool defos_is_cursor_visible(); extern bool defos_is_mouse_in_view(); extern void defos_set_cursor_pos(float x, float y); extern void defos_set_cursor_pos_view(float x, float y); +extern WinPoint defos_get_cursor_pos(); +extern WinPoint defos_get_cursor_pos_view(); extern void defos_set_cursor_clipped(bool clipped); extern bool defos_is_cursor_clipped(); diff --git a/defos/src/defos_win.cpp b/defos/src/defos_win.cpp index 502eba7..dfd9a95 100644 --- a/defos/src/defos_win.cpp +++ b/defos/src/defos_win.cpp @@ -310,6 +310,27 @@ WinRect defos_get_view_size() return rect; } +WinPoint defos_get_cursor_pos() +{ + POINT point; + GetCursorPos(&point); + + WinPoint result = { .x = point.x, .y = point.y }; + return result; +} + +WinPoint defos_get_cursor_pos_view() +{ + POINT point; + GetCursorPos(&point); + + HWND window = dmGraphics::GetNativeWindowsHWND(); + ScreenToClient(window, &point); + + WinPoint result = { .x = point.x, .y = point.y }; + return result; +} + void defos_set_cursor_pos(float x, float y) { SetCursorPos((int)x, (int)y); diff --git a/example/example.gui b/example/example.gui index c66e065..b2578f3 100644 --- a/example/example.gui +++ b/example/example.gui @@ -2892,6 +2892,68 @@ nodes { text_leading: 1.0 text_tracking: 0.0 } +nodes { + position { + x: 367.0 + y: 270.066 + z: 0.0 + w: 1.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + scale { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + size { + x: 700.0 + y: 100.0 + z: 0.0 + w: 1.0 + } + color { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + type: TYPE_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "cursor position" + font: "larryfont" + id: "cursor_pos" + xanchor: XANCHOR_NONE + yanchor: YANCHOR_NONE + pivot: PIVOT_NW + outline { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } + shadow { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } + adjust_mode: ADJUST_MODE_FIT + line_break: false + layer: "" + inherit_alpha: true + alpha: 1.0 + outline_alpha: 1.0 + shadow_alpha: 1.0 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 +} material: "/builtins/materials/gui.material" adjust_reference: ADJUST_REFERENCE_LEGACY max_nodes: 512 diff --git a/example/example.gui_script b/example/example.gui_script index cfe9853..fd158d8 100644 --- a/example/example.gui_script +++ b/example/example.gui_script @@ -143,6 +143,9 @@ function update(self, dt) gui.set_text(gui.get_node("window_pos"),"window position "..x.." "..y.." "..w.." "..h) x,y,w,h = defos.get_view_size() gui.set_text(gui.get_node("view_pos"),"view position "..x.." "..y.." "..w.." "..h) + x, y = defos.get_cursor_pos() + w, h = defos.get_cursor_pos_view() + gui.set_text(gui.get_node("cursor_pos"),"cursor: "..x.." "..y.." view: "..w.." "..h) gui.set_text(gui.get_node("is_fullscreen"),"is_fullscreen "..tostring(defos.is_fullscreen())) gui.set_text(gui.get_node("is_maximized"),"is_maximized "..tostring(defos.is_maximized())) gui.set_text(gui.get_node("is_mouse_in_view"),"is_mouse_in_view "..tostring(defos.is_mouse_in_view())) From d9cee6eb3d044ea0632e0b4fbde4167073d9accf Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sun, 21 Oct 2018 22:13:55 +0300 Subject: [PATCH 44/57] Round off cursor position display On macOS, cursor position is returned with sub-pixel precision --- example/example.gui_script | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/example.gui_script b/example/example.gui_script index fd158d8..0aab76e 100644 --- a/example/example.gui_script +++ b/example/example.gui_script @@ -145,7 +145,7 @@ function update(self, dt) gui.set_text(gui.get_node("view_pos"),"view position "..x.." "..y.." "..w.." "..h) x, y = defos.get_cursor_pos() w, h = defos.get_cursor_pos_view() - gui.set_text(gui.get_node("cursor_pos"),"cursor: "..x.." "..y.." view: "..w.." "..h) + gui.set_text(gui.get_node("cursor_pos"),"cursor: "..math.floor(x).." "..math.floor(y).." view: "..math.floor(w).." "..math.floor(h)) gui.set_text(gui.get_node("is_fullscreen"),"is_fullscreen "..tostring(defos.is_fullscreen())) gui.set_text(gui.get_node("is_maximized"),"is_maximized "..tostring(defos.is_maximized())) gui.set_text(gui.get_node("is_mouse_in_view"),"is_mouse_in_view "..tostring(defos.is_mouse_in_view())) From c9ce6a1d65b052e3163636b1f50c4119109c97f0 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sun, 21 Oct 2018 22:21:52 +0300 Subject: [PATCH 45/57] Fix view cursor coordinates on macOS --- defos/src/defos_mac.mm | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/defos/src/defos_mac.mm b/defos/src/defos_mac.mm index f2b018a..2471079 100644 --- a/defos/src/defos_mac.mm +++ b/defos/src/defos_mac.mm @@ -263,10 +263,16 @@ WinPoint defos_get_cursor_pos() { WinPoint defos_get_cursor_pos_view() { NSView* view = dmGraphics::GetNativeOSXNSView(); - NSPoint point = [view convertPoint: NSEvent.mouseLocation fromView: nil]; + NSPoint pointInScreen = NSEvent.mouseLocation; + NSPoint windowOrigin = window.frame.origin; + NSPoint pointInWindow = NSMakePoint( + pointInScreen.x - windowOrigin.x, + pointInScreen.y - windowOrigin.y + ); + NSPoint point = [view convertPoint: pointInWindow fromView: nil]; WinPoint result; result.x = (float)point.x; - result.y = (float)NSMaxY(NSScreen.screens[0].frame) - point.y; + result.y = (float)(view.bounds.size.height - point.y); return result; } From d758259a7a4531f2f881f6078e87b9f44f43076a Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sun, 21 Oct 2018 22:35:00 +0300 Subject: [PATCH 46/57] Fix always on top not toggling back on Linux --- defos/src/defos_linux.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index f7a0ea5..fce4a37 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -300,7 +300,7 @@ void defos_toggle_always_on_top() { send_message(win, NET_WM_STATE, - _NET_WM_STATE_TOGGLE, + defos_is_always_on_top() ? _NET_WM_STATE_REMOVE : _NET_WM_STATE_ADD, NET_WM_STATE_ABOVE, 0, 1, From 1764b29d6be2873dfdcfcef65374a5c37a006a68 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sun, 21 Oct 2018 22:50:46 +0300 Subject: [PATCH 47/57] Implement get_parameters() on Linux --- defos/src/defos_linux.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index fce4a37..851721f 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -779,8 +779,25 @@ char* defos_get_bundle_root() return result; } +static int shared_argc = 0; +static char** shared_argv = NULL; +static void arguments_main_hook(int argc, char* argv[], char* envp[]) +{ + shared_argc = argc; + shared_argv = argv; +} + +__attribute__((section(".init_array"), used)) +void (* defos_arguments_main_hook)(int,char*[],char*[]) = &arguments_main_hook; + + void defos_get_parameters(dmArray ¶meters) { + parameters.OffsetCapacity(shared_argc); + for (int i = 0; i < shared_argc; i++) + { + parameters.Push(copy_string(shared_argv[i])); + } } //from glfw/x11_window.c From d7a70e0327e9ffc634cd0a813fbd967367e44932 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Sun, 21 Oct 2018 23:15:37 +0300 Subject: [PATCH 48/57] Rename get_parameters to get_arguments --- README.md | 2 +- defos/src/defos.cpp | 17 +++++++++-------- defos/src/defos_html5.cpp | 6 +++--- defos/src/defos_linux.cpp | 6 +++--- defos/src/defos_mac.mm | 6 +++--- defos/src/defos_private.h | 2 +- defos/src/defos_win.cpp | 6 +++--- example/example.gui_script | 2 +- 8 files changed, 24 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 3df6380..bb18084 100644 --- a/README.md +++ b/README.md @@ -291,7 +291,7 @@ defos.set_window_icon(path_to_icon) **Returns a table of command line arguments** used to run the app. On HTML5, returns a table with a single string: the query string part of the URL (eg. `{ "?param1=foo¶m2=bar" }`). ```lua -arguments = defos.get_parameters() +arguments = defos.get_arguments() ``` --- diff --git a/defos/src/defos.cpp b/defos/src/defos.cpp index 1c5dde8..33cff5d 100644 --- a/defos/src/defos.cpp +++ b/defos/src/defos.cpp @@ -185,17 +185,17 @@ static int get_bundle_root(lua_State *L) return 1; } -static int get_parameters(lua_State *L) +static int get_arguments(lua_State *L) { - dmArray parameters; - defos_get_parameters(parameters); + dmArray arguments; + defos_get_arguments(arguments); lua_newtable(L); - for (unsigned int i = 0; i < parameters.Size(); i++) + for (unsigned int i = 0; i < arguments.Size(); i++) { - char* param = parameters[i]; - lua_pushstring(L, param); + char* arg = arguments[i]; + lua_pushstring(L, arg); lua_rawseti(L, 1, i+1); - free(param); + free(arg); } return 1; } @@ -603,7 +603,8 @@ static const luaL_reg Module_methods[] = {"get_current_display_id", get_current_display_id}, {"set_window_icon", set_window_icon}, {"get_bundle_root", get_bundle_root}, - {"get_parameters", get_parameters}, + {"get_arguments", get_arguments}, + {"get_parameters", get_arguments}, // For backwards compatibility {0, 0}}; static void LuaInit(lua_State *L) diff --git a/defos/src/defos_html5.cpp b/defos/src/defos_html5.cpp index f6c437a..a9da404 100644 --- a/defos/src/defos_html5.cpp +++ b/defos/src/defos_html5.cpp @@ -191,7 +191,7 @@ char* defos_get_bundle_root() { return bundlePath; } -void defos_get_parameters(dmArray ¶meters) { +void defos_get_arguments(dmArray &arguments) { char *param = (char*)EM_ASM_INT({ var jsString = window.location.search; var lengthBytes = lengthBytesUTF8(jsString) + 1; @@ -199,8 +199,8 @@ void defos_get_parameters(dmArray ¶meters) { stringToUTF8(jsString, stringOnWasmHeap, lengthBytes+1); return stringOnWasmHeap; },0); - parameters.OffsetCapacity(1); - parameters.Push(param); + arguments.OffsetCapacity(1); + arguments.Push(param); } void defos_set_window_size(float x, float y, float w, float h) { diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index 851721f..6250896 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -791,12 +791,12 @@ __attribute__((section(".init_array"), used)) void (* defos_arguments_main_hook)(int,char*[],char*[]) = &arguments_main_hook; -void defos_get_parameters(dmArray ¶meters) +void defos_get_arguments(dmArray &arguments) { - parameters.OffsetCapacity(shared_argc); + arguments.OffsetCapacity(shared_argc); for (int i = 0; i < shared_argc; i++) { - parameters.Push(copy_string(shared_argv[i])); + arguments.Push(copy_string(shared_argv[i])); } } diff --git a/defos/src/defos_mac.mm b/defos/src/defos_mac.mm index 2471079..e9f57e8 100644 --- a/defos/src/defos_mac.mm +++ b/defos/src/defos_mac.mm @@ -149,15 +149,15 @@ void defos_set_window_icon(const char *icon_path){ return bundlePath_lua; } -void defos_get_parameters(dmArray ¶meters) { +void defos_get_arguments(dmArray &arguments) { NSArray *args = [[NSProcessInfo processInfo] arguments]; int argCount = [args count]; - parameters.OffsetCapacity(argCount); + arguments.OffsetCapacity(argCount); for (int i = 0; i < argCount; i++){ const char *param = [args[i] UTF8String]; char* lua_param = (char*)malloc(strlen(param) + 1); strcpy(lua_param, param); - parameters.Push(lua_param); + arguments.Push(lua_param); } } diff --git a/defos/src/defos_private.h b/defos/src/defos_private.h index f149e56..5ff0fa4 100644 --- a/defos/src/defos_private.h +++ b/defos/src/defos_private.h @@ -80,7 +80,7 @@ extern void defos_minimize(); extern void defos_set_window_title(const char* title_lua); extern void defos_set_window_icon(const char *icon_path); extern char* defos_get_bundle_root(); -extern void defos_get_parameters(dmArray ¶meters); +extern void defos_get_arguments(dmArray &arguments); extern void defos_set_window_size(float x, float y, float w, float h); extern WinRect defos_get_window_size(); diff --git a/defos/src/defos_win.cpp b/defos/src/defos_win.cpp index dfd9a95..48fe291 100644 --- a/defos/src/defos_win.cpp +++ b/defos/src/defos_win.cpp @@ -259,19 +259,19 @@ char* defos_get_bundle_root() { return bundlePath; } -void defos_get_parameters(dmArray ¶meters) { +void defos_get_arguments(dmArray &arguments) { LPWSTR *szArglist; int nArgs; int i; szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs); if( NULL != szArglist ){ - parameters.OffsetCapacity(nArgs); + arguments.OffsetCapacity(nArgs); for( i=0; i Date: Mon, 22 Oct 2018 11:14:11 +0300 Subject: [PATCH 49/57] Report correct scaling factor in get_display_modes() on Windows --- defos/src/defos_win.cpp | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/defos/src/defos_win.cpp b/defos/src/defos_win.cpp index 48fe291..1800811 100644 --- a/defos/src/defos_win.cpp +++ b/defos/src/defos_win.cpp @@ -448,7 +448,7 @@ static void parse_display_mode(const DEVMODE &devMode, DisplayModeInfo &mode) mode.scaling_factor = 1.0; } -BOOL CALLBACK monitor_enum_callback(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData) +static BOOL CALLBACK monitor_enum_callback(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData) { MONITORINFOEX monitorInfo; monitorInfo.cbSize = sizeof(monitorInfo); @@ -484,15 +484,51 @@ void defos_get_displays(dmArray &displayList) EnumDisplayMonitors(NULL, NULL, monitor_enum_callback, reinterpret_cast(&displayList)); } +struct MonitorScaleData { + const char *display_device_name; + double scaling_factor; +}; + +static BOOL CALLBACK monitor_scale_enum_callback(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData) +{ + MonitorScaleData *data = reinterpret_cast(dwData); + + MONITORINFOEX monitorInfo; + monitorInfo.cbSize = sizeof(monitorInfo); + if (!GetMonitorInfo(hMonitor, &monitorInfo)) { return TRUE; } + + if (strcmp(monitorInfo.szDevice, data->display_device_name) != 0) { return TRUE; } + + DEVMODE devMode; + devMode.dmSize = sizeof(devMode); + EnumDisplaySettings(monitorInfo.szDevice, ENUM_CURRENT_SETTINGS, &devMode); + data->scaling_factor = (double)devMode.dmPelsWidth / (double)(monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left); + + return FALSE; +} + +static double scale_of_monitor(DisplayID displayID) +{ + MonitorScaleData data = { + .display_device_name = displayID, + .scaling_factor = 1.0, + }; + EnumDisplayMonitors(NULL, NULL, monitor_scale_enum_callback, reinterpret_cast(&data)); + return data.scaling_factor; +} + void defos_get_display_modes(DisplayID displayID, dmArray &modeList) { DEVMODE devMode = {}; devMode.dmSize = sizeof(devMode); + double scaling_factor = scale_of_monitor(displayID); + for (int i = 0; EnumDisplaySettings(displayID, i, &devMode) != 0; i++) { DisplayModeInfo mode; parse_display_mode(devMode, mode); + mode.scaling_factor = scaling_factor; bool isDuplicate = false; for (int j = (int)modeList.Size() - 1; j >= 0; j--) From e2f24312d2e72afd51a8a3aaef062bbbed7a67c3 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Mon, 22 Oct 2018 13:16:51 +0300 Subject: [PATCH 50/57] Ensure consistent handling and reporting of orientations across platforms --- README.md | 6 ++++++ defos/src/defos.cpp | 6 ++++++ defos/src/defos_linux.cpp | 39 +++++++++++++++++++++++++++++--------- defos/src/defos_mac.mm | 12 +++++++++--- defos/src/defos_private.h | 3 +++ defos/src/defos_win.cpp | 21 ++++++++++++++++++-- example/example.gui_script | 2 +- 7 files changed, 74 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index bb18084..a250b39 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,9 @@ A display info table has the following format: scaling_factor = 2, refresh_rate = 60, bits_per_pixel = 32, + orientation = 0, + reflect_x = false, + reflect_y = false, }, name = "Built-in Retina Display", } @@ -142,6 +145,9 @@ A resolution mode has the following format: scaling_factor = 2, -- Hi-DPI scaling factor refresh_rate = 60, bits_per_pixel = 32, + orientation = 0, -- One of 0, 90, 180, 270 + reflect_x = false, -- Linux supports flipping the screen around one of the axes + reflect_y = false, } ``` diff --git a/defos/src/defos.cpp b/defos/src/defos.cpp index 33cff5d..9b7bb1c 100644 --- a/defos/src/defos.cpp +++ b/defos/src/defos.cpp @@ -377,6 +377,12 @@ static void push_display_mode(lua_State *L, const DisplayModeInfo &mode) lua_setfield(L, -2, "scaling_factor"); lua_pushnumber(L, mode.bits_per_pixel); lua_setfield(L, -2, "bits_per_pixel"); + lua_pushnumber(L, mode.orientation); + lua_setfield(L, -2, "orientation"); + lua_pushboolean(L, mode.reflect_x); + lua_setfield(L, -2, "reflect_x"); + lua_pushboolean(L, mode.reflect_y); + lua_setfield(L, -2, "reflect_y"); } static int get_displays(lua_State *L) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index 6250896..a8ffa16 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -573,6 +573,33 @@ static bool axis_flipped(Rotation rotation) return !!(rotation & (RR_Rotate_90 | RR_Rotate_270)); } +static unsigned long orientation_from_rotation(Rotation rotation) +{ + if (rotation & RR_Rotate_0) { return 0; } + if (rotation & RR_Rotate_90) { return 90; } + if (rotation & RR_Rotate_180) { return 180; } + if (rotation & RR_Rotate_270) { return 270; } + return 0; +} + +static void parse_display_mode(const XRRModeInfo* modeInfo, DisplayModeInfo &mode, Rotation rotation) +{ + if (axis_flipped(rotation)) + { + mode.width = modeInfo->height; + mode.height = modeInfo->width; + } else { + mode.width = modeInfo->width; + mode.height = modeInfo->height; + } + mode.refresh_rate = compute_refresh_rate(modeInfo); + mode.bits_per_pixel = 32; + mode.scaling_factor = 1.0; + mode.orientation = orientation_from_rotation(rotation); + mode.reflect_x = !!(rotation & RR_Reflect_X); + mode.reflect_y = !!(rotation & RR_Reflect_Y); +} + void defos_get_displays(dmArray &displayList) { XRRScreenResources *screenResources = XRRGetScreenResourcesCurrent(disp, win); @@ -618,13 +645,9 @@ void defos_get_displays(dmArray &displayList) display.bounds.y = crtcInfo->y; display.bounds.w = crtcInfo->width; display.bounds.h = crtcInfo->height; - display.mode.width = modeInfo->width; - display.mode.height = modeInfo->height; - display.mode.refresh_rate = compute_refresh_rate(modeInfo); + parse_display_mode(modeInfo, display.mode, crtcInfo->rotation); display.mode.bits_per_pixel = bpp; - display.mode.scaling_factor = (double)display.mode.width / (double)( - axis_flipped(crtcInfo->rotation) ? crtcInfo->height : crtcInfo->width - ); + display.mode.scaling_factor = (double)display.mode.width / (double)crtcInfo->width; display.name = NULL; if (crtcInfo->noutput > 0) @@ -676,9 +699,7 @@ void defos_get_display_modes(DisplayID displayID, dmArray &mode const XRRModeInfo *modeInfo = get_mode_info(screenResources, outputInfo->modes[i]); DisplayModeInfo mode; - mode.width = modeInfo->width; - mode.height = modeInfo->height; - mode.refresh_rate = compute_refresh_rate(modeInfo); + parse_display_mode(modeInfo, mode, crtcInfo->rotation); mode.bits_per_pixel = bpp; mode.scaling_factor = scaling_factor; diff --git a/defos/src/defos_mac.mm b/defos/src/defos_mac.mm index e9f57e8..b8c28f5 100644 --- a/defos/src/defos_mac.mm +++ b/defos/src/defos_mac.mm @@ -389,7 +389,7 @@ void defos_reset_cursor() { current_cursor = default_cursor; } -static DisplayModeInfo parse_mode(CGDisplayModeRef mode, CVDisplayLinkRef displayLink) { +static DisplayModeInfo parse_mode(CGDisplayModeRef mode, CVDisplayLinkRef displayLink, double rotation) { DisplayModeInfo mode_info; mode_info.width = CGDisplayModeGetPixelWidth(mode); mode_info.height = CGDisplayModeGetPixelHeight(mode); @@ -399,6 +399,9 @@ static DisplayModeInfo parse_mode(CGDisplayModeRef mode, CVDisplayLinkRef displa CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(mode); mode_info.bits_per_pixel = getBPPFromModeString(pixelEncoding); CFRelease(pixelEncoding); + mode_info.orientation = (unsigned long)rotation; + mode_info.reflect_x = false; + mode_info.reflect_y = false; if (mode_info.refresh_rate == 0) { const CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(displayLink); @@ -514,7 +517,8 @@ void defos_get_displays(dmArray &displayList){ CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displayID); CVDisplayLinkRef displayLink; CVDisplayLinkCreateWithCGDisplay(displayID, &displayLink); - display.mode = parse_mode(mode, displayLink); + double rotation = CGDisplayRotation(displayID); + display.mode = parse_mode(mode, displayLink, rotation); CVDisplayLinkRelease(displayLink); CGDisplayModeRelease(mode); @@ -545,10 +549,12 @@ void defos_get_display_modes(DisplayID displayID_, dmArray &mod CVDisplayLinkRef displayLink; CVDisplayLinkCreateWithCGDisplay(displayID, &displayLink); + double rotation = CGDisplayRotation(displayID); + modeList.OffsetCapacity(modeCount); for (int i = 0; i < modeCount; i++) { CGDisplayModeRef mode = allModes[i]; - DisplayModeInfo modeInfo = parse_mode(mode, displayLink); + DisplayModeInfo modeInfo = parse_mode(mode, displayLink, rotation); // Remove duplicates size_t width = CGDisplayModeGetWidth(mode); diff --git a/defos/src/defos_private.h b/defos/src/defos_private.h index 5ff0fa4..e2544a4 100644 --- a/defos/src/defos_private.h +++ b/defos/src/defos_private.h @@ -45,6 +45,9 @@ struct DisplayModeInfo { unsigned long bits_per_pixel; double refresh_rate; double scaling_factor; + unsigned long orientation; + bool reflect_x; + bool reflect_y; }; struct DisplayInfo { diff --git a/defos/src/defos_win.cpp b/defos/src/defos_win.cpp index 1800811..4fb5e47 100644 --- a/defos/src/defos_win.cpp +++ b/defos/src/defos_win.cpp @@ -439,6 +439,18 @@ static char* copy_string(const char *s) return buffer; } +static unsigned long translate_orientation(DWORD orientation) +{ + switch (orientation) + { + case DMDO_DEFAULT: return 0; + case DMDO_90: return 90; + case DMDO_180: return 180; + case DMDO_270: return 270; + default: return 0; + } +} + static void parse_display_mode(const DEVMODE &devMode, DisplayModeInfo &mode) { mode.width = devMode.dmPelsWidth; @@ -446,6 +458,11 @@ static void parse_display_mode(const DEVMODE &devMode, DisplayModeInfo &mode) mode.bits_per_pixel = devMode.dmBitsPerPel; mode.refresh_rate = devMode.dmDisplayFrequency; mode.scaling_factor = 1.0; + mode.orientation = (devMode.dmFields & DM_DISPLAYORIENTATION) + ? translate_orientation(devMode.dmDisplayOrientation) + : 0; + mode.reflect_x = false; + mode.reflect_y = false; } static BOOL CALLBACK monitor_enum_callback(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData) @@ -463,7 +480,7 @@ static BOOL CALLBACK monitor_enum_callback(HMONITOR hMonitor, HDC, LPRECT, LPARA DEVMODE devMode; devMode.dmSize = sizeof(devMode); - EnumDisplaySettings(monitorInfo.szDevice, ENUM_CURRENT_SETTINGS, &devMode); + EnumDisplaySettingsEx(monitorInfo.szDevice, ENUM_CURRENT_SETTINGS, &devMode, 0); parse_display_mode(devMode, display.mode); display.mode.scaling_factor = (double)devMode.dmPelsWidth / (double)(monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left); @@ -524,7 +541,7 @@ void defos_get_display_modes(DisplayID displayID, dmArray &mode double scaling_factor = scale_of_monitor(displayID); - for (int i = 0; EnumDisplaySettings(displayID, i, &devMode) != 0; i++) + for (int i = 0; EnumDisplaySettingsEx(displayID, i, &devMode, 0) != 0; i++) { DisplayModeInfo mode; parse_display_mode(devMode, mode); diff --git a/example/example.gui_script b/example/example.gui_script index 747019a..4c0614b 100644 --- a/example/example.gui_script +++ b/example/example.gui_script @@ -125,7 +125,7 @@ function init(self) print( mode.width .. "x" .. mode.height .. " " .. mode.bits_per_pixel .. "bit @" .. mode.refresh_rate .. "Hz x" .. - mode.scaling_factor + mode.scaling_factor .. " " .. mode.orientation .. "deg" ) end From a6f5b09665d4643c0311f74f388cb864d4c456ca Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Mon, 22 Oct 2018 13:31:07 +0300 Subject: [PATCH 51/57] Clarify what reflect_x and reflect_y do --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a250b39..1dcf447 100644 --- a/README.md +++ b/README.md @@ -146,8 +146,8 @@ A resolution mode has the following format: refresh_rate = 60, bits_per_pixel = 32, orientation = 0, -- One of 0, 90, 180, 270 - reflect_x = false, -- Linux supports flipping the screen around one of the axes - reflect_y = false, + reflect_x = false, -- Linux supports reflecting either of the axes, + reflect_y = false, -- effectively flipping the image like a mirror } ``` From 5c75ac63e53a5f69b296de87793115c3bffacf08 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Mon, 22 Oct 2018 10:36:15 +0300 Subject: [PATCH 52/57] Allow only one of x, y to be nil when setting size on Linux --- defos/src/defos_linux.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index a8ffa16..83ae163 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -365,8 +365,8 @@ void defos_set_window_size(float x, float y, float w, float h) { WinRect screenBounds; get_current_crtc(screenBounds); - x = screenBounds.x + ((float)screenBounds.w - w) / 2; - y = screenBounds.y + ((float)screenBounds.h - h) / 2; + if (isnan(x) { x = screenBounds.x + ((float)screenBounds.w - w) / 2; } + if (isnan(y) { y = screenBounds.y + ((float)screenBounds.h - h) / 2; } } WindowExtents extents = get_window_extents(); @@ -390,8 +390,8 @@ void defos_set_view_size(float x, float y, float w, float h) { WinRect screenBounds; get_current_crtc(screenBounds); - x = screenBounds.x + ((float)screenBounds.w - w) / 2; - y = screenBounds.y + ((float)screenBounds.h - h) / 2; + if (isnan(x)) { x = screenBounds.x + ((float)screenBounds.w - w) / 2; } + if (isnan(y)) { y = screenBounds.y + ((float)screenBounds.h - h) / 2; } } if (resize_locked) { lock_resize(w, h); } From 7378ec75e4b097ed68d2dc6c22339d3b8adc057c Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Mon, 22 Oct 2018 10:44:00 +0300 Subject: [PATCH 53/57] Make x, y = nil, nil center in the middle of the current screen on Winows --- defos/src/defos_win.cpp | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/defos/src/defos_win.cpp b/defos/src/defos_win.cpp index 4fb5e47..6f46134 100644 --- a/defos/src/defos_win.cpp +++ b/defos/src/defos_win.cpp @@ -189,28 +189,33 @@ bool defos_is_console_visible() void defos_set_window_size(float x, float y, float w, float h) { - if (isnan(x)) - { - x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2; - } - if (isnan(y)) + HWND window = dmGraphics::GetNativeWindowsHWND(); + + if (isnan(x) || isnan(y)) { - y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2; + HMONITOR hMonitor = MonitorFromWindow(window, MONITOR_DEFAULTTONEAREST); + MONITORINFO monitorInfo; + monitorInfo.cbSize = sizeof(monitorInfo); + GetMonitorInfo(hMonitor, &monitorInfo); + if (isnan(x)) { x = (monitorInfo.rcMonitor.left + monitorInfo.rcMonitor.right - w) / 2; } + if (isnan(y)) { y = (monitorInfo.rcMonitor.top + monitorInfo.rcMonitor.bottom - h) / 2; } } - HWND window = dmGraphics::GetNativeWindowsHWND(); SetWindowPos(window, window, (int)x, (int)y, (int)w, (int)h, SWP_NOZORDER); } void defos_set_view_size(float x, float y, float w, float h) { - if (isnan(x)) - { - x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2; - } - if (isnan(y)) + HWND window = dmGraphics::GetNativeWindowsHWND(); + + if (isnan(x) || isnan(y)) { - y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2; + HMONITOR hMonitor = MonitorFromWindow(window, MONITOR_DEFAULTTONEAREST); + MONITORINFO monitorInfo; + monitorInfo.cbSize = sizeof(monitorInfo); + GetMonitorInfo(hMonitor, &monitorInfo); + if (isnan(x)) { x = (monitorInfo.rcMonitor.left + monitorInfo.rcMonitor.right - w) / 2; } + if (isnan(y)) { y = (monitorInfo.rcMonitor.top + monitorInfo.rcMonitor.bottom - h) / 2; } } RECT rect = {0, 0, (int)w, (int)h}; @@ -220,8 +225,6 @@ void defos_set_view_size(float x, float y, float w, float h) // TODO: we are assuming the window have no menu, maybe it is better to expose it as parameter later AdjustWindowRect(&rect, style, false); - HWND window = dmGraphics::GetNativeWindowsHWND(); - SetWindowPos(window, window, (int)x, (int)y, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER); } From 9c7e13d09d6a321c99fc8d94f587ba63c593b2c7 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Mon, 22 Oct 2018 10:46:23 +0300 Subject: [PATCH 54/57] Fix Linux build --- defos/src/defos_linux.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index 83ae163..9474d3d 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -365,8 +365,8 @@ void defos_set_window_size(float x, float y, float w, float h) { WinRect screenBounds; get_current_crtc(screenBounds); - if (isnan(x) { x = screenBounds.x + ((float)screenBounds.w - w) / 2; } - if (isnan(y) { y = screenBounds.y + ((float)screenBounds.h - h) / 2; } + if (isnan(x)) { x = screenBounds.x + ((float)screenBounds.w - w) / 2; } + if (isnan(y)) { y = screenBounds.y + ((float)screenBounds.h - h) / 2; } } WindowExtents extents = get_window_extents(); From 0667c010d3ad2ea96ce7e3100121d4a7691f33cb Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Mon, 22 Oct 2018 16:13:06 +0300 Subject: [PATCH 55/57] Update Linux TODO list --- defos/src/defos_linux.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index 9474d3d..23f8745 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -11,11 +11,10 @@ */ /* TODO: - 1. ON_MOUSE_ENTER / ON_MOUSE_LEAVE - 2. cursor locking - 3. cursor clipping - 4. getting arguments - 5. setting the window icon + ON_MOUSE_ENTER / ON_MOUSE_LEAVE + cursor locking + cursor clipping + setting the window icon */ #include "defos_private.h" From d2e2554de2539601b2c2d3b847dcde591822dee6 Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Mon, 22 Oct 2018 16:44:39 +0300 Subject: [PATCH 56/57] Tidy up README and add compatibility status for each function --- README.md | 66 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 1dcf447..ee1ae2f 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,14 @@ # DefOS + Extra native OS functions for games written using the Defold game engine -Currently uses Native Extension for macOS, Windows and HTML5. Contribute! +Currently supports macOS, Windows, Linux and HTML5. Contribute! ## Installation -You can use DefOS in your own project by adding this project as a [Defold library dependency](http://www.defold.com/manuals/libraries/). Open your game.project file and in the dependencies field under project add: + +You can use DefOS in your own project by adding this project as a +[Defold library dependency](http://www.defold.com/manuals/libraries/). +Open your `game.project` file and in the dependencies field under project add: https://github.com/subsoap/defos/archive/master.zip @@ -13,9 +17,9 @@ https://github.com/subsoap/defos/archive/master.zip **Customize title bar** accessories and title. ```lua -defos.disable_maximize_button() -defos.disable_minimize_button() -defos.disable_window_resize() +defos.disable_maximize_button() -- Not supported on HTML5 +defos.disable_minimize_button() -- Not supported on HTML5 +defos.disable_window_resize() -- Not supported on HTML5 defos.set_window_title("I set this title using Defos") ``` @@ -41,7 +45,7 @@ bool_value = defos.is_fullscreen() --- -**Keep window on top**. +**Keep window on top**. Not supported on HTML5. ```lua defos.set_always_on_top(bool_value) @@ -51,7 +55,7 @@ bool_value = defos.is_always_on_top() --- -**Minimize window**. +**Minimize window**. Not supported on HTML5. ```lua defos.minimize() @@ -94,6 +98,8 @@ defos.set_view_size(x, y, w, h) `defos.get_displays()` returns a table which can be indexed with either number indices (like an array), either with display `id`s. +Not supported on HTML5. + ```lua displays = defos.get_displays() pprint(displays[1]) -- Print info about the main display @@ -127,10 +133,12 @@ A display info table has the following format: --- -**Query display modes** for a display. +**Query resolution modes** for a display. Returns a table with all the resolution modes a display supports. +Not supported on HTML5. + ```lua display_id = defos.get_current_display_id() modes = defos.get_display_modes(display_id) @@ -145,7 +153,7 @@ A resolution mode has the following format: scaling_factor = 2, -- Hi-DPI scaling factor refresh_rate = 60, bits_per_pixel = 32, - orientation = 0, -- One of 0, 90, 180, 270 + orientation = 0, -- One of 0, 90, 180, 270 (degrees measured clockwise) reflect_x = false, -- Linux supports reflecting either of the axes, reflect_y = false, -- effectively flipping the image like a mirror } @@ -164,6 +172,8 @@ bool_value = defos.is_cursor_visible() **Respond to the mouse entering and leaving** the game view area. +`on_mouse_enter()` / `on_mouse_leave()` not supported on Linux yet. + ```lua bool_value = defos.is_mouse_in_view() defos.on_mouse_enter(function () @@ -187,6 +197,8 @@ x, y = defos.get_cursor_pos_view() -- In game view coordinates **Move the cursor** programatically. +Not supported on HTML5. + ```lua defos.set_cursor_pos(x, y) -- In screen coordinates defos.set_cursor_pos_view(x, y) -- In game view coordinates @@ -195,6 +207,8 @@ defos.set_cursor_pos_view(x, y) -- In game view coordinates **Clip cursor** to current game view area. +Not supported on Linux and HTML5. + ```lua defos.set_cursor_clipped(bool_value) bool_value = defos.is_cursor_clipped() @@ -202,7 +216,10 @@ bool_value = defos.is_cursor_clipped() --- -**Lock cursor movement**. On HTML5 this only works from `defos.on_click()`. +**Lock cursor movement**. + +On HTML5 this only works from `defos.on_click()`. +Not supported on Linux yet. ```lua defos.set_cursor_locked(bool_value) @@ -231,11 +248,14 @@ end) } ``` -On macOS, custom cursors can be any image file supported by `NSImage`, but it's highly recommended to -[create a TIFF](https://developer.apple.com/library/content/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Optimizing/Optimizing.html#//apple_ref/doc/uid/TP40012302-CH7-SW27) -with two images, one at 72DPI (for low density displays) and another at 144DPI (for Retina displays). +On macOS, custom cursors can be any image file supported by `NSImage`, but it's +highly recommended to [create a TIFF][cursor-tiff] with two images, one at +72DPI (for low density displays) and another at 144DPI (for Retina displays). + +The hotspot is an anchor point within the image that will overlap with the +functional position of the mouse pointer (eg. the tip of the arrow). -The hotspot is an anchor point within the image that will overlap with the functional position of the mouse pointer (eg. the tip of the arrow). +[cursor-tiff]: https://developer.apple.com/library/content/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Optimizing/Optimizing.html#//apple_ref/doc/uid/TP40012302-CH7-SW27 ```lua defos.set_cursor(cursor) @@ -270,7 +290,9 @@ end) --- -**Get the absolute path to the game's containing directory.** On macOS this will be the path to the .app bundle +**Get the absolute path to the game's containing directory**. On macOS this +will be the path to the .app bundle. On HTML5 this will be the page URL up until +the last `/`. ```lua path = defos.get_bundle_root() @@ -286,15 +308,19 @@ defos.PATH_SEP --- -**Change the game's icon** at runtime. +**Change the game window's icon** at runtime. On Windows, this function accepts +`.ico` files. On macOS this accepts any image file supported by `NSImage`. +On Linux this function is not supported yet. ```lua -defos.set_window_icon(path_to_icon) +defos.set_window_icon(path_to_icon_file) ``` --- -**Returns a table of command line arguments** used to run the app. On HTML5, returns a table with a single string: the query string part of the URL (eg. `{ "?param1=foo¶m2=bar" }`). +**Returns a table of command line arguments** used to run the app. On HTML5, +returns a table with a single string: the query string part of the URL +(eg. `{ "?param1=foo¶m2=bar" }`). ```lua arguments = defos.get_arguments() @@ -302,8 +328,10 @@ arguments = defos.get_arguments() --- -If you'd like to see any other feature, open an issue. +If you'd like to see any other features, open an issue. ## Example + An example is made using [DirtyLarry](https://github.com/andsve/dirtylarry) + ![Defos example screenshot](https://user-images.githubusercontent.com/2209596/37050119-158e6b34-2184-11e8-95fd-b2e293fba456.jpg) From b2a78363398c3a584a0b7c0d5fc18f3b60a2fe8c Mon Sep 17 00:00:00 2001 From: Marius Petcu Date: Mon, 22 Oct 2018 16:59:51 +0300 Subject: [PATCH 57/57] Log warnings instead of info for method unimplemented warnings --- defos/src/defos.cpp | 2 +- defos/src/defos_html5.cpp | 18 +++++++++--------- defos/src/defos_linux.cpp | 8 ++++---- defos/src/defos_mac.mm | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/defos/src/defos.cpp b/defos/src/defos.cpp index 9b7bb1c..74c80dc 100644 --- a/defos/src/defos.cpp +++ b/defos/src/defos.cpp @@ -521,7 +521,7 @@ static int on_mouse_enter(lua_State *L) static int on_click(lua_State *L) { #ifndef DM_PLATFORM_HTML5 - dmLogInfo("Event 'on_click' exists only on HTML5"); + dmLogWarning("Event 'on_click' exists only in HTML5"); #endif set_event_handler(L, 1, DEFOS_EVENT_CLICK); return 0; diff --git a/defos/src/defos_html5.cpp b/defos/src/defos_html5.cpp index a9da404..77b88bf 100644 --- a/defos/src/defos_html5.cpp +++ b/defos/src/defos_html5.cpp @@ -109,19 +109,19 @@ void defos_event_handler_was_set(DefosEvent event) { } void defos_disable_maximize_button() { - dmLogInfo("Method 'disable_maximize_button' is not supported in html5"); + dmLogWarning("Method 'disable_maximize_button' is not supported in HTML5"); } void defos_disable_minimize_button() { - dmLogInfo("Method 'disable_minimize_button' is not supported in html5"); + dmLogWarning("Method 'disable_minimize_button' is not supported in HTML5"); } void defos_disable_window_resize() { - dmLogInfo("Method 'disable_window_resize' is not supported in html5"); + dmLogWarning("Method 'disable_window_resize' is not supported in HTML5"); } void defos_minimize() { - dmLogInfo("Method 'minimize' is not supported in html5"); + dmLogWarning("Method 'minimize' is not supported in HTML5"); } void defos_toggle_fullscreen() { @@ -154,7 +154,7 @@ bool defos_is_maximized() { } void defos_toggle_always_on_top() { - dmLogInfo("Method 'toggle_always_on_top' is not supported in html5"); + dmLogWarning("Method 'toggle_always_on_top' is not supported in HTML5"); } bool defos_is_always_on_top() { @@ -236,7 +236,7 @@ bool defos_is_console_visible() { } void defos_set_console_visible(bool visible) { - dmLogInfo("Method 'defos_set_console_visible' is not supported in html5, it is meant for Windows builds only"); + dmLogWarning("Method 'set_console_visible' is only supported on Windows"); } void defos_set_cursor_visible(bool visible) { @@ -269,15 +269,15 @@ WinPoint defos_get_cursor_pos_view() { } void defos_set_cursor_pos(float x, float y) { - dmLogInfo("Method 'defos_set_cursor_pos' is not supported in html5"); + dmLogWarning("Method 'defos_set_cursor_pos' is not supported in HTML5"); } void defos_set_cursor_pos_view(float x, float y) { - dmLogInfo("Method 'defos_set_cursor_pos_view' is not supported in html5"); + dmLogWarning("Method 'defos_set_cursor_pos_view' is not supported in HTML5"); } void defos_set_cursor_clipped(bool clipped) { - dmLogInfo("Method 'defos_set_cursor_clipped' is not supported in html5"); + dmLogWarning("Method 'defos_set_cursor_clipped' is not supported in HTML5"); } bool defos_is_cursor_clipped() { diff --git a/defos/src/defos_linux.cpp b/defos/src/defos_linux.cpp index 23f8745..e414ce1 100644 --- a/defos/src/defos_linux.cpp +++ b/defos/src/defos_linux.cpp @@ -315,7 +315,7 @@ void defos_minimize() void defos_set_console_visible(bool visible) { - dmLogInfo("Method 'defos_set_console_visible' is not supported in Linux"); + dmLogWarning("Method 'set_console_visible' is only supported on Windows"); } bool defos_is_console_visible() @@ -471,7 +471,7 @@ void defos_set_cursor_pos_view(float x, float y) void defos_set_cursor_clipped(bool clipped) { - dmLogInfo("Method 'defos_set_cursor_clipped' is not supported in Linux"); + dmLogWarning("Method 'set_cursor_clipped' is not supported on Linux"); } bool defos_is_cursor_clipped() @@ -481,7 +481,7 @@ bool defos_is_cursor_clipped() void defos_set_cursor_locked(bool locked) { - dmLogInfo("Method 'defos_set_cursor_locked' is not supported in Linux"); + dmLogWarning("Method 'set_cursor_locked' is not supported on Linux"); } bool defos_is_cursor_locked() @@ -768,7 +768,7 @@ DisplayID defos_get_current_display() void defos_set_window_icon(const char *icon_path) { - dmLogInfo("Method 'defos_set_window_icon' is not supported on Linux"); + dmLogWarning("Method 'set_window_icon' is not supported on Linux"); } static char* copy_string(const char * s) diff --git a/defos/src/defos_mac.mm b/defos/src/defos_mac.mm index b8c28f5..c6b5c61 100644 --- a/defos/src/defos_mac.mm +++ b/defos/src/defos_mac.mm @@ -228,7 +228,7 @@ WinRect defos_get_view_size() { } void defos_set_console_visible(bool visible) { - dmLogInfo("Method 'defos_set_console_visible' is not supported in macOS"); + dmLogWarning("Method 'set_console_visible' is only supported on Windows"); } bool defos_is_console_visible() {