Compare commits

...

391 Commits

Author SHA1 Message Date
Kovid Goyal
20f7118432 version 0.14.4 2019-08-31 10:20:47 +05:30
Kovid Goyal
37e6c3f0cb Merge branch 'bool_indentation' of https://github.com/Luflosi/kitty 2019-08-30 19:08:46 +05:30
Luflosi
0459dda5c2 Fix bool indentation
The wrong indentation was caused by the removal of GLFWbool in fe62700825.
2019-08-30 15:32:20 +02:00
Kovid Goyal
a10c816c05 Merge branch 'fix_nslog_string_format' of https://github.com/Luflosi/kitty 2019-08-30 18:40:49 +05:30
Luflosi
c0c7cfacc2 Fix NSLog() printing of unicode format strings
See https://stackoverflow.com/questions/720052/nslog-incorrect-encoding.
The `%s` format placeholder for `NSLog()` expects an encoding other than UTF-8, which leads to garbled Unicode characters when trying to print a UTF-8 encoded string.
```Objective-C
NSLog(@"Ä %s %@", "Ä", @("Ä"));
```
prints `Ä √Ñ Ä`.

As can be seen in the example above, the workaround is to convert the UTF-8 encoded C-string to an `NSString` object and print that instead.
`debug_key()` calls `NSLog()`.
2019-08-30 15:03:51 +02:00
Kovid Goyal
8cdb6647ed Merge branch 'fix_update_encoding' of https://github.com/Luflosi/kitty 2019-08-30 16:20:42 +05:30
Luflosi
b68e3c85b9 Add missing MENU key to key_encoding.py 2019-08-30 12:37:23 +02:00
Luflosi
ef25d5bbd5 Fix update_encoding() not adding the last key 2019-08-30 12:36:37 +02:00
Kovid Goyal
278bf6e897 Fix #1937 2019-08-30 15:02:17 +05:30
Kovid Goyal
90a985b73a Make format_text() more secure 2019-08-28 05:41:20 +05:30
Kovid Goyal
b016353809 Some clarifications for the graphics protocol
See discussion on #33
2019-08-28 05:28:05 +05:30
Kovid Goyal
bc222af2e2 When dumping scrollback as ansi, reset SGR formatting at end of scrollback 2019-08-27 19:35:01 +05:30
Kovid Goyal
44599c9460 Merge branch 'simplify_compile_code' of https://github.com/Luflosi/kitty 2019-08-26 20:25:19 +05:30
Luflosi
902fc22670 Simplify GLFW compilation code
This commit removes the need for `is_macos` in `glfw/glfw.py` by moving a few lines of code. Instead of relying on the information that the compilation is or isn't happening on macOS, the code now does the right thing based on which `module` is being built.
This changes the order of the compilation flags slightly.
2019-08-26 16:47:19 +02:00
Kovid Goyal
d84e22fbf1 Merge branch 'fix_typos' of https://github.com/Luflosi/kitty 2019-08-26 16:34:54 +05:30
Luflosi
6cc720a350 Fix typos
Inspired by 4d3ee554b3.
Found using `codespell`.
2019-08-26 12:31:15 +02:00
Kovid Goyal
c905978874 Merge branch 'fix_issue_1924' of https://github.com/s1341/kitty
Fixes #1924
2019-08-26 10:19:50 +05:30
Kovid Goyal
bfe595a8e8 Merge branch '_glfwInputError_format' of https://github.com/Luflosi/kitty 2019-08-26 06:24:02 +05:30
Luflosi
94d56d1a9e Correct indentation for two _glfwInputError() messages
This commit changes the indentation of two error messages to match the indentation in the rest of the code.
2019-08-25 21:29:58 +02:00
s1341
bd3f0b5363 Properly handle all NULL cases 2019-08-25 17:22:06 +03:00
s1341
6fae3545c7 Fix null pointer deref 2019-08-25 16:39:39 +03:00
s1341
297963f6ab Fix issue #1924 by making prev_cell persistent across line_as_ansi calls 2019-08-25 16:25:36 +03:00
Kovid Goyal
a0ceba407e Merge branch 'drag_and_drop_text' of https://github.com/Luflosi/kitty 2019-08-24 08:39:27 +05:30
Kovid Goyal
35fa91fba2 When the OS returns a fallback font that does not actually contain glyphs for the text, do not exhaust the list of fallback fonts
Fixes #1918

Apparently fontconfig does this for Tangut components.
2019-08-24 08:27:54 +05:30
Kovid Goyal
a5d6cd169e Fix piping PNG images into the icat kitten not working
Fixes #1920
2019-08-24 08:04:04 +05:30
Luflosi
06c2263657 macOS: implement drag and drop of text into kitty
Closes #1368.
2019-08-24 01:29:33 +02:00
Kovid Goyal
472c6f6b8d When running kittens, use the colorscheme of the current window rather than the configured colorscheme
Fixes #1906
2019-08-18 18:27:44 +05:30
Kovid Goyal
afcaca85da Merge branch 'hints_regex_doc' of https://github.com/toonn/kitty 2019-08-18 07:41:14 +05:30
Toon Nolten
2575349ec2 Add expected regex syntax to hints kitten docs
The hints kitten's help documentation did not mention what syntax to use
for the regular expressions. I knew much of kitty was implemented in
python so I guessed correctly but not everyone might know this.

I also fixed some double-spaced sentences because most of them are
single-spaced.
2019-08-17 21:27:53 +02:00
Kovid Goyal
77054f688d Workaround for window managers like xmonad that in some circumstances set window size to zero. Fixes #1910 2019-08-17 18:04:08 +05:30
Kovid Goyal
c5cb24378f Merge branch 'fix_macos_show_window_title_in' of https://github.com/Luflosi/kitty 2019-08-14 06:36:25 +05:30
Luflosi
d66123dd14 Fix hiding the window title in macOS
In b5c2163238 I introduced a bug where only the window title of the first OS window would be hidden. This commit fixes that bug.
The bug was caused by the code hiding the window title being in an `if` statement that only executes once.
2019-08-13 21:02:28 +02:00
Kovid Goyal
4ef8f11f9e Merge branch 'add_frameworks_only_once' of https://github.com/Luflosi/kitty 2019-08-11 07:43:36 +05:30
Luflosi
599be7ddc9 Don't add Apple Frameworks twice
These Frameworks are added again a couple lines below in the check for `module == 'cocoa'`.
2019-08-11 02:26:12 +02:00
Kovid Goyal
685497fc8c Fix shaping test 2019-08-10 08:58:02 +05:30
Kovid Goyal
57542fc204 Only disable liga and dlig for nimbus mono 2019-08-10 08:22:36 +05:30
Kovid Goyal
8d9323aec6 Merge branch 'unnecessary_indentation' of https://github.com/Luflosi/kitty 2019-08-09 07:05:26 +05:30
Luflosi
4984a25b19 Remove unnecessary indentation 2019-08-09 03:27:22 +02:00
Kovid Goyal
3bdcb29e01 Merge branch 'trailing_whitespace' of https://github.com/Luflosi/kitty 2019-08-09 06:34:19 +05:30
Luflosi
b9ab8e6348 Remove trailing whitespace 2019-08-08 20:26:20 +02:00
Kovid Goyal
4a851701e9 Fix a regression that broke setting background_opacity via remote control
Fixes #1895
2019-08-07 15:09:04 +05:30
Kovid Goyal
eafd8af937 Merge branch 'glfw_3.4' of https://github.com/Luflosi/kitty 2019-08-03 07:38:14 +05:30
Luflosi
28bb123be8 Update the GLFW version number from 3.3 to 3.4
Closes https://github.com/kovidgoyal/kitty/issues/1884.
From a337c56848.
2019-08-02 11:00:16 -05:00
Kovid Goyal
8e1ed2f8c3 Update unicode data to 12.1 2019-08-02 14:48:18 +05:30
Kovid Goyal
4a0fcb3cff Merge branch 'macos_show_window_title_in' of https://github.com/Luflosi/kitty 2019-08-02 11:51:38 +05:30
Luflosi
b5c2163238 Add option to hide the window title on macOS
Deprecate `macos_show_window_title_in_menubar` and create a new option `macos_show_window_title_in`.
2019-08-02 00:20:43 -05:00
Kovid Goyal
d0ecdfb330 Add a :opt:kitten_alias option that can be used to alias kitten invocation for brevity and to change kitten option defaults globally
See #1879
2019-08-02 10:40:11 +05:30
Kovid Goyal
bdf7d98a36 hints kitten: Allow specifying :option:kitty +kitten hints --program multiple times to run multiple programs
See #1879
2019-08-02 10:03:04 +05:30
Kovid Goyal
e4b0980d15 DRYer 2019-08-02 07:18:42 +05:30
Kovid Goyal
d99c57aeae Merge branch 'open_context_manager' of https://github.com/Luflosi/kitty 2019-08-02 07:14:11 +05:30
Luflosi
5f855ce547 Use context managers to open files
Inspired by d50a6ddc1b.
2019-08-01 13:21:26 -05:00
Kovid Goyal
68f3b6fbeb Fix the decode_hint function to work with an arbitrary alphabet 2019-08-01 19:31:21 +05:30
Kovid Goyal
dc6d14943e Dont use a global variable for the hints alphabet 2019-08-01 19:24:09 +05:30
Kovid Goyal
05f7334db9 hints kitten: Add a :option:kitty +kitten hints --alphabet option to control what alphabets are used for hints
Fixes #1879
2019-08-01 16:25:54 +05:30
Kovid Goyal
cd707e9335 Merge branch 'wait_for_shell' of https://github.com/Luflosi/kitty 2019-08-01 12:56:12 +05:30
Luflosi
505ed5e43b Fix crash when the shell takes too long to start when reading the environment
According to https://docs.python.org/3/library/subprocess.html#subprocess.Popen.wait, `wait()` throws a `TimeoutExpired` exception when the process is not done after the timeout. I noticed this because kitty crashed for me.
The old code looks like it's trying to wait as long as it takes for the process to finish, which is what I implemented.
2019-08-01 02:03:08 -05:00
Kovid Goyal
9dc8bf5f62 Merge branch 'ignore_directories' of https://github.com/Luflosi/kitty 2019-08-01 06:38:34 +05:30
Luflosi
f8098662b6 Explicitly mark directories as such in .gitignore 2019-07-31 15:27:06 -05:00
Kovid Goyal
de7a0e86c4 Merge branch 'ignore_files_only_in_root' of https://github.com/Luflosi/kitty 2019-07-31 20:56:50 +05:30
Luflosi
ca55438fda Ignore several directories and files only in the root of the repo
These directories are always located in the root directory of the repository. Therefore it's better to only ignore these files in this location.
2019-07-31 10:16:19 -05:00
Kovid Goyal
a4b60e7eef Disable the `liga and dlig` OpenType features so that kitty works with "so-called" monospace fonts such as Nimbus Mono that have non-programming ligatures. 2019-07-31 20:02:48 +05:30
Kovid Goyal
5d22e07738 More details on login shell invocation 2019-07-31 12:20:02 +05:30
Kovid Goyal
bdade7e151 Use a new controlling terminal when reading shell environment
This is because some people do things in their rc files based
on checking the name of the controlling terminal.
2019-07-31 11:34:54 +05:30
Kovid Goyal
6958ded4c4 Dont fail to start if running the shell to read the EDITOR env var fails
Fixes #1869
2019-07-31 06:37:17 +05:30
Kovid Goyal
cc06104be6 Create FUNDING.yml
Add links to the various funding sources
2019-07-30 15:07:12 +05:30
Kovid Goyal
059c34c345 Add a version check to the installer on macOS 2019-07-30 15:01:07 +05:30
Kovid Goyal
9cbb726566 Fix #1865 2019-07-30 06:20:54 +05:30
Kovid Goyal
e8b4356a88 Merge branch 'ignore_build_only_in_root' of https://github.com/Luflosi/kitty 2019-07-29 11:37:36 +05:30
Kovid Goyal
634138cd3b Removed unused entry from .gitignore
Fixes #1859

tags is the file generated by ctags
2019-07-29 11:36:46 +05:30
Luflosi
3f6b07de81 Ignore the build directory only in the root of the repo
The `build` directory is always located at the root directory of the repository. Therefore it's better to only ignore `build` in this location.
2019-07-29 00:59:35 -05:00
Kovid Goyal
d218900b57 Remove unused header 2019-07-29 09:45:02 +05:30
Kovid Goyal
cab949a939 Fix building with compilers that dont support __has_include 2019-07-29 09:44:05 +05:30
Kovid Goyal
e350822f5e version 0.14.3 2019-07-29 09:29:50 +05:30
Kovid Goyal
3d6fe93297 DRYer 2019-07-29 09:23:29 +05:30
Kovid Goyal
3a5baf2722 Merge branch 'doc/mapping_shortcuts' of https://github.com/MagicDuck/kitty 2019-07-29 09:13:16 +05:30
Stephan Badragan
cdb472cb56 Adding documentation for how to map shortcuts 2019-07-28 15:53:44 -07:00
Kovid Goyal
e634350e77 Merge branch 'indentation' of https://github.com/Luflosi/kitty 2019-07-28 10:55:49 +05:30
Luflosi
464a6c1441 Fix indentation of bool variables in glfw/egl_context.h
Caused by fe62700825.
2019-07-28 00:23:17 -05:00
Kovid Goyal
d3750b2244 Merge branch 'glfw_reduce_difference' of https://github.com/Luflosi/kitty 2019-07-28 10:48:22 +05:30
Luflosi
b8d2b76ee4 Reduce the difference of glfw to upstream 2019-07-28 00:10:50 -05:00
Kovid Goyal
14fb7c3201 Merge branch 'glfw_fix_invalid_gamepad_axis_ranges' of https://github.com/Luflosi/kitty 2019-07-27 08:20:02 +05:30
Luflosi
922bc62e0e GLFW: Fix invalid ranges for gamepad axis sources
From 9420e6f0d0.
2019-07-26 13:30:38 -05:00
Kovid Goyal
00cae4ccd1 Merge branch 'indentation' of https://github.com/Luflosi/kitty 2019-07-26 23:00:25 +05:30
Luflosi
61df266df7 Fix indentation of bool variables in glfw/internal.h
Caused by fe62700825.
2019-07-26 11:45:32 -05:00
Kovid Goyal
17751666f2 Merge branch 'glfw_documentation_work' of https://github.com/Luflosi/kitty 2019-07-26 12:04:32 +05:30
Luflosi
961b2c9b65 GLFW: Documentation work
From 3cf7645b96.
2019-07-25 23:07:00 -05:00
Kovid Goyal
eaf6f06047 Merge branch 'remove_empty_line' of https://github.com/Luflosi/kitty 2019-07-26 08:27:57 +05:30
Luflosi
d0ac218c05 Remove empty line 2019-07-25 20:41:08 -05:00
Kovid Goyal
1a01bc15d8 Merge branch 'more_modern_objective-c' of https://github.com/Luflosi/kitty 2019-07-26 06:06:58 +05:30
Luflosi
cdbe2f13ca Cocoa: Move slightly towards modern Objective-C
Inspired by 9a9568212c.
2019-07-25 17:14:32 -05:00
Kovid Goyal
4f5264277e Merge branch 'remove_space' of https://github.com/Luflosi/kitty 2019-07-25 22:12:28 +05:30
Luflosi
bed3adcc95 Remove space from cast in kitty/cocoa_window.m
All the other casts to `NSWindow` in this file have the same formatting.
2019-07-25 11:01:16 -05:00
Kovid Goyal
0c5d59bcf6 Merge branch 'move_dict_iter_define' of https://github.com/Luflosi/kitty 2019-07-25 10:13:58 +05:30
Luflosi
ff20acd8b8 Move #define dict_iter() closer to where it is used 2019-07-24 23:30:40 -05:00
Kovid Goyal
d1cffcde68 Merge branch 'one_less_monotonic' of https://github.com/Luflosi/kitty 2019-07-25 09:45:39 +05:30
Luflosi
546dd9b225 Remove unnecessary call to monotonic()
Assuming the call to `update_drag()` returns basically instantly, this call to `monotonic()` can be safely removed.
2019-07-24 23:12:50 -05:00
Kovid Goyal
2a666620c8 Merge branch 'autoreleasepool_comments' of https://github.com/Luflosi/kitty 2019-07-25 06:04:26 +05:30
Luflosi
db50985040 Format the @autoreleasepool blocks in kitty/cocoa_window.m like in GLFW 2019-07-24 18:03:40 -05:00
Kovid Goyal
8c6d593c41 Merge branch 'rename_cocoa_update_title' of https://github.com/Luflosi/kitty 2019-07-24 11:59:23 +05:30
Luflosi
40086c8d1c Rename cocoa_update_title() -> cocoa_update_menu_bar_title()
I renamed `cocoa_update_title()` to `cocoa_update_menu_bar_title()` since that more accurately reflects what this function actually does.
2019-07-23 15:06:18 -05:00
Kovid Goyal
38f73b9f5e Fix #1832 2019-07-23 13:31:09 +05:30
Kovid Goyal
49429b5f49 When zeroing memory, use type independent code
Reduces the potential for bugs
2019-07-23 10:54:10 +05:30
Kovid Goyal
d9f90ef077 Make qsort invocations type independent 2019-07-23 10:20:41 +05:30
Kovid Goyal
6a126fa18e Fix a crash when displaying very large number of images
Fixes #1825
2019-07-23 10:18:09 +05:30
Kovid Goyal
14d703f5cc Cleanup 2019-07-23 09:44:58 +05:30
Kovid Goyal
9850025f3a Use image ids instead of pointers when removing images since pointer values are changed by the remove operation 2019-07-23 09:40:41 +05:30
Kovid Goyal
8daab0ba41 Change image internal_id type to id_type 2019-07-23 09:34:04 +05:30
Kovid Goyal
88f25ccc76 Also handle non-absolute paths being used for $EDITOR 2019-07-22 10:30:11 +05:30
Kovid Goyal
50e7351c73 When detecting the EDITOR from the environment, if the EDITOR env var is not present, try to read it from the shell's rc files by executing a login shell and dumping its environment
macOS makes it unreasonably hard to set system-wide environment
variables, so this hack might be useful there.
2019-07-22 09:29:55 +05:30
Kovid Goyal
51453a54e4 Merge branch 'remove_wgl_context' of https://github.com/Luflosi/kitty 2019-07-22 06:31:32 +05:30
Luflosi
c02ba03f39 Remove glfw/wgl_context.c and glfw/wgl_context.h 2019-07-21 15:03:39 -05:00
Kovid Goyal
78dec3d698 Merge branch 'fix_assertion' of https://github.com/Luflosi/kitty 2019-07-21 09:54:15 +05:30
Luflosi
1590c59131 Fix assertion for glfwSetGamma value
From 751c6f9a27.
2019-07-20 23:17:58 -05:00
Kovid Goyal
b26f79998a Merge branch 'glfw_c_dialect_reminders' of https://github.com/Luflosi/kitty 2019-07-21 08:33:19 +05:30
Luflosi
489f3e6c9d Add C dialect reminders to each glfw source file
Reduces the difference to upstream.
From 56aad76b16.
2019-07-20 21:07:27 -05:00
Kovid Goyal
5fef4726a7 Cocoa: Fix file-local function not declared static
From upstream: 062a1c22b5
2019-07-20 19:12:21 +05:30
Kovid Goyal
51fdb8200a X11: Fix focus events not being filtered
From upstream: c6b95e3b07
2019-07-20 19:11:00 +05:30
Kovid Goyal
fb0d98ead1 Add more debugs to Wayland handleEvents() 2019-07-20 14:48:28 +05:30
Kovid Goyal
4096caba64 Cancel read if dispatch_pending fails 2019-07-20 14:32:57 +05:30
Kovid Goyal
38f77144fa Wayland: dont abort the event handler early if there are no pending events from the compositor. This ensures that the tick callback and other event sources are dispatched. 2019-07-20 14:09:09 +05:30
Kovid Goyal
b8041ce17f Wayland: Fix infinite loop if the compositor dies 2019-07-20 13:55:38 +05:30
Kovid Goyal
00575733c8 Merge branch 'current_move_events_modifiers' of https://github.com/Luflosi/kitty 2019-07-20 11:33:12 +05:30
Luflosi
621c92780c Get more up-to-date modifiers for mouse move events 2019-07-20 01:00:02 -05:00
Kovid Goyal
37f03af4b7 Merge branch 'glfw_copyright_years' of https://github.com/Luflosi/kitty 2019-07-20 11:14:11 +05:30
Luflosi
bdc4558a43 Update GLFW copyright years
Reduces the difference to upstream.
From ab118b2529.
2019-07-20 00:30:13 -05:00
Kovid Goyal
46d483e8b2 Merge branch 'add_kakoune_editor' of https://github.com/Luflosi/kitty 2019-07-20 08:53:35 +05:30
Luflosi
5143b62a07 Add kakoune to the list of editors 2019-07-20 01:07:10 +02:00
Kovid Goyal
87ed774cb4 Add a new option :opt:pointer_shape_when_grabbed that allows you to control the mouse pointer shape when the terminal programs grabs the pointer
Fixes #1808
2019-07-19 19:34:32 +05:30
Kovid Goyal
4e427d05b7 Fix mouse move events not having modifiers
The lack of modifiers meant that detect of whether the event should be
tracked in kitty was not working
2019-07-19 19:02:09 +05:30
Kovid Goyal
195d987331 Make handle_in_kitty consistent between the button and motion handlers 2019-07-19 18:58:46 +05:30
Kovid Goyal
9b58317fb1 Better fix for kitty not getting key events when launched via a symlink on macOS
Avoids the overhead of checking for a symlink and re-execing.
Apparently all that was needed was setting the correct activation
policy, glfw is supposed to do this but does it only if the menubar hint
is on, which we turn off as we create our own menubar.
2019-07-18 16:00:16 +05:30
Kovid Goyal
1cb15dedac Simplify the event loop code
Also reduce input latency by ignoring repaint_delay when
there is actual pending input.

Gets rid of request_tick_callback(). Now empty events
result in the tick callback being called so there is only a
single mechanism for waking up the main loop and getting
the tick callback called.
2019-07-18 15:51:54 +05:30
Kovid Goyal
5521d6b623 Reset the sigprocmask and signal handlers when launching child processes. Fixes #1806 2019-07-18 09:26:31 +05:30
Kovid Goyal
f5cf6c1dcb Also make the loop flags volatile 2019-07-17 19:55:19 +05:30
Kovid Goyal
89307727e7 Use atomic variables for main loop flags 2019-07-17 19:45:52 +05:30
Kovid Goyal
c30c21b250 Dont sort on mtime
Files are built in order by size anyway and mtime sort makes link order
mtime dependent which breaks reproducible builds on openSUSE as they
modify mtimes randomnly. See #1804
2019-07-16 20:10:14 +05:30
Kovid Goyal
b6fb087d7e sub-sort by filename in find_c_files() 2019-07-16 16:46:48 +05:30
Kovid Goyal
97c2b7c1fe Fix #1804 2019-07-16 07:22:31 +05:30
Kovid Goyal
81506640c8 Run instructions for empty event test 2019-07-15 21:31:31 +05:30
Kovid Goyal
8244f7cd58 Linux: Only process global state when something interesting happens
This matches behavior on macOS. Had initially set the code to process
on every loop tick in an attmept to workaround the issue of the event
loop freezing on X11 until an X event is delivered. However, in light
of #1782 that workaround was incorrect anyway. Better to have similar
behavior across platforms. This also has the advantage of reducing CPU
consumption.

Also add a simple program to test event loop wakeups.
2019-07-15 21:30:00 +05:30
Kovid Goyal
63573d6e26 DRYer 2019-07-15 18:23:17 +05:30
Kovid Goyal
9368f7f670 When using :opt:strip_trailing_spaces do not remove empty lines
Fixes #1802
2019-07-15 17:17:40 +05:30
Kovid Goyal
b7a11035d5 Merge branch 'master' of https://github.com/sterpe/kitty 2019-07-15 09:44:20 +05:30
Steven Richard Terpe
2e1b5e2fa7 Update docs on kitty completion for bash v3.2, etc
See kovidgoyal/kitty#1520
2019-07-14 13:59:03 -07:00
Kovid Goyal
8e5cbafe63 Fix kitty @focus-tab not reporting errors
Fixes #1799
2019-07-14 10:08:44 +05:30
Kovid Goyal
eb006a6688 Indicate if set_active_tab() worked or not 2019-07-14 10:02:33 +05:30
Kovid Goyal
40b9049deb Move the kitty OpenGL API into its own compilation unit 2019-07-12 15:29:48 +05:30
Kovid Goyal
64ffca2d0a Merge branch 'reword_changelog_entry' of https://github.com/Luflosi/kitty 2019-07-12 04:48:04 +05:30
Luflosi
1f4b6d4e9a Update a changelog entry to be more descriptive
I think it is not clear what this entry actually means without the additional explanation.
2019-07-11 19:30:19 +02:00
Kovid Goyal
eb30ba7722 Cocoa: Fix code to shutdown display link for inactive monitors 2019-07-11 22:34:28 +05:30
Kovid Goyal
3e0f4d36bc DRYer 2019-07-11 21:48:45 +05:30
Kovid Goyal
1fb118edee Merge branch 'relative_path_compile' of https://github.com/Luflosi/kitty 2019-07-11 21:45:22 +05:30
Luflosi
ca39634880 Use relative paths when compiling 2019-07-11 16:51:50 +02:00
Kovid Goyal
f8418d68a6 Fully drain the wakeupfd 2019-07-09 18:49:46 +05:30
Kovid Goyal
c0000fb24e Should use an unsigned int for eventfd 2019-07-09 18:42:17 +05:30
Kovid Goyal
c169f7ae83 Retry writing to wakeupfd on EAGAIN as well 2019-07-09 18:40:51 +05:30
Kovid Goyal
7ab5244bf5 ssh kitten: Make argument parsing more like ssh
Fixes #1787
2019-07-09 17:48:43 +05:30
Kovid Goyal
7e36489034 Dont call detect joysticks if support for them has been disabled 2019-07-08 11:18:00 +05:30
Kovid Goyal
d259b12ae7 Micro-optimization: Avoid repeated calls to XQLength 2019-07-08 11:05:04 +05:30
Kovid Goyal
8f8138d9bd Have monotic() return numbers offset from init time 2019-07-08 10:30:06 +05:30
Kovid Goyal
a8668f5fbf Add a separate CI job for linux-package
Should catch issues like #1786 in the future
2019-07-08 07:44:01 +05:30
Kovid Goyal
e00e6bd1c2 Dont print "done" when doing nothing 2019-07-08 07:36:30 +05:30
Kovid Goyal
0fc6c47556 Merge branch 'glad2' of https://github.com/Dav1dde/kitty 2019-07-08 07:31:38 +05:30
Kovid Goyal
d530dccb96 Move docs generation into create_linux_bundle_gunk 2019-07-08 07:26:07 +05:30
Kovid Goyal
37bf0e81d2 Fix #1786 2019-07-08 06:46:16 +05:30
David Herberth
f872f955b0 Replace glad with glad2 2019-07-07 21:10:15 +02:00
Kovid Goyal
003cd0a203 Add a little more event loop debug output 2019-07-07 06:10:59 +05:30
Kovid Goyal
e7173f8145 Linux: Fix a regression in 0.14.0 that caused the event loop to tick continuously, wasting CPU even when idle
Fixes #1782
2019-07-07 05:57:18 +05:30
Kovid Goyal
93af102bec Clean link_commands.json 2019-07-07 04:52:24 +05:30
Kovid Goyal
67f23664c9 Generate Wayland protocol definitions in parallel as well 2019-07-05 20:57:56 +05:30
Kovid Goyal
39f6071c68 macOS: Fix a deadlock with CVDisplayLink
I had added an optimization to not pass messages to
main thread every time the CVDisplayLink timer fired, unless
a render frame for that monitor was actually requested.

However, this optimization is impossible to implement wihtout a deadlock
since CVDisplayLink has its own internal lock that it does not expose.

So I guess macOS users with multiple monitors will simply have to take
the performance hit of useless wakeups sixty times a second for every
extra monitor.

Fixes #1779
2019-07-05 20:16:32 +05:30
Kovid Goyal
edc8878632 Use relative paths for object files 2019-07-05 19:13:34 +05:30
Kovid Goyal
93b62c4dfd Also redo linking if the link command changes 2019-07-05 19:09:10 +05:30
Kovid Goyal
c3e210c80f Less output when building 2019-07-05 18:34:01 +05:30
Kovid Goyal
9a5cc8f650 Mark source names with glfw backend prefix 2019-07-05 18:27:13 +05:30
Kovid Goyal
5e7fbfefe9 Refactor the compilation code
Makes it a bit more efficient. All compiling is done in parallel,
followed by all linking.
2019-07-05 18:13:21 +05:30
Kovid Goyal
29ad6fba22 Linux: Use eventfd rather than a pipe for loop wakeup 2019-07-05 14:54:54 +05:30
Kovid Goyal
c848c3ee0d Use an interrupt-safe close() 2019-07-05 14:39:07 +05:30
Kovid Goyal
547132131a Linux: use signalfd rather than a pipe to handle signals 2019-07-05 14:33:22 +05:30
Kovid Goyal
40186fb54b Restore accidentally removed signal.h include 2019-07-05 12:22:38 +05:30
Kovid Goyal
5dc4e79c8d Move code to handle loop wakeup and signals into its own module 2019-07-05 12:19:37 +05:30
Kovid Goyal
556992a117 Forgot to make the eventfd cloexec and non-blocking 2019-07-05 10:08:15 +05:30
Kovid Goyal
a41ef8d513 Abort if addWatch during initialization of poll data fails 2019-07-05 10:00:39 +05:30
Kovid Goyal
6d96a89328 Linux: Use the more efficient eventfd mechanism to wakeup the event loop 2019-07-05 09:54:24 +05:30
Kovid Goyal
0fb1481038 Move event loop wakeup code into backend_utils 2019-07-05 09:34:51 +05:30
Kovid Goyal
4b77530c65 Store a reference to the glfw window pointer in the NSWindow class as well 2019-07-04 09:56:59 +05:30
Kovid Goyal
cdb493cf50 Couple more MIN/MAX type fixes 2019-07-04 09:15:13 +05:30
Kovid Goyal
c9a574a764 Cocoa: Ensure no callbacks are called on the view even if it is retained after being released
Fixes #1761 (I hope)
2019-07-04 09:03:13 +05:30
Kovid Goyal
bdb633a882 Merge branch 'tabs_to_spaces' of https://github.com/Luflosi/kitty 2019-07-04 08:19:01 +05:30
Luflosi
37aee7133d Convert tabs to spaces 2019-07-03 20:28:40 +02:00
Kovid Goyal
2cfd55f3ce Linux: Use the system "bell" for the terminal bell
Adds libcanberra as a new dependency to play the system sound.
2019-07-03 22:06:47 +05:30
Kovid Goyal
2e8188e89d Add libcanberra to the CI linux image 2019-07-03 20:30:12 +05:30
Kovid Goyal
1e172caea3 - Add an option :opt:terminal_select_modifiers to control which modifiers are used to override mouse selection
Fixes #1774
2019-07-03 10:50:07 +05:30
Kovid Goyal
6866cd0fb8 Document shift selection override behavior 2019-07-03 10:46:16 +05:30
Kovid Goyal
2719926870 Add some documentation on how to get regexes in the hints kitten to match over multiple lines. 2019-07-03 10:45:37 +05:30
Kovid Goyal
406891abcc Merge branch 'move_so_tmp_location' of https://github.com/Luflosi/kitty 2019-07-02 07:04:12 +05:30
Luflosi
4be6e9009a Move temporary location for shared objects into build directory 2019-07-02 01:49:35 +02:00
Kovid Goyal
6a31909557 Make the MIN and MAX macros typesafe 2019-07-01 17:03:47 +05:30
Kovid Goyal
f49f0d19f9 oops 2019-07-01 16:39:02 +05:30
Kovid Goyal
a2407f94e4 Remove unnecessary call to monotonic() 2019-07-01 16:36:29 +05:30
Kovid Goyal
62a0be4a11 Fix #1771 2019-07-01 16:35:35 +05:30
Kovid Goyal
b9029f6c67 Remove unnecessary extra copy 2019-07-01 13:57:16 +05:30
Kovid Goyal
92496f42c9 Try a couple of different header files for the BTN_ includes 2019-07-01 10:48:35 +05:30
Kovid Goyal
841c907efc Build glfw with all warnings enabled 2019-07-01 10:42:07 +05:30
Kovid Goyal
9bc288cd8e ... 2019-07-01 08:49:18 +05:30
Kovid Goyal
2ef0391b08 Convert some declarations to C99 style
From upstream: 0c6b505619
2019-07-01 08:32:47 +05:30
Kovid Goyal
6db768d1a3 Remove unneeded header
Fixes #1768
2019-07-01 06:07:55 +05:30
Kovid Goyal
9b080950a9 Cocoa: Cleanup
This makes the Cocoa _glfwPlatformSetWindowMonitor consistent with its
X11 and Win32 counterparts.

From upstream: 3262c29440
2019-07-01 05:59:32 +05:30
Kovid Goyal
3cd1fef4cb X11: Clean up EWMH feature detection
From upstream: fad9896d38
2019-07-01 05:57:17 +05:30
Kovid Goyal
a491a801bf X11: Let the language initialize XEvent structs
From upstream: 1f508530f0
2019-07-01 05:47:04 +05:30
Kovid Goyal
41ebb72276 Merge branch 'clean_kitty_launcher' of https://github.com/Luflosi/kitty 2019-07-01 05:28:08 +05:30
Luflosi
e4c0e9073e Clean "kitty/launcher" 2019-07-01 01:15:33 +02:00
Kovid Goyal
efad733cc5 DRYer 2019-06-30 18:42:20 +05:30
Kovid Goyal
1fcd6e1811 macOS: Fix finding fallback font for private use unicode symbols not working reliably
Fixes #1650
2019-06-30 18:11:58 +05:30
Kovid Goyal
75d697fa97 Fix #1766 2019-06-30 16:07:45 +05:30
Kovid Goyal
cde69670ba Linux: Fix incorrect scaling for fallback fonts when the font has an underscore that renders out of bounds
The calc_cell_height() function should not use underscore heights when
called in contexts other than cell metrics calculation.

Fixes #1713
2019-06-30 08:51:35 +05:30
Kovid Goyal
0be6c9cb97 Allow passing a `!neighbor` argument to the new_window mapping to open a new window next to the active window
Fixes #1746
2019-06-29 15:13:54 +05:30
Kovid Goyal
8c9d2d3ca2 macOS: Reduce energy consumption when idle by shutting down Apple's display link thread after 30 second of inactivity
Fixes #1763
2019-06-29 14:21:47 +05:30
Kovid Goyal
c84e73d8e6 Add some docs for how the completion system can be extended for a new shell 2019-06-29 07:56:24 +05:30
Kovid Goyal
3fb00f6c70 Re-request render frames if we dont hear back in a quarter of a second
Fixes #1748 (I hope)
2019-06-28 18:26:11 +05:30
Kovid Goyal
86305fdeb3 Use CVDisplayLinkIsRunning() rather than tracking started state since the OS can apparently shutdown the thread on its own in some scenarios 2019-06-28 17:46:59 +05:30
Kovid Goyal
710e146d22 Remove Makefile rule for logo building as the logo is now in git 2019-06-28 17:36:06 +05:30
Kovid Goyal
d5abc84bea Remote control: Add a command kitty @ scroll-window to scroll windows 2019-06-28 17:07:31 +05:30
Kovid Goyal
6f8214c15c Add the generated macOS icons to git
Removes the need for optipng/librsvg when building kitty.
2019-06-28 13:48:09 +05:30
Kovid Goyal
a56475e32f Dont use chdir() in logo/make.py 2019-06-28 13:44:42 +05:30
Kovid Goyal
9dadd91887 Build the kitty logo on CircleCI 2019-06-28 12:07:52 +05:30
Kovid Goyal
df5a73bb35 Dont change dirs when packaging 2019-06-28 12:00:12 +05:30
Kovid Goyal
a50bf59a2c macOS: Use a minimal bundle for the in-source kitty launcher
This should allow the Cocoa UI integration to work when running
kitty as kitty/launcher/kitty

Fixes #1756
2019-06-28 11:20:59 +05:30
Kovid Goyal
241354ae52 Move generation of Info.plist into its own function 2019-06-28 10:47:00 +05:30
Kovid Goyal
c863116011 Merge branch 'strip_once' of https://github.com/Luflosi/kitty 2019-06-27 05:18:04 +05:30
Luflosi
5cbd591a1e .strip() only once
`ans.append('KITTY_VCS_REV="{}"'.format(rev.strip()))` strips the
whitespace again later.
2019-06-26 19:48:58 +02:00
Kovid Goyal
6bb78c9499 Merge branch 'empty_lines' of https://github.com/Luflosi/kitty 2019-06-26 22:34:38 +05:30
Luflosi
893f406a99 Remove empty lines 2019-06-26 17:50:14 +02:00
Kovid Goyal
f722b898b0 Remove hard-coded restriction on drawing borders when only a single window is present
Instead this is controlled by the active layout. Fixes #1750
2019-06-26 19:35:49 +05:30
Kovid Goyal
18335b3eac Merge branch 'unify_compilation_database_access' of https://github.com/Luflosi/kitty 2019-06-26 19:30:30 +05:30
Luflosi
4708b592e2 Unify compilation_database access
`file` and `arguments` are accessed using the square bracket syntax, while `output` is accessed using `.get()`. This commit uses square brackets for all three. This will throw a `KeyError` if `compilation_database` does not have the key, which is the correct behaviour IMO.
2019-06-26 15:16:14 +02:00
Kovid Goyal
7598a2965c Merge branch 'sys_stat.h_macos_only' of https://github.com/Luflosi/kitty 2019-06-26 18:01:04 +05:30
Luflosi
1b59761a19 Only #include <sys/stat.h> on macOS
The `<sys/stat.h>` include in `launcher.c` is only used to check if the executable is a symlink on macOS. Therefore it is not needed on other platforms.
2019-06-26 14:05:35 +02:00
Kovid Goyal
7fd1053e0f Merge branch 'clean_more' of https://github.com/Luflosi/kitty 2019-06-26 08:18:45 +05:30
Luflosi
e178e7f6a5 Clean asan-launcher and kitty-profile 2019-06-25 20:22:23 +02:00
Kovid Goyal
d0bf21ab16 ... 2019-06-25 20:00:58 +05:30
Kovid Goyal
c826965833 Use libdir_name when bundle gunking on linux 2019-06-25 18:47:09 +05:30
Kovid Goyal
a76db39c19 Use a symlink for the in src launcher in a package 2019-06-25 18:37:11 +05:30
Kovid Goyal
323a538bdd Fix #1744 2019-06-25 18:16:00 +05:30
Kovid Goyal
2435feca3b oops 2019-06-25 08:26:19 +05:30
Kovid Goyal
29d059680c Merge branch 'fix_kitty.app_incremental_build' of https://github.com/Luflosi/kitty 2019-06-25 08:14:23 +05:30
Luflosi
aaaf7f9d8b Fix incremental compilation
The macOS specific `package()` code changes the directory. This didn't cause any problems before 9135387cfa since `compile_commands.json` was written to the filesystem before `package()` was called. This is not the case anymore, which results in `compile_commands.json` being written into the `kitty.app` bundle. I fixed the problem by using a context manager to change the direcctory back after `kitty.app` was created.
2019-06-25 02:55:13 +02:00
Kovid Goyal
bc90ce569a Build kitty.app on CI 2019-06-24 18:17:26 +05:30
Kovid Goyal
27f9f1756b Test doc building on macOS 2019-06-24 18:09:06 +05:30
Kovid Goyal
9135387cfa Get rid of the various different launchers
Now there is only one launcher. Which means it can be used to start
kitty with profiling and ASAN in the natural way. The recommended
way to run kitty from source is now:

./kitty/launcher/kitty

The launcher also automatically re-execs to resolve symlinks on macOS.
2019-06-24 17:21:30 +05:30
Kovid Goyal
af3504e05c Ensure that ensure_space() does not leave a NULL pointer 2019-06-24 16:00:45 +05:30
Kovid Goyal
9c9eac9d46 Merge branch 'delete_.dSYM' of https://github.com/Luflosi/kitty 2019-06-24 15:59:30 +05:30
Luflosi
f28383206a Delete *.dSYM directories when cleaning 2019-06-24 10:48:33 +02:00
Kovid Goyal
ba1c093d18 Merge branch 'manual_cleaning' of https://github.com/Luflosi/kitty 2019-06-24 08:36:52 +05:30
Luflosi
3ea3a85694 Never delete any files in the .git directory when cleaning manually
This is how results can be removed from os.walk(), according to https://docs.python.org/3/library/os.html#os.walk.
2019-06-23 21:08:46 +02:00
Luflosi
0e1a423889 Always clean files manually instead of using git
I see a couple problems with using git to determine the files to delete:
- git needs to be installed
- The manual cleaning code is supposed to function correctly, so why not always use it? That way bugs in the manual cleaning code are also more likely to get discovered
- If some files ignored by git should not be deleted, they need to be added to a sort of blacklist. If some files should be deleted by the manual cleanup code, they need to be added to a sort of whitelist. If someone forgets to add files to one of these lists, then not deleting files that should be deleted is better than deleting files that should not be deleted.
2019-06-23 21:08:16 +02:00
Kovid Goyal
3ce68ed53f Merge branch 'dSYM' of https://github.com/Luflosi/kitty 2019-06-23 20:03:07 +05:30
Luflosi
90c10da398 Ignore all *.dSYM directories
Building `kitty-profile` on macOS creates a `kitty-profile.dSYM` directory, that should be ignored, just like `asan-launcher.dSYM`.
2019-06-23 14:18:45 +02:00
Kovid Goyal
630bf28c22 Add examples for how to use OSC codes to change colors 2019-06-23 08:05:19 +05:30
Kovid Goyal
ff89c1d8e4 oops 2019-06-23 07:36:21 +05:30
Kovid Goyal
96703c23c8 Deal with .git being a file when getting the VCS commit hash during building 2019-06-23 07:36:03 +05:30
Kovid Goyal
2b78f5adad Merge branch 'copy_and_paste_error' of https://github.com/Luflosi/kitty 2019-06-23 07:27:22 +05:30
Luflosi
ab7df777eb Fix copy & paste error 2019-06-22 17:52:26 +02:00
Kovid Goyal
adbc694ff8 Merge branch 'non-mutable_default_argument' of https://github.com/Luflosi/kitty 2019-06-22 20:45:12 +05:30
Luflosi
7709cdb12b Make default argument non-mutable
Calling `Env()` without the `ldpaths` parameter after a call with the `ldpaths` parameter, keeps the list from the first call because the argument is mutable. This is probably not what was intended. This commit fixes this issue and also reverts a change to two lines introduced in 091e74d618, which was probably a workaround for this issue.
2019-06-22 16:57:38 +02:00
Kovid Goyal
f6051f73f5 Use SPECIAL_SOURCES for KITTY_VCS_REV
Fixes #1734
2019-06-22 18:54:58 +05:30
Kovid Goyal
d5c2a21cdf Merge branch 'diff_glfw_upstream' of https://github.com/Luflosi/kitty 2019-06-21 19:52:53 +05:30
Luflosi
8ffc841a3a Reduce the difference of glfw/cocoa_* to upstream
This only changes some formatting, whitespace, etc.. There are no
changes to the functionality.
Let me know if you don't like some of those changes.
2019-06-21 15:53:26 +02:00
Kovid Goyal
6c478977bb Merge branch 'missing_space' of https://github.com/Luflosi/kitty 2019-06-21 15:58:59 +05:30
Luflosi
07beb53b37 Add space after "if" 2019-06-21 12:12:13 +02:00
Kovid Goyal
59df1a8647 Merge branch 'diff_glfw_upstream' of https://github.com/Luflosi/kitty 2019-06-21 08:25:34 +05:30
Luflosi
fb98aa650d Reduce the difference of glfw to upstream
This only changes some formatting, whitespace, etc.. There are no
changes to the functionality.
Let me know if you don't like some of those changes.
2019-06-20 21:40:59 +02:00
Kovid Goyal
9981b5a9c6 Update xcode version in macos brew CI build 2019-06-20 06:28:49 +05:30
Kovid Goyal
603533e632 Fix a regression that caused closing an overlay window to focus the previously focused window rather than the underlying window
Fixes #1720
2019-06-17 09:00:47 +05:30
Kovid Goyal
38bc90f724 unicode_input kitten: Fix a regression that broke using indices to select recently used symbols. 2019-06-17 07:11:07 +05:30
Kovid Goyal
721beb9202 More docs for the cell fragment shader 2019-06-14 11:11:43 +05:30
Kovid Goyal
2e99259589 Make it possible to run custom kittens via kitty +kitten
Should help reduce confusion about how kittens work. Fixes #1712
2019-06-14 09:05:03 +05:30
Kovid Goyal
83e6b75872 More helpful error message if user tries to run a custom kitten via kitty +kitten 2019-06-14 08:23:25 +05:30
Kovid Goyal
cf70946f50 ... 2019-06-13 05:08:13 +05:30
Luflosi
f1c36aba83 Reduce the difference of glfw/null_* to upstream
This only changes some formatting, whitespace, etc.. There are no
changes to the functionality.
Let me know if you don't like some of those changes.
2019-06-12 20:45:21 +02:00
Kovid Goyal
2973cf15a4 Dont leak a file descriptor if pthread_create() fails 2019-06-12 21:51:32 +05:30
Kovid Goyal
55969bc3c5 Also set cwd when piping to none 2019-06-12 21:43:13 +05:30
Kovid Goyal
a8504c971a Also set special env for piped child with no input 2019-06-12 21:36:13 +05:30
Kovid Goyal
1644de2083 Use an explicit pipe instead of relying on subprocess.PIPE
Not sure what the lifetime semantics for fds created by subprocess.PIPE
are
2019-06-12 21:31:06 +05:30
Kovid Goyal
dd1fb85f60 When piping data to a child in the pipe command do it in a thread so as not to block the UI
See #1708
2019-06-12 21:03:18 +05:30
Kovid Goyal
b945b19865 Make thread_write() more robust 2019-06-12 20:58:47 +05:30
Kovid Goyal
91bf9f2ec8 Ensure fd is blocking in thread_write() 2019-06-12 20:42:17 +05:30
Kovid Goyal
f151f4c165 Detach the stdin write thread so that it is auto-cleaned up 2019-06-12 20:36:53 +05:30
Kovid Goyal
95b9b2d373 Merge branch 'diff_glfw_upstream' of https://github.com/Luflosi/kitty 2019-06-12 19:40:07 +05:30
Luflosi
8be698681c Reduce the difference of glfw/wl_* to upstream
This only changes some formatting, whitespace, etc.. There are no
changes to the functionality.
Let me know if you don't like some of those changes.
2019-06-12 14:55:56 +02:00
Kovid Goyal
da3e1a3730 Finish documenting commands 2019-06-12 15:30:26 +05:30
Kovid Goyal
29f637c19a Document a couple more commands 2019-06-12 15:14:15 +05:30
Kovid Goyal
3d01565ba7 Document more commands 2019-06-12 15:01:14 +05:30
Kovid Goyal
962291cc8e Document another command 2019-06-12 13:41:46 +05:30
Kovid Goyal
a662dace9c Document a couple more commands 2019-06-12 13:33:12 +05:30
Kovid Goyal
d34e0b325e Document a couple more commands 2019-06-12 13:20:54 +05:30
Kovid Goyal
4c242ec528 Document a couple more commands 2019-06-12 13:17:28 +05:30
Kovid Goyal
658be9405f Document the kitty remote control protocol
Fixes #1646
2019-06-12 13:12:53 +05:30
Kovid Goyal
15e8f6ad8a Another fix to the scissor for rendering the cell area
With a cyan background it becomes apparent that the width/height are one
pixel too small
2019-06-12 10:37:20 +05:30
Kovid Goyal
a5aca35f1c Simplify and document the operation of the cell fragment shader
Also get rid of the unneccessary double bg_alpha followed by divide by
alpha step when rendering interleaved and premult
2019-06-12 10:22:47 +05:30
Kovid Goyal
ae9df1ffac oops 2019-06-12 08:03:10 +05:30
Kovid Goyal
8bf2e098f5 Fix an out of bounds read causing a crash when selecting text with the mouse in the alternate screen mode
Fixes #1578
2019-06-12 07:52:37 +05:30
Kovid Goyal
7091d554b5 Merge branch 'diff_glfw_upstream' of https://github.com/Luflosi/kitty 2019-06-12 05:17:15 +05:30
Luflosi
bada795320 Reduce the difference of glfw/x11_* to glfw upstream
This only changes some formatting, whitespace, etc.. There are no
changes to the functionality.
Let me know if you don't like some of those changes.
2019-06-11 17:57:39 +02:00
Kovid Goyal
7d385849fb Merge branch 'simplify_code' of https://github.com/Luflosi/kitty 2019-06-11 19:42:59 +05:30
Luflosi
78775b7f6b Use "with suppress()" to suppress a python exception 2019-06-11 15:48:27 +02:00
Kovid Goyal
8d21a5b6b3 Fallback on ctypes' find_library to load libxkbcommon 2019-06-11 16:58:57 +05:30
Kovid Goyal
9da095ca50 Fix #1703 2019-06-11 16:54:55 +05:30
Kovid Goyal
0fafc07db0 Fix #1702 2019-06-11 15:30:50 +05:30
Kovid Goyal
65b95999c1 version 0.14.2 2019-06-09 13:40:02 +05:30
Kovid Goyal
056012871f Merge branch 'bash_shebang' of https://github.com/Luflosi/kitty 2019-06-09 08:44:06 +05:30
Luflosi
c7b377080c Use "#!/usr/bin/env bash" shebang instead of "#!/bin/bash"
All python scripts start with `#!/usr/bin/env python3` so I did the same
for a bash script.
2019-06-08 12:57:46 +02:00
Kovid Goyal
47acc9ff2f Get rid of GLFW_(TRUE|FALSE) 2019-06-08 08:14:30 +05:30
Kovid Goyal
fe62700825 Get rid of GLFWbool 2019-06-08 08:12:42 +05:30
Kovid Goyal
6bcab56988 Merge branch 'whitespace' of https://github.com/Luflosi/kitty 2019-06-08 07:18:18 +05:30
Luflosi
fbc4d3e1be Remove extra spaces 2019-06-08 00:48:09 +02:00
Kovid Goyal
c89d1643f4 Merge branch 'typo' of https://github.com/Luflosi/kitty 2019-06-07 16:30:39 +05:30
Luflosi
e2226a1509 Fix typo 2019-06-07 12:26:52 +02:00
Kovid Goyal
656916e0fa Use remove_i_from_array in a few more places
Also simplify the REMOVER macro
2019-06-07 14:25:33 +05:30
Kovid Goyal
4a55eb9e7f typo 2019-06-07 13:53:35 +05:30
Kovid Goyal
9c8cf04a80 Wayland: Don't insert the same monitor twice if the done event for an output is sent twice 2019-06-07 13:38:44 +05:30
Kovid Goyal
e846bc9308 Wayland: Fix crash when enabling disabling monitors on sway
When an output is unregistered, the corresponding monitor object should
be removed from every windows' monitor list

Proper fix for #1696
2019-06-07 12:40:02 +05:30
Kovid Goyal
3c7a71772c Wrap memmove in glfw with a nice safe macro 2019-06-07 10:01:10 +05:30
Kovid Goyal
857a53e80f Dont crash if GLFW gives us obviously erroneous framebuffer sizes
Fixes #1696
2019-06-07 09:28:30 +05:30
Kovid Goyal
84fcabe5cf Allow using the pipe command to send screen and scrollback contents directly to the clipboard
See #1693
2019-06-07 07:47:34 +05:30
Kovid Goyal
9dc410c9fd oops 2019-06-07 07:20:08 +05:30
Kovid Goyal
8ebad06e7e clipboard kitten: Add a --wait-for-completion option to have the kitten wait till copying to clipboard is complete
Fixes #1693
2019-06-07 07:13:15 +05:30
Kovid Goyal
5db1a07f81 Merge branch 'simplify_code' of https://github.com/Luflosi/kitty 2019-06-07 06:21:00 +05:30
Luflosi
48e5c8edb3 Remove unused code
As far as I can tell, these attributes are not used anywhere.
2019-06-06 18:03:48 +02:00
Kovid Goyal
eefc21920e Merge branch 'simplify_code' of https://github.com/Luflosi/kitty 2019-06-06 21:26:24 +05:30
Luflosi
d7dd9c295b Use more specific exception
I think it's better to use `ImportError` here instead of the much more generic `Exception`.
2019-06-06 17:45:37 +02:00
Kovid Goyal
4faf71bd03 Merge branch 'simplify_code' of https://github.com/Luflosi/kitty 2019-06-06 06:22:52 +05:30
Luflosi
2751dbdb94 Fix test_url_at
`lspace_test()` has a parameter called scheme with the default value `http`. It
is called in a nested for loop, but the scheme from the inner for loop is
just ignored.
2019-06-05 18:32:23 +02:00
Kovid Goyal
fe329cb4ab Merge branch 'simplify_code' of https://github.com/Luflosi/kitty 2019-06-05 21:40:15 +05:30
Luflosi
741e719ff8 Remove unused function
Searching for `color_as_vec3` yielded no results in the entire project
but I encourage you to verify that this function is really not used
anywhere.
2019-06-05 18:01:19 +02:00
Kovid Goyal
866bb32046 Merge branch 'simplify_code' of https://github.com/Luflosi/kitty 2019-06-05 21:14:16 +05:30
Luflosi
7f01e758b3 Simplify code
The result from `self.add_os_window()` is overwritten later and not used
between the two assignments, so I removed the first assignment and moved the second
assignment to the line after the call to `self.add_os_window()`.
2019-06-05 17:33:04 +02:00
Kovid Goyal
03003d270e Merge branch 'simplify_code' of https://github.com/Luflosi/kitty 2019-06-05 20:47:11 +05:30
Luflosi
3d313016ba Remove double assignment
The `payload` variable is assigned twice.
Static program analysis FTW!
2019-06-05 17:12:21 +02:00
Kovid Goyal
1292c752a8 Merge branch 'simplify_code' of https://github.com/Luflosi/kitty 2019-06-05 20:35:29 +05:30
Luflosi
4783947135 Remove useless code
As far as I can tell, `.active_window` does absolutely nothing, so I
removed it.
2019-06-05 16:53:32 +02:00
Kovid Goyal
c9045788f5 Merge branch 'chained_comparisons' of https://github.com/Luflosi/kitty 2019-06-05 19:38:24 +05:30
Luflosi
4eed8463b3 Simplify chained comparisions 2019-06-05 15:24:36 +02:00
Kovid Goyal
303711ab8d Wayland: Detect SSD by querying compositor
Much more reliable than checking environment variables. Does
add ~1ms to startup time on Wayland.
2019-06-05 10:37:57 +05:30
Kovid Goyal
98d7fc9f39 Simplify code 2019-06-05 08:26:25 +05:30
Kovid Goyal
c0a96f2087 icat kitten: Fix a regression that broke passing directories to icat
Fixes #1683
2019-06-05 07:36:47 +05:30
Kovid Goyal
c509ecca52 Wayland: Fix resizing the window on a compositor that does not provide server side window decorations, such a GNOME or Weston not working correctly
See #1659
2019-06-04 19:40:00 +05:30
Kovid Goyal
e5d8eb7845 Micro-optimization 2019-06-04 19:28:46 +05:30
Kovid Goyal
277f43aed6 Linux: Disable the Wayland backend on GNOME
GNOME has no support for server side decorations.
Can be controlled by new option linux_display_server.
2019-06-04 19:10:13 +05:30
Kovid Goyal
f1494b64e5 Do not depend on glfw just to parse the config file 2019-06-04 18:02:56 +05:30
Kovid Goyal
6b9c71ec62 ... 2019-06-04 17:24:42 +05:30
Kovid Goyal
d12a4b0a1a Test changing of update_check_interval on the CI server 2019-06-04 14:32:37 +05:30
Kovid Goyal
a75d075dd1 Add an option to control the default update_check_interval when building kitty packages
Fixes #1675
2019-06-04 14:27:28 +05:30
Kovid Goyal
8f8a37bf94 Fix #1678 2019-06-04 14:14:12 +05:30
Kovid Goyal
03f692fed8 Make it clear what pass_selection_to_program does 2019-06-04 13:48:34 +05:30
Kovid Goyal
614416d4b0 Fix positioning of text in the panel kitten 2019-06-03 20:37:36 +05:30
Kovid Goyal
feb851716e Merge branch 'python_beautify' of https://github.com/Luflosi/kitty 2019-06-03 16:18:42 +05:30
Luflosi
2b095f720e Use "with suppress()" to suppress python exceptions
Using
```Python
with suppress(OSError):
    os.remove('somefile.tmp')
```
instead of
```Python
try:
    os.remove('somefile.tmp')
except OSError:
    pass
```
makes the code more compact and more readable IMO.

This pattern was recommended by Raymond Hettinger, a Python Core
Developer in his talk "Transforming Code into Beautiful, Idiomatic Python" at https://www.youtube.com/watch?v=OSGv2VnC0go. The transcript is available at https://github.com/JeffPaine/beautiful_idiomatic_python
2019-06-03 12:27:43 +02:00
Kovid Goyal
d6e750727f Merge branch 'master' of https://github.com/copy/kitty 2019-06-03 08:46:47 +05:30
Fabian
961ff8633d Add align_top_left option to avoid a padding on the top/left 2019-06-02 11:08:09 -05:00
Kovid Goyal
8406d4a8f1 Forgot another print statement
Really should not code when I am busy :)
2019-06-02 20:23:56 +05:30
Kovid Goyal
e25b64ae15 ... 2019-06-02 18:01:32 +05:30
Kovid Goyal
59205a4caf macOS: Fix a regression in the previous release that broke using :kbd:ctrl+shift+tab
Fixes #1671
2019-06-02 17:36:16 +05:30
Kovid Goyal
5001797179 Merge branch 'fix_typo' of https://github.com/Luflosi/kitty 2019-06-02 16:50:02 +05:30
Luflosi
b24dd69067 Fix typo 2019-06-02 11:54:20 +02:00
Kovid Goyal
4f163338dd Allow controlling how multiple selections are handled in the hints kitten
Fixes #1665
2019-06-02 09:23:20 +05:30
Kovid Goyal
1e8f1f8cc6 Ensure trailing space is drawn around tab separator when title is too long to fit
Fix #1668
2019-05-31 17:51:56 +05:30
Kovid Goyal
5c3e2e6877 Add a note for packagers if they want to turn off the update check mechanism 2019-05-31 17:47:53 +05:30
Kovid Goyal
ff52ff7865 version 0.14.1 2019-05-29 19:57:00 +05:30
Kovid Goyal
f6f55aaa9a NSGL: Remove enforcement of forward-compatible flag
Upstream commit:
0b01d850ed
2019-05-29 19:52:15 +05:30
Kovid Goyal
6f1aecab99 Remove pointless comment
Upstream commit
84ec99bb01
2019-05-29 19:50:22 +05:30
Kovid Goyal
f33205a490 Wayland: Fix maximizing the window on a compositor that does not provide server side window decorations, such a GNOME or Weston not working
Fixes #1662
2019-05-29 17:07:42 +05:30
Kovid Goyal
2920638a3d Add a shortcut to toggle maximized window state 2019-05-29 16:41:34 +05:30
Kovid Goyal
1ae32b5742 Linux: Automatically increase cell height if the font being used is broken and draws the underscore outside the bounding box
See #690
2019-05-29 16:04:50 +05:30
Kovid Goyal
4e9dabfb25 Add an option :opt:command_on_bell to run an arbitrary command when a bell occurs
Fixes #1660
2019-05-29 09:42:52 +05:30
Kovid Goyal
ca2c419c9b Fix colors not being preserved when using the pipe command with the pager history buffer
Fixes #1657
2019-05-29 09:13:55 +05:30
Kovid Goyal
020c1311ca When resizing and only a single window is present in the current layout, use that window's background color to fill in the blank areas. 2019-05-29 09:01:57 +05:30
Kovid Goyal
8193b2a44b Use layout depenedent key check for strl+tab as well 2019-05-29 08:43:13 +05:30
Kovid Goyal
324a000777 Merge branch 'docs_conf.py_shebang' of https://github.com/Luflosi/kitty 2019-05-28 20:53:30 +05:30
Luflosi
951b1c1e83 Add shebang for docs/conf.py 2019-05-28 17:17:18 +02:00
Kovid Goyal
8e57fd93c6 macOS: Fix a regression that caused cmd+v to double up in the dvorak keyboard layout
Fixes #1652
2019-05-28 20:35:13 +05:30
Kovid Goyal
d262f43b5b Log ARepeat property 2019-05-28 20:18:50 +05:30
Kovid Goyal
73224e7d95 One less line in the debug log 2019-05-28 20:04:21 +05:30
Kovid Goyal
19463c81a3 Merge branch 'docs_copyright_year' of https://github.com/Luflosi/kitty 2019-05-28 19:12:24 +05:30
Luflosi
6f2bb31068 Make the copyright year dynamic for the documentation 2019-05-28 14:58:09 +02:00
Kovid Goyal
abf9c4117d macOS: Fix a regression that could cause rendering of a kitty window to occasionally freeze in certain situations, such as moving it between monitors or transitioning from/to fullscreen
Fixes #1641
2019-05-28 17:54:34 +05:30
Kovid Goyal
39f50830d7 Fix a missing newline when using the pipe command between the scrollback and screen contents
See #1642
2019-05-28 15:30:44 +05:30
Kovid Goyal
c2fd7005cb Fix Ctrl+underscore not being passed to child programs in normal and application keyboard modes 2019-05-24 19:21:48 +05:30
Kovid Goyal
52f2ed33f5 Add a link to the Ubuntu kitty package 2019-05-24 18:08:29 +05:30
Kovid Goyal
a51239c6ae Add support for the underscore key found in some keyboard layouts
Fixes #1639
2019-05-24 17:59:50 +05:30
Jerome Reybert
e6217e1428 Fix warning with old freetype headers
On Centos 7.6, build produces the following warnings:

    kitty/freetype.c: In function ‘render_bitmap’:
    kitty/freetype.c:369:36: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
             for (unsigned int i = 0; i < bitmap.rows; ++i) {
                                        ^
    kitty/freetype.c:371:40: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
                 for (unsigned int j = 0; j < bitmap.width; ++j) bitmap.buffer[i * stride + j] *= 255;
2019-05-24 11:57:08 +02:00
189 changed files with 38935 additions and 38239 deletions

View File

@@ -10,10 +10,16 @@ jobs:
- run: if grep -Inr '\s$' kitty kitty_tests kittens docs *.py *.asciidoc *.rst .gitattributes .gitignore; then echo Trailing whitespace found, aborting.; exit 1; fi
- run: python3 -m flake8 --count .
- run: python3 setup.py build --debug --verbose
- run: python3 test.py
- run: ./kitty/launcher/kitty +launch test.py
- run: make FAIL_WARN=-W man
- run: make FAIL_WARN=-W html
- run: python3 setup.py linux-package
lin-package:
docker:
- image: kovidgoyal/kitty-test:latest
steps:
- checkout
- run: python3 setup.py linux-package --update-check-interval=0
lin-35:
docker:
@@ -26,7 +32,7 @@ jobs:
steps:
- checkout
- run: /opt/py3.5/bin/python3 setup.py build --debug --verbose --sanitize
- run: ./asan-launcher test.py
- run: ./kitty/launcher/kitty +launch test.py
lin-37:
docker:
@@ -38,7 +44,7 @@ jobs:
steps:
- checkout
- run: /opt/py3.7/bin/python3 setup.py build --debug --verbose --sanitize
- run: ./asan-launcher test.py
- run: ./kitty/launcher/kitty +launch test.py
lin-bundle:
docker:
@@ -49,8 +55,9 @@ jobs:
- checkout
- run: echo "export LD_LIBRARY_PATH=$SW/lib" >> $BASH_ENV
- run: echo "export PKG_CONFIG_PATH=$SW/lib/pkgconfig" >> $BASH_ENV
- run: echo "export PYTHONHOME=$SW" >> $BASH_ENV
- run: $SW/bin/python3 setup.py build --debug --verbose
- run: $SW/bin/python3 test.py
- run: ./kitty/launcher/kitty +launch test.py
mac-bundle:
macos:
@@ -65,21 +72,23 @@ jobs:
- run: curl https://download.calibre-ebook.com/travis/kitty/osx.tar.xz | tar xJ -C $SW
- run: echo "export PATH=$SW/bin:$PATH" >> $BASH_ENV
- run: python3 setup.py build --debug --verbose
- run: python3 test.py
- run: ./kitty/launcher/kitty +launch test.py
mac-brew:
macos:
xcode: "10.1.0"
xcode: "10.2.0"
environment:
LC_ALL: en_US.UTF-8
LANG: en_US.UTF-8
steps:
- checkout
- run: brew bundle
- run: python3 logo/make.py
- run: python3 setup.py build --debug --verbose
- run: python3 test.py
- run: python3 setup.py macos-bundle
- run: ./kitty/launcher/kitty +launch test.py
- run: echo "export PATH=/usr/local/opt/sphinx-doc/bin:$PATH" >> $BASH_ENV
- run: python3 setup.py linux-package --verbose
- run: python3 setup.py kitty.app --verbose
- run: kitty.app/Contents/MacOS/kitty +runpy "from kitty.constants import *; print(kitty_exe())"
workflows:
@@ -90,5 +99,6 @@ workflows:
- lin-sys
- lin-35
- lin-37
- lin-package
- lin-bundle
- mac-brew

View File

@@ -31,7 +31,7 @@ ENV LANG=en_US.UTF-8
RUN apt-get install -y libreadline-dev zlib1g-dev libssl-dev libbz2-dev libsqlite3-dev libffi-dev
# kitty deps
RUN apt-get install -y libgl1-mesa-dev libxi-dev libxrandr-dev libxinerama-dev libxcursor-dev libxcb-xkb-dev libdbus-1-dev libxkbcommon-dev libharfbuzz-dev libpng-dev libfontconfig-dev libpython3-dev libxkbcommon-x11-dev python3-pygments
RUN apt-get install -y libgl1-mesa-dev libxi-dev libxrandr-dev libxinerama-dev libxcursor-dev libxcb-xkb-dev libdbus-1-dev libxkbcommon-dev libharfbuzz-dev libpng-dev libfontconfig-dev libpython3-dev libxkbcommon-x11-dev python3-pygments libcanberra-dev
# Needed to build kitty docs
RUN pip3 install sphinx

3
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,3 @@
patreon: kovidgoyal
liberapay: kovidgoyal
custom: https://sw.kovidgoyal.net/kitty/support.html

28
.gitignore vendored
View File

@@ -1,19 +1,17 @@
*.so
*.pyc
*.pyo
tags
build
linux-package
kitty.app
logo/*.iconset
compile_commands.json
glad/out
asan-launcher
asan-launcher.dSYM
kitty-profile
dev
__pycache__
glfw/wayland-*-client-protocol.[ch]
docs/_build
docs/generated
/tags
/build/
/linux-package/
/kitty.app/
/compile_commands.json
/link_commands.json
/glad/out/
/kitty/launcher/
/*.dSYM/
__pycache__/
/glfw/wayland-*-client-protocol.[ch]
/docs/_build/
/docs/generated/
.DS_Store

View File

@@ -1,6 +1,5 @@
brew 'pkg-config'
brew 'imagemagick'
brew 'optipng'
brew 'librsvg'
brew 'harfbuzz'
brew 'python'
brew 'sphinx-doc'

View File

@@ -1,8 +1,8 @@
ifdef V
VVAL=--verbose
VVAL=--verbose
endif
ifdef VERBOSE
VVAL=--verbose
VVAL=--verbose
endif
all:
@@ -28,12 +28,7 @@ asan:
profile:
python3 setup.py build $(VVAL) --profile
logo/kitty.iconset/icon_256x256.png: logo/kitty.svg logo/make.py
logo/make.py
rendered_logo: logo/kitty.iconset/icon_256x256.png
app: rendered_logo
app:
python3 setup.py kitty.app $(VVAL)
man:

View File

@@ -1,19 +0,0 @@
/*
* asan-launcher.c
* Copyright (C) 2017 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#include <Python.h>
#define MAX_ARGC 1024
int main(int argc, char *argv[]) {
wchar_t *argvw[MAX_ARGC + 1] = {0};
argvw[0] = L"kitty";
for (int i = 1; i < argc; i++) argvw[i] = Py_DecodeLocale(argv[i], NULL);
int ret = Py_Main(argc, argvw);
for (int i = 1; i < argc; i++) PyMem_RawFree(argvw[i]);
return ret;
}

View File

@@ -1,2 +1,2 @@
#!/bin/bash
#!/usr/bin/env bash
cloc --exclude-list-file <(echo -e 'kitty/wcwidth-std.h\nkitty/glfw.c\nkitty/keys.h\nkitty/charsets.c\nkitty/unicode-data.c\nkitty/key_encoding.py\nkitty/rgb.py\nkitty/gl.h\nkitty/gl-wrapper.h\nkitty/gl-wrapper.c\nkitty/khrplatform.h\nkitty/glfw-wrapper.h\nkitty/glfw-wrapper.c\nkitty/emoji.h\nkittens/unicode_input/names.h') kitty kittens

View File

@@ -20,6 +20,7 @@ Run-time dependencies:
* libpng
* freetype (not needed on macOS)
* fontconfig (not needed on macOS)
* libcanberra (not needed on macOS)
* ImageMagick (optional, needed to use the ``kitty icat`` tool to display images in the terminal)
* pygments (optional, need for syntax highlighting in ``kitty +kitten diff``)
@@ -28,7 +29,7 @@ Build-time dependencies:
* gcc or clang
* pkg-config
* For building on Linux in addition to the above dependencies you might also need to install the ``-dev`` packages for:
``libdbus-1-dev``, ``libxcursor-dev``, ``libxrandr-dev``, ``libxi-dev``, ``libxinerama-dev``, ``libgl1-mesa-dev``, ``libxkbcommon-x11-dev``, ``libfontconfig-dev`` and ``libpython-dev``.
``libdbus-1-dev``, ``libxcursor-dev``, ``libxrandr-dev``, ``libxi-dev``, ``libxinerama-dev``, ``libgl1-mesa-dev``, ``libxkbcommon-x11-dev``, ``libfontconfig-dev``, ``libcanberra-dev`` and ``libpython-dev``.
if they are not already installed by your distro.
Install and run from source
@@ -44,25 +45,17 @@ Now build the native code parts of |kitty| with the following command::
You can run |kitty|, as::
python3 .
./kitty/launcher/kitty
If that works, you can create a script to launch |kitty|:
.. code-block:: sh
#!/usr/bin/env python3
import runpy
runpy.run_path('/path/to/kitty/dir', run_name='__main__')
And place it in :file:`~/bin` or :file:`/usr/bin` so that you can run |kitty| using
If that works, you can create a symlink to the launcher in :file:`~/bin` or
some other directory on your PATH so that you can run |kitty| using
just ``kitty``.
Building kitty.app on macOS from source
-------------------------------------------
Install `imagemagick`, `optipng` and `librsvg` using `brew` or similar (needed
for the logo generation step). And run::
Run::
make app
@@ -111,3 +104,9 @@ without needing to install all of |kitty|.
This applies to creating packages for |kitty| for macOS package managers such as
brew or MacPorts as well.
.. note::
|kitty| has its own update check mechanism, if you would like to turn
it off for your package, use
``python3 setup.py linux-package --update-check-interval=0``

View File

@@ -4,6 +4,177 @@ Changelog
|kitty| is a feature full, cross-platform, *fast*, GPU based terminal emulator.
To update |kitty|, :doc:`follow the instructions <binary>`.
0.14.4 [2019-08-31]
---------------------
- hints kitten: Add a :option:`kitty +kitten hints --alphabet` option to
control what alphabets are used for hints (:iss:`1879`)
- hints kitten: Allow specifying :option:`kitty +kitten hints --program`
multiple times to run multiple programs (:iss:`1879`)
- Add a :opt:`kitten_alias` option that can be used to alias kitten invocation
for brevity and to change kitten option defaults globally (:iss:`1879`)
- macOS: Add an option :opt:`macos_show_window_title_in` to control
showing the window title in the menubar/titlebar (:pull:`1837`)
- macOS: Allow drag and drop of text from other applications into kitty
(:pull:`1921`)
- When running kittens, use the colorscheme of the current window
rather than the configured colorscheme (:iss:`1906`)
- Don't fail to start if running the shell to read the EDITOR env var fails
(:iss:`1869`)
- Disable the ``liga`` and ``dlig`` OpenType features for broken fonts
such as Nimbus Mono.
- Fix a regression that broke setting background_opacity via remote control
(:iss:`1895`)
- Fix piping PNG images into the icat kitten not working (:iss:`1920`)
- When the OS returns a fallback font that does not actually contain glyphs
for the text, do not exhaust the list of fallback fonts (:iss:`1918`)
- Fix formatting attributes not reset across line boundaries when passing
buffer as ANSI (:iss:`1924`)
0.14.3 [2019-07-29]
---------------------
- Remote control: Add a command `kitty @ scroll-window` to scroll windows
- Allow passing a ``!neighbor`` argument to the new_window mapping to open a
new window next to the active window (:iss:`1746`)
- Document the kitty remote control protocol (:iss:`1646`)
- Add a new option :opt:`pointer_shape_when_grabbed` that allows you to control
the mouse pointer shape when the terminal programs grabs the pointer
(:iss:`1808`)
- Add an option :opt:`terminal_select_modifiers` to control which modifiers
are used to override mouse selection even when a terminal application has
grabbed the mouse (:iss:`1774`)
- When piping data to a child in the pipe command do it in a thread so as not
to block the UI (:iss:`1708`)
- unicode_input kitten: Fix a regression that broke using indices to select
recently used symbols.
- Fix a regression that caused closing an overlay window to focus
the previously focused window rather than the underlying window (:iss:`1720`)
- macOS: Reduce energy consumption when idle by shutting down Apple's display
link thread after 30 second of inactivity (:iss:`1763`)
- Linux: Fix incorrect scaling for fallback fonts when the font has an
underscore that renders out of bounds (:iss:`1713`)
- macOS: Fix finding fallback font for private use unicode symbols not working
reliably (:iss:`1650`)
- Fix an out of bounds read causing a crash when selecting text with the mouse
in the alternate screen mode (:iss:`1578`)
- Linux: Use the system "bell" sound for the terminal bell. Adds libcanberra
as a new dependency to play the system sound.
- macOS: Fix a rare deadlock causing kitty to hang (:iss:`1779`)
- Linux: Fix a regression in 0.14.0 that caused the event loop to tick
continuously, wasting CPU even when idle (:iss:`1782`)
- ssh kitten: Make argument parsing more like ssh (:iss:`1787`)
- When using :opt:`strip_trailing_spaces` do not remove empty lines
(:iss:`1802`)
- Fix a crash when displaying very large number of images (:iss:`1825`)
0.14.2 [2019-06-09]
---------------------
- Add an option :opt:`placement_strategy` to control how the cell area is
aligned inside the window when the window size is not an exact multiple
of the cell size (:pull:`1670`)
- hints kitten: Add a :option:`kitty +kitten hints --multiple-joiner` option to
control how multiple selections are serialized when copying to clipboard
or inserting into the terminal. You can have them on separate lines,
separated by arbitrary characters, or even serialized as JSON (:iss:`1665`)
- macOS: Fix a regression in the previous release that broke using
:kbd:`ctrl+shift+tab` (:iss:`1671`)
- panel kitten: Fix the contents of the panel kitten not being positioned
correctly on the vertical axis
- icat kitten: Fix a regression that broke passing directories to icat
(:iss:`1683`)
- clipboard kitten: Add a :option:`kitty +kitten clipboard --wait-for-completion`
option to have the kitten wait till copying to clipboard is complete
(:iss:`1693`)
- Allow using the :doc:`pipe <pipe>` command to send screen and scrollback
contents directly to the clipboard (:iss:`1693`)
- Linux: Disable the Wayland backend on GNOME by default as GNOME has no
support for server side decorations. Can be controlled by
:opt:`linux_display_server`.
- Add an option to control the default :opt:`update_check_interval` when
building kitty packages
- Wayland: Fix resizing the window on a compositor that does not provide
server side window decorations, such a GNOME or Weston not working
correctly (:iss:`1659`)
- Wayland: Fix crash when enabling disabling monitors on sway (:iss:`1696`)
0.14.1 [2019-05-29]
---------------------
- Add an option :opt:`command_on_bell` to run an arbitrary command when
a bell occurs (:iss:`1660`)
- Add a shortcut to toggle maximized window state :sc:`toggle_maximized`
- Add support for the underscore key found in some keyboard layouts
(:iss:`1639`)
- Fix a missing newline when using the pipe command between the
scrollback and screen contents (:iss:`1642`)
- Fix colors not being preserved when using the pipe command with
the pager history buffer (:pull:`1657`)
- macOS: Fix a regression that could cause rendering of a kitty window
to occasionally freeze in certain situations, such as moving it between
monitors or transitioning from/to fullscreen (:iss:`1641`)
- macOS: Fix a regression that caused :kbd:`cmd+v` to double up in the dvorak
keyboard layout (:iss:`1652`)
- When resizing and only a single window is present in the current layout,
use that window's background color to fill in the blank areas.
- Linux: Automatically increase cell height if the font being used is broken
and draws the underscore outside the bounding box (:iss:`690`)
- Wayland: Fix maximizing the window on a compositor that does not provide
server side window decorations, such a GNOME or Weston not working
(:iss:`1662`)
0.14.0 [2019-05-24]
---------------------
@@ -60,7 +231,7 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
- macOS: Fix :kbd:`cmd+period` key not working (:iss:`1318`)
- macOS: Add an option :opt:`macos_show_window_title_in_menubar` to not
- macOS: Add an option `macos_show_window_title_in_menubar` to not
show the current window title in the menu-bar (:iss:`1066`)
- macOS: Workaround for cocoa bug that could cause the mouse cursor to become

View File

@@ -1,3 +1,4 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Configuration file for the Sphinx documentation builder.
@@ -11,6 +12,7 @@ import os
import re
import subprocess
import sys
import time
from functools import partial
from docutils import nodes
@@ -32,7 +34,7 @@ str_version = importlib.import_module('kitty.constants').str_version
# -- Project information -----------------------------------------------------
project = 'kitty'
copyright = '2018, Kovid Goyal'
copyright = time.strftime('%Y, Kovid Goyal')
author = 'Kovid Goyal'
building_man_pages = 'man' in sys.argv
@@ -274,6 +276,48 @@ def write_cli_docs(all_kitten_names):
# }}}
def write_remote_control_protocol_docs(): # {{{
from kitty.cmds import cmap
field_pat = re.compile(r'\s*([a-zA-Z0-9_+]+)\s*:\s*(.+)')
def format_cmd(p, name, cmd):
p(name)
p('-' * 80)
lines = cmd.__doc__.strip().splitlines()
fields = []
for line in lines:
m = field_pat.match(line)
if m is None:
p(line)
else:
fields.append((m.group(1), m.group(2)))
if fields:
p('\nFields are:\n')
for (name, desc) in fields:
if '+' in name:
title = name.replace('+', ' (required)')
else:
title = name
defval = cmd.get_default(name.replace('-', '_'), cmd)
if defval is not cmd:
title = f'{title} (default: {defval})'
else:
title = f'{title} (optional)'
p(f':code:`{title}`')
p(' ', desc), p()
p(), p()
with open(f'generated/rc.rst', 'w') as f:
p = partial(print, file=f)
for name in sorted(cmap):
cmd = cmap[name]
if not cmd.__doc__:
continue
name = name.replace('_', '-')
format_cmd(p, name, cmd)
# }}}
# config file docs {{{
class ConfLexer(RegexLexer):
@@ -481,9 +525,12 @@ def process_shortcut_link(env, refnode, has_explicit_title, title, target):
conf_name, slug = 'kitty', conf_name
full_name = conf_name + '.' + slug
try:
target, title = shortcut_slugs[full_name]
target, stitle = shortcut_slugs[full_name]
except KeyError:
logger.warning('Unknown shortcut: {}'.format(target), location=refnode)
else:
if not has_explicit_title:
title = stitle
return title, target
@@ -535,6 +582,7 @@ def setup(app):
from kittens.runner import all_kitten_names
all_kitten_names = all_kitten_names()
write_cli_docs(all_kitten_names)
write_remote_control_protocol_docs()
write_conf_docs(app, all_kitten_names)
app.add_lexer('session', SessionLexer())
app.add_role('link', link_role)

View File

@@ -103,6 +103,28 @@ for |kitty| and use :ref:`at_set-colors`.
A list of pre-made color themes for kitty is available at:
`kitty-themes <https://github.com/dexpota/kitty-themes>`_
Examples of using OSC escape codes to set colors::
Change the default foreground color:
printf '\x1b]10;#ff0000\x1b\\'
Change the default background color:
printf '\x1b]11;blue\x1b\\'
Change the cursor color:
printf '\x1b]12;blue\x1b\\'
Change the selection background color:
printf '\x1b]17;blue\x1b\\'
Change the selection foreground color:
printf '\x1b]19;blue\x1b\\'
Change the nth color (0 - 255):
printf '\x1b]4;n;green\x1b\\'
You can use various syntaxes/names for color specifications in the above
examples. See `XParseColor <https://linux.die.net/man/3/xparsecolor>`_
for full details.
If a ``?`` is given rather than a color specification, kitty will respond
with the current value for the specified color.
How do I specify command line options for kitty on macOS?
---------------------------------------------------------------
@@ -140,3 +162,31 @@ Bringing up applications on a single key press is the job of the window
manager/desktop environment. For ways to do it with kitty (or indeed any
terminal) in different environments,
see `here <https://github.com/kovidgoyal/kitty/issues/45>`_.
How do I map key presses in kitty to different keys in the terminal program?
--------------------------------------------------------------------------------------
This is accomplished by using ``map`` with :sc:`send_text <send_text>` in :file:`kitty.conf`.
For example::
map alt+s send_text all \x13
This maps :kbd:`alt+s`` to :kbd:`ctrl+s`. To figure out what bytes to use for
the :sc:`send_text <send_text>` you can use the ``showkey`` utility. Run::
showkey -a
Then press the key you want to emulate. On macOS, this utility is currently not
available. The manual way to figure it out is:
1. Look up your key's decimal value in the table at the bottom of `this
page <http://ascii-table.com/ansi-escape-sequences.php>`_ or any
ANSI escape sequence table. There are different modifiers for :kbd:`ctrl`,
:kbd:`alt`, etc. For e.g., for :kbd:`ctrl+s`, find the ``S`` row and look at
the third column value, ``19``.
2. Convert the decimal value to hex with ``kitty +runpy "print(hex(19))"``.
This shows the hex value, ``13`` in this case.
3. Use ``\x(hexval)`` in your ``send_text`` command in kitty. So in this example, ``\x13``

View File

@@ -107,7 +107,8 @@ features of the graphics protocol:
sys.stdout.flush()
cmd.clear()
write_chunked({'a': 'T', 'f': 100}, open(sys.argv[-1], 'rb').read())
with open(sys.argv[-1], 'rb') as f:
write_chunked({'a': 'T', 'f': 100}, f.read())
Save this script as :file:`png.py`, then you can use it to display any PNG
@@ -255,7 +256,10 @@ sequence of escape codes to the terminal emulator::
Note that only the first escape code needs to have the full set of control
codes such as width, height, format etc. Subsequent chunks must have
only the ``m`` key. The client **must** finish sending all chunks for a single image
before sending any other graphics related escape codes.
before sending any other graphics related escape codes. Note that the cursor
position used to display the image **must** be the position when the final chunk is
received. Finally, terminals must not display anything, until the entire sequence is
received and validated.
Detecting available transmission mediums

View File

@@ -60,6 +60,7 @@ You can also use your favorite package manager to install the |kitty| package.
|kitty| packages are available for:
`macOS with Homebrew (Cask) <https://formulae.brew.sh/cask/kitty>`_,
`macOS and Linux with Nix <https://nixos.org/nixos/packages.html#kitty>`_,
`Ubuntu <https://launchpad.net/ubuntu/+source/kitty>`_,
`Debian <https://packages.debian.org/buster/kitty>`_,
`openSUSE <https://build.opensuse.org/package/show/X11:terminals/kitty>`_,
`Arch Linux <https://www.archlinux.org/packages/community/x86_64/kitty/>`_,
@@ -186,6 +187,7 @@ Increase font size :sc:`increase_font_size` (also :kbd:`⌘++`
Decrease font size :sc:`decrease_font_size` (also :kbd:`⌘+-` on macOS)
Restore font size :sc:`reset_font_size` (also :kbd:`⌘+0` on macOS)
Toggle fullscreen :sc:`toggle_fullscreen` (also :kbd:`^+⌘+f` on macOS)
Toggle maximized :sc:`toggle_maximized`
Input unicode character :sc:`input_unicode_character`
Click URL using the keyboard :sc:`open_url`
Reset the terminal :sc:`reset_terminal`
@@ -366,6 +368,8 @@ Mouse features
columns.
* Selecting text automatically copies it to the primary clipboard (on
platforms with a primary clipboard).
* You can select text with kitty even when a terminal program has grabbed
the mouse by holding down the :kbd:`shift` key.
Font control
@@ -446,6 +450,14 @@ Add the following to your :file:`~/.bashrc`
source <(kitty + complete setup bash)
Older versions of bash (for example, v3.2) do not support
process substitution with the source command, in which
case you can try an alternative:
.. code-block:: sh
source /dev/stdin <<<"$(kitty + complete setup bash)"
zsh
~~~~~~~~~
@@ -484,3 +496,4 @@ See :doc:`changelog`.
*
kittens/*
generated/rc

View File

@@ -20,6 +20,10 @@ import tempfile
py3 = sys.version_info[0] > 2
is64bit = platform.architecture()[0] == '64bit'
is_macos = 'darwin' in sys.platform.lower()
if is_macos:
mac_ver = tuple(map(int, platform.mac_ver()[0].split('.')))
if mac_ver[:2] < (10, 12):
raise SystemExit('Your version of macOS is too old, at least 10.12 is required')
try:
__file__
@@ -225,7 +229,8 @@ def script_launch():
def update_intaller_wrapper():
# To run: python3 -c "import runpy; runpy.run_path('installer.py', run_name='update_wrapper')" installer.sh
src = open(__file__, 'rb').read().decode('utf-8')
with open(__file__, 'rb') as f:
src = f.read().decode('utf-8')
wrapper = sys.argv[-1]
with open(wrapper, 'r+b') as f:
raw = f.read().decode('utf-8')

View File

@@ -14,12 +14,12 @@ render loop to reduce CPU usage. See :ref:`conf-kitty-performance` for details.
See also the :opt:`sync_to_monitor` option to further decrease latency at the cost
of some `tearing <https://en.wikipedia.org/wiki/Screen_tearing>`_ while scrolling.
You can generate detailed per-function performance data using
`gperftools <https://github.com/gperftools/gperftools>`_. Build |kitty| with
`make profile` which will create an executable called `kitty-profile`. Run
that and perform the task you want to analyse, for example, scrolling a large
file with `less`. After you quit, function call statistics will be printed to
`stdout` and you can use tools like *kcachegrind* for more detailed analysis.
You can generate detailed per-function performance data using `gperftools
<https://github.com/gperftools/gperftools>`_. Build |kitty| with `make
profile`. Run kitty and perform the task you want to analyse, for example,
scrolling a large file with `less`. After you quit, function call statistics
will be printed to `stdout` and you can use tools like *kcachegrind* for more
detailed analysis.
Here are some CPU usage numbers for the task of scrolling a file continuously
in less. The CPU usage is for the terminal process and X together and is

View File

@@ -43,6 +43,10 @@ You can choose where to run the pipe program:
``tab``
A new window in a new tab
``clipboard, primary``
Copy the text directly to the clipboard. In this case the specified program
is not run, so use some dummy program name for it.
``none``
Run it in the background

29
docs/rc_protocol.rst Normal file
View File

@@ -0,0 +1,29 @@
Documentation for the kitty remote control protocol
======================================================
The kitty remote control protocol is a simple protocol that involves sending
data to kitty in the form of JSON. Any individual command of kitty has the
form::
<ESC>P@kitty-cmd<JSON object><ESC>\
Where ``<ESC>`` is the byte ``0x1b``. The JSON object has the form::
{
'cmd': "command name",
'version': "kitty version",
'no_response': Optional Boolean,
'payload': <Optional JSON object>,
}
The ``version`` above is a string of the form :code:`0.14.2`. If you are developing a
standalone client, use the kitty version that you are developing against. Using
a version greater than the version of the kitty instance you are talking to,
will cause a failure.
Set ``no_response`` to True if you don't want a response from kitty.
The optional payload is a JSON object that is specific to the actual command being sent.
The fields in the object for every command are documented below.
.. include:: generated/rc.rst

View File

@@ -134,5 +134,10 @@ still write to the pipes of any other program on the same computer and
therefore can control |kitty|. It can, however, be useful to block programs
running on other computers (for example, over ssh) or as other users.
Documentation for the remote control protocol
-----------------------------------------------
If you wish to develop your own client to talk to |kitty|, you
can use the :doc:`rc_protocol`.
.. include:: generated/cli-kitty-at.rst

View File

@@ -93,7 +93,7 @@ def generate(function_name, callback_name, report_name, keymap, command_class, i
report_cmd = cmd_for_report(report_name, keymap, type_map, payload_allowed)
if payload_allowed:
payload_after_value = "case ';': state = PAYLOAD; break;"
payload = payload = ', PAYLOAD'
payload = ', PAYLOAD'
parr = 'static uint8_t payload[4096];'
payload_case = f'''
case PAYLOAD: {{

View File

@@ -29,10 +29,12 @@ def get_data(fname, folder='UCD'):
bn = os.path.basename(url)
local = os.path.join('/tmp', bn)
if os.path.exists(local):
data = open(local, 'rb').read()
with open(local, 'rb') as f:
data = f.read()
else:
data = urlopen(url).read()
open(local, 'wb').write(data)
with open(local, 'wb') as f:
f.write(data)
for line in data.decode('utf-8').splitlines():
line = line.strip()
if line and not line.startswith('#'):
@@ -166,21 +168,20 @@ def write_case(spec, p):
@contextmanager
def create_header(path, include_data_types=True):
f = open(path, 'w')
p = partial(print, file=f)
p('// unicode data, built from the unicode standard on:', date.today())
p('// see gen-wcwidth.py')
if path.endswith('.h'):
p('#pragma once')
if include_data_types:
p('#include "data-types.h"\n')
p('START_ALLOW_CASE_RANGE')
p()
yield p
p()
if include_data_types:
p('END_ALLOW_CASE_RANGE')
f.close()
with open(path, 'w') as f:
p = partial(print, file=f)
p('// unicode data, built from the unicode standard on:', date.today())
p('// see gen-wcwidth.py')
if path.endswith('.h'):
p('#pragma once')
if include_data_types:
p('#include "data-types.h"\n')
p('START_ALLOW_CASE_RANGE')
p()
yield p
p()
if include_data_types:
p('END_ALLOW_CASE_RANGE')
def gen_emoji():
@@ -282,7 +283,9 @@ def gen_ucd():
p('combining_type mark_for_codepoint(char_type c) {')
rmap = codepoint_to_mark_map(p, mark_map)
p('}\n')
expected = int(re.search(r'^#define VS15 (\d+)', open('kitty/unicode-data.h').read(), re.M).group(1))
with open('kitty/unicode-data.h') as f:
unicode_data = f.read()
expected = int(re.search(r'^#define VS15 (\d+)', unicode_data, re.M).group(1))
if rmap[0xfe0e] != expected:
raise ValueError('The mark for 0xfe0e has changed, you have to update VS15 to {} and VS16 to {} in unicode-data.h'.format(
rmap[0xfe0e], rmap[0xfe0f]

View File

@@ -8,9 +8,11 @@ import shlex
import shutil
import subprocess
cmdline = (
'glad --profile core --out-path {dest} --api gl=3.3 --generator {generator} --spec gl'
' --extensions GL_ARB_texture_storage,GL_ARB_copy_image,GL_ARB_multisample,GL_ARB_robustness,GL_KHR_debug'
'glad --out-path {dest} --api gl:core=3.3 '
' --extensions GL_ARB_texture_storage,GL_ARB_copy_image,GL_ARB_multisample,GL_ARB_robustness,GL_KHR_debug '
'c --header-only --debug'
)
@@ -23,7 +25,7 @@ def regenerate():
clean('out')
subprocess.check_call(
shlex.split(cmdline.format(dest='out', generator='c-debug'))
shlex.split(cmdline.format(dest='out'))
)
@@ -32,33 +34,12 @@ def strip_trailing_whitespace(c):
def export():
c = open('out/src/glad.c', 'rb').read().decode('utf-8')
functions = []
with open('out/include/glad/gl.h', 'r', encoding='utf-8') as source:
data = source.read()
data = strip_trailing_whitespace(data)
def sub(m):
functions.append(m.group(2))
return m.group()
c = re.sub(r'^([A-Z0-9]+) glad_debug_([a-zA-Z0-9]+) = glad_debug_impl_\2;$', sub, c, flags=re.M)
switch = ['glad_debug_{0} = glad_{0}'.format(f) for f in functions]
c = c.replace('<glad/glad.h>', '"gl-wrapper.h"', 1)
c = '#pragma GCC diagnostic ignored "-Wpedantic"\n' + c
c += '''
int
init_glad(GLADloadproc load, int debug) {
int ret = gladLoadGLLoader(load);
if (ret && !debug) {
SUB;
}
return ret;
}'''.replace('SUB', ';\n '.join(switch), 1)
open('../kitty/gl-wrapper.c', 'w').write(strip_trailing_whitespace(c))
raw = open('out/include/glad/glad.h').read()
raw = raw.replace('<KHR/khrplatform.h>', '"khrplatform.h"')
raw += '\nint init_glad(GLADloadproc, int);\n'
open('../kitty/gl-wrapper.h', 'w').write(strip_trailing_whitespace(raw))
raw = open('out/include/KHR/khrplatform.h', 'rb').read().decode('utf-8')
open('../kitty/khrplatform.h', 'w').write(strip_trailing_whitespace(raw))
with open('../kitty/gl-wrapper.h', 'w', encoding='utf-8') as dest:
dest.write(data)
if __name__ == '__main__':

89
glfw/backend_utils.c vendored
View File

@@ -11,6 +11,8 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <float.h>
#include <time.h>
@@ -220,24 +222,90 @@ dispatchTimers(EventLoopData *eld) {
}
static void
drain_wakeup_fd(int fd, int events, void* data) {
drain_wakeup_fd(int fd, EventLoopData* eld) {
static char drain_buf[64];
while(read(fd, drain_buf, sizeof(drain_buf)) < 0 && errno == EINTR);
eld->wakeup_data_read = false;
while(true) {
ssize_t ret = read(fd, drain_buf, sizeof(drain_buf));
if (ret < 0) {
if (errno == EINTR) continue;
break;
}
if (ret > 0) { eld->wakeup_data_read = true; continue; }
break;
}
}
static void
mark_wakep_fd_ready(int fd UNUSED, int events UNUSED, void *data) {
((EventLoopData*)(data))->wakeup_fd_ready = true;
}
bool
initPollData(EventLoopData *eld, int display_fd) {
if (!addWatch(eld, "display", display_fd, POLLIN, 1, NULL, NULL)) return false;
#ifdef HAS_EVENT_FD
eld->wakeupFd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
if (eld->wakeupFd == -1) return false;
const int wakeup_fd = eld->wakeupFd;
#else
if (pipe2(eld->wakeupFds, O_CLOEXEC | O_NONBLOCK) != 0) return false;
const int wakeup_fd = eld->wakeupFds[0];
#endif
if (!addWatch(eld, "wakeup", wakeup_fd, POLLIN, 1, mark_wakep_fd_ready, eld)) return false;
return true;
}
void
initPollData(EventLoopData *eld, int wakeup_fd, int display_fd) {
addWatch(eld, "display", display_fd, POLLIN, 1, NULL, NULL);
addWatch(eld, "wakeup", wakeup_fd, POLLIN, 1, drain_wakeup_fd, NULL);
check_for_wakeup_events(EventLoopData *eld) {
#ifdef HAS_EVENT_FD
int fd = eld->wakeupFd;
#else
int fd = eld->wakeupFds[0];
#endif
drain_wakeup_fd(fd, eld);
}
void
wakeupEventLoop(EventLoopData *eld) {
#ifdef HAS_EVENT_FD
static const uint64_t value = 1;
while (write(eld->wakeupFd, &value, sizeof value) < 0 && (errno == EINTR || errno == EAGAIN));
#else
while (write(eld->wakeupFds[1], "w", 1) < 0 && (errno == EINTR || errno == EAGAIN));
#endif
}
#ifndef HAS_EVENT_FD
static inline void
closeFds(int *fds, size_t count) {
while(count--) {
if (*fds > 0) {
close(*fds);
*fds = -1;
}
fds++;
}
}
#endif
void
finalizePollData(EventLoopData *eld) {
#ifdef HAS_EVENT_FD
close(eld->wakeupFd); eld->wakeupFd = -1;
#else
closeFds(eld->wakeupFds, arraysz(eld->wakeupFds));
#endif
}
int
pollForEvents(EventLoopData *eld, double timeout) {
int read_ok = 0;
timeout = prepareForPoll(eld, timeout);
EVDBG("pollForEvents final timeout: %.3f", timeout);
int result;
double end_time = monotonic() + timeout;
eld->wakeup_fd_ready = false;
while(1) {
if (timeout >= 0) {
@@ -270,17 +338,6 @@ pollForEvents(EventLoopData *eld, double timeout) {
return read_ok;
}
void
closeFds(int *fds, size_t count) {
while(count--) {
if (*fds > 0) {
close(*fds);
*fds = -1;
}
fds++;
}
}
// Splits and translates a text/uri-list into separate file paths
// NOTE: This function destroys the provided string
//

23
glfw/backend_utils.h vendored
View File

@@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.3 Wayland - www.glfw.org
// GLFW 3.4 Wayland - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
//
@@ -29,6 +29,16 @@
#include <unistd.h>
#include <stdbool.h>
#ifdef __has_include
#if __has_include(<sys/eventfd.h>)
#define HAS_EVENT_FD
#include <sys/eventfd.h>
#endif
#else
#define HAS_EVENT_FD
#include <sys/eventfd.h>
#endif
typedef unsigned long long id_type;
typedef void(*watch_callback_func)(int, int, void*);
typedef void(*timer_callback_func)(id_type, void*);
@@ -56,13 +66,19 @@ typedef struct {
typedef struct {
struct pollfd fds[32];
#ifdef HAS_EVENT_FD
int wakeupFd;
#else
int wakeupFds[2];
#endif
bool wakeup_data_read, wakeup_fd_ready;
nfds_t watches_count, timers_count;
Watch watches[32];
Timer timers[128];
} EventLoopData;
void check_for_wakeup_events(EventLoopData *eld);
id_type addWatch(EventLoopData *eld, const char *name, int fd, int events, int enabled, watch_callback_func cb, void *cb_data);
void removeWatch(EventLoopData *eld, id_type watch_id);
void toggleWatch(EventLoopData *eld, id_type watch_id, int enabled);
@@ -75,6 +91,7 @@ double prepareForPoll(EventLoopData *eld, double timeout);
int pollWithTimeout(struct pollfd *fds, nfds_t nfds, double timeout);
int pollForEvents(EventLoopData *eld, double timeout);
unsigned dispatchTimers(EventLoopData *eld);
void closeFds(int *fds, size_t count);
void initPollData(EventLoopData *eld, int wakeup_fd, int display_fd);
void finalizePollData(EventLoopData *eld);
bool initPollData(EventLoopData *eld, int display_fd);
char** parseUriList(char* text, int* count);
void wakeupEventLoop(EventLoopData *eld);

View File

@@ -1,7 +1,7 @@
//========================================================================
// GLFW 3.3 macOS - www.glfw.org
// GLFW 3.4 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -23,9 +23,12 @@
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include "internal.h"
#include <sys/param.h> // For MAXPATHLEN
#include <pthread.h>
// Change to our application bundle's resources directory, if present
//
@@ -197,7 +200,7 @@ static void createKeyTables(void)
// Retrieve Unicode data for the current keyboard layout
//
static GLFWbool updateUnicodeDataNS(void)
static bool updateUnicodeDataNS(void)
{
if (_glfw.ns.inputSource)
{
@@ -214,7 +217,7 @@ static GLFWbool updateUnicodeDataNS(void)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to retrieve keyboard layout input source");
return GLFW_FALSE;
return false;
}
_glfw.ns.unicodeData =
@@ -224,15 +227,15 @@ static GLFWbool updateUnicodeDataNS(void)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to retrieve keyboard layout Unicode data");
return GLFW_FALSE;
return false;
}
return GLFW_TRUE;
return true;
}
// Load HIToolbox.framework and the TIS symbols we need from it
//
static GLFWbool initializeTIS(void)
static bool initializeTIS(void)
{
// This works only because Cocoa has already loaded it properly
_glfw.ns.tis.bundle =
@@ -241,19 +244,19 @@ static GLFWbool initializeTIS(void)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to load HIToolbox.framework");
return GLFW_FALSE;
return false;
}
CFStringRef* kPropertyUnicodeKeyLayoutData =
CFBundleGetDataPointerForName(_glfw.ns.tis.bundle,
CFSTR("kTISPropertyUnicodeKeyLayoutData"));
_glfw.ns.tis.CopyCurrentKeyboardLayoutInputSource =
*(void **)&_glfw.ns.tis.CopyCurrentKeyboardLayoutInputSource =
CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
CFSTR("TISCopyCurrentKeyboardLayoutInputSource"));
_glfw.ns.tis.GetInputSourceProperty =
*(void **)&_glfw.ns.tis.GetInputSourceProperty =
CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
CFSTR("TISGetInputSourceProperty"));
_glfw.ns.tis.GetKbdType =
*(void **)&_glfw.ns.tis.GetKbdType =
CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
CFSTR("LMGetKbdType"));
@@ -264,7 +267,7 @@ static GLFWbool initializeTIS(void)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to load TIS API symbols");
return GLFW_FALSE;
return false;
}
_glfw.ns.tis.kPropertyUnicodeKeyLayoutData =
@@ -280,14 +283,16 @@ static GLFWbool initializeTIS(void)
- (void)selectedKeyboardInputSourceChanged:(NSObject* )object
{
(void)object;
updateUnicodeDataNS();
}
- (void)doNothing:(id)object
{
(void)object;
}
@end // GLFWHelper
@end // GLFWHelper
@interface GLFWApplication : NSApplication
- (void)tick_callback;
@@ -307,24 +312,33 @@ static GLFWbool initializeTIS(void)
}
@end
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
static inline bool
is_ctrl_tab(NSEvent *event, NSEventModifierFlags modifierFlags) {
return event.keyCode == kVK_Tab && (modifierFlags == NSEventModifierFlagControl || modifierFlags == (
NSEventModifierFlagControl | NSEventModifierFlagShift));
if (
(modifierFlags == NSEventModifierFlagControl &&
[event.charactersIgnoringModifiers isEqualToString:@"\t"]) ||
(modifierFlags == (NSEventModifierFlagControl | NSEventModifierFlagShift) &&
[event.charactersIgnoringModifiers isEqualToString:@"\x19"])
) return true;
return false;
}
static inline bool
is_cmd_period(NSEvent *event, NSEventModifierFlags modifierFlags) {
return event.keyCode == kVK_ANSI_Period && modifierFlags == NSEventModifierFlagCommand;
if (modifierFlags != NSEventModifierFlagCommand) return false;
if ([event.charactersIgnoringModifiers isEqualToString:@"."]) return true;
return false;
}
int _glfwPlatformInit(void)
{
@autoreleasepool {
_glfw.ns.helper = [[GLFWHelper alloc] init];
[NSThread detachNewThreadSelector:@selector(doNothing:)
@@ -367,6 +381,7 @@ int _glfwPlatformInit(void)
_glfw.ns.keyDownMonitor =
[NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskKeyDown
handler:keydown_block];
if (_glfw.hints.init.ns.chdir)
changeToResourcesDirectory();
@@ -380,31 +395,27 @@ int _glfwPlatformInit(void)
_glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
if (!_glfw.ns.eventSource)
return GLFW_FALSE;
return false;
CGEventSourceSetLocalEventsSuppressionInterval(_glfw.ns.eventSource, 0.0);
if (!initializeTIS())
return GLFW_FALSE;
return false;
_glfw.ns.displayLinks.lock = [NSLock new];
_glfwInitTimerNS();
_glfwInitJoysticksNS();
_glfwPollMonitorsNS();
}
return GLFW_TRUE;
return true;
} // autoreleasepool
}
void _glfwPlatformTerminate(void)
{
@autoreleasepool {
if (_glfw.ns.displayLinks.lock) {
_glfwClearDisplayLinks();
[_glfw.ns.displayLinks.lock release];
_glfw.ns.displayLinks.lock = nil;
}
_glfwClearDisplayLinks();
if (_glfw.ns.inputSource)
{
@@ -437,6 +448,7 @@ void _glfwPlatformTerminate(void)
[_glfw.ns.helper release];
_glfw.ns.helper = nil;
}
if (_glfw.ns.keyUpMonitor)
[NSEvent removeMonitor:_glfw.ns.keyUpMonitor];
if (_glfw.ns.keyDownMonitor)
@@ -446,7 +458,8 @@ void _glfwPlatformTerminate(void)
_glfwTerminateNSGL();
_glfwTerminateJoysticksNS();
}
} // autoreleasepool
}
const char* _glfwPlatformGetVersionString(void)
@@ -461,32 +474,56 @@ const char* _glfwPlatformGetVersionString(void)
static GLFWtickcallback tick_callback = NULL;
static void* tick_callback_data = NULL;
static bool tick_callback_requested = false;
static pthread_t main_thread;
static NSLock *tick_lock = NULL;
void _glfwDispatchTickCallback() {
if (tick_callback) {
tick_callback_requested = false;
tick_callback(tick_callback_data);
if (tick_lock && tick_callback) {
[tick_lock lock];
while(tick_callback_requested) {
tick_callback_requested = false;
tick_callback(tick_callback_data);
}
[tick_lock unlock];
}
}
void _glfwPlatformRequestTickCallback() {
static void
request_tick_callback() {
if (!tick_callback_requested) {
tick_callback_requested = true;
[NSApp performSelectorOnMainThread:@selector(tick_callback) withObject:nil waitUntilDone:NO];
}
}
void _glfwPlatformPostEmptyEvent(void)
{
if (pthread_equal(pthread_self(), main_thread)) {
request_tick_callback();
} else if (tick_lock) {
[tick_lock lock];
request_tick_callback();
[tick_lock unlock];
}
}
void _glfwPlatformStopMainLoop(void) {
tick_callback = NULL;
[NSApp stop:nil];
_glfwPlatformPostEmptyEvent();
_glfwCocoaPostEmptyEvent();
}
void _glfwPlatformRunMainLoop(GLFWtickcallback callback, void* data) {
main_thread = pthread_self();
tick_callback = callback;
tick_callback_data = data;
tick_lock = [NSLock new];
[NSApp run];
[tick_lock release];
tick_lock = NULL;
tick_callback = NULL;
tick_callback_data = NULL;
}
@@ -509,10 +546,7 @@ remove_timer_at(size_t idx) {
Timer *t = timers + idx;
if (t->os_timer) { [t->os_timer invalidate]; t->os_timer = NULL; }
if (t->callback_data && t->free_callback_data) { t->free_callback_data(t->id, t->callback_data); t->callback_data = NULL; }
num_timers--;
if (idx < num_timers) {
memmove(timers + idx, timers + idx + 1, sizeof(timers[0]) * (num_timers - idx));
}
remove_i_from_array(timers, idx, num_timers);
}
}
@@ -554,7 +588,7 @@ void _glfwPlatformRemoveTimer(unsigned long long timer_id) {
}
}
void _glfwPlatformUpdateTimer(unsigned long long timer_id, double interval, GLFWbool enabled) {
void _glfwPlatformUpdateTimer(unsigned long long timer_id, double interval, bool enabled) {
for (size_t i = 0; i < num_timers; i++) {
if (timers[i].id == timer_id) {
Timer *t = timers + i;

View File

@@ -1,7 +1,7 @@
//========================================================================
// GLFW 3.3 Cocoa - www.glfw.org
// GLFW 3.4 Cocoa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages

View File

@@ -1,7 +1,7 @@
//========================================================================
// GLFW 3.3 Cocoa - www.glfw.org
// GLFW 3.4 Cocoa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net>
//
// This software is provided 'as-is', without any express or implied
@@ -24,6 +24,8 @@
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include "internal.h"
@@ -75,7 +77,7 @@ static long getElementValue(_GLFWjoystick* js, _GLFWjoyelementNS* element)
//
static CFComparisonResult compareElements(const void* fp,
const void* sp,
void* user)
void* user UNUSED)
{
const _GLFWjoyelementNS* fe = fp;
const _GLFWjoyelementNS* se = sp;
@@ -117,9 +119,9 @@ static void closeJoystick(_GLFWjoystick* js)
// Callback for user-initiated joystick addition
//
static void matchCallback(void* context,
IOReturn result,
void* sender,
static void matchCallback(void* context UNUSED,
IOReturn result UNUSED,
void* sender UNUSED,
IOHIDDeviceRef device)
{
int jid;
@@ -270,9 +272,9 @@ static void matchCallback(void* context,
// Callback for user-initiated joystick removal
//
static void removeCallback(void* context,
IOReturn result,
void* sender,
static void removeCallback(void* context UNUSED,
IOReturn result UNUSED,
void* sender UNUSED,
IOHIDDeviceRef device)
{
int jid;
@@ -316,7 +318,7 @@ void _glfwInitJoysticksNS(void)
return;
}
for (int i = 0; i < sizeof(usages) / sizeof(long); i++)
for (size_t i = 0; i < sizeof(usages) / sizeof(long); i++)
{
const long page = kHIDPage_GenericDesktop;

View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 macOS - www.glfw.org
// GLFW 3.4 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -24,6 +24,8 @@
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include "internal.h"
@@ -116,16 +118,16 @@ static char* getDisplayName(CGDirectDisplayID displayID)
// Check whether the display mode should be included in enumeration
//
static GLFWbool modeIsGood(CGDisplayModeRef mode)
static bool modeIsGood(CGDisplayModeRef mode)
{
uint32_t flags = CGDisplayModeGetIOFlags(mode);
if (!(flags & kDisplayModeValidFlag) || !(flags & kDisplayModeSafeFlag))
return GLFW_FALSE;
return false;
if (flags & kDisplayModeInterlacedFlag)
return GLFW_FALSE;
return false;
if (flags & kDisplayModeStretchedFlag)
return GLFW_FALSE;
return false;
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
@@ -133,12 +135,12 @@ static GLFWbool modeIsGood(CGDisplayModeRef mode)
CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0))
{
CFRelease(format);
return GLFW_FALSE;
return false;
}
CFRelease(format);
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
return GLFW_TRUE;
return true;
}
// Convert Core Graphics display mode to GLFW video mode
@@ -215,12 +217,12 @@ static void endFadeReservation(CGDisplayFadeReservationToken token)
// Finds and caches the NSScreen corresponding to the specified monitor
//
GLFWbool refreshMonitorScreen(_GLFWmonitor* monitor)
static bool refreshMonitorScreen(_GLFWmonitor* monitor)
{
if (monitor->ns.screen)
return GLFW_TRUE;
return true;
for (NSScreen* screen in [NSScreen screens])
for (NSScreen* screen in [NSScreen screens])
{
NSNumber* displayID = [screen deviceDescription][@"NSScreenNumber"];
@@ -230,12 +232,12 @@ GLFWbool refreshMonitorScreen(_GLFWmonitor* monitor)
if (monitor->ns.unitNumber == CGDisplayUnitNumber([displayID unsignedIntValue]))
{
monitor->ns.screen = screen;
return GLFW_TRUE;
return true;
}
}
_glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to find a screen for monitor");
return GLFW_FALSE;
_glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to find a screen for monitor");
return false;
}
//////////////////////////////////////////////////////////////////////////
@@ -243,49 +245,30 @@ GLFWbool refreshMonitorScreen(_GLFWmonitor* monitor)
//////////////////////////////////////////////////////////////////////////
void _glfwClearDisplayLinks() {
[_glfw.ns.displayLinks.lock lock];
for (size_t i = 0; i < _glfw.ns.displayLinks.count; i++) {
if (_glfw.ns.displayLinks.entries[i].displayLinkStarted) {
CVDisplayLinkStop(_glfw.ns.displayLinks.entries[i].displayLink);
_glfw.ns.displayLinks.entries[i].displayLinkStarted = GLFW_FALSE;
}
if (_glfw.ns.displayLinks.entries[i].displayLink) {
CVDisplayLinkStop(_glfw.ns.displayLinks.entries[i].displayLink);
CVDisplayLinkRelease(_glfw.ns.displayLinks.entries[i].displayLink);
_glfw.ns.displayLinks.entries[i].displayLink = nil;
_glfw.ns.displayLinks.entries[i].lastRenderFrameRequestedAt = 0;
}
}
_glfw.ns.displayLinks.count = 0;
[_glfw.ns.displayLinks.lock unlock];
}
static CVReturn displayLinkCallback(
CVDisplayLinkRef displayLink,
const CVTimeStamp* now, const CVTimeStamp* outputTime,
CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* userInfo)
CVDisplayLinkRef displayLink UNUSED,
const CVTimeStamp* now UNUSED, const CVTimeStamp* outputTime UNUSED,
CVOptionFlags flagsIn UNUSED, CVOptionFlags* flagsOut UNUSED, void* userInfo)
{
CGDirectDisplayID displayID = (CGDirectDisplayID)userInfo;
[_glfw.ns.displayLinks.lock lock];
GLFWbool notify = GLFW_FALSE;
for (size_t i = 0; i < _glfw.ns.displayLinks.count; i++) {
if (_glfw.ns.displayLinks.entries[i].displayID == displayID) {
if (_glfw.ns.displayLinks.entries[i].renderFrameRequested) {
notify = GLFW_TRUE;
_glfw.ns.displayLinks.entries[i].renderFrameRequested = GLFW_FALSE;
}
break;
}
}
[_glfw.ns.displayLinks.lock unlock];
if (notify) {
NSNumber *arg = [NSNumber numberWithUnsignedInt:displayID];
[NSApp performSelectorOnMainThread:@selector(render_frame_received:) withObject:arg waitUntilDone:NO];
[arg release];
}
NSNumber *arg = [NSNumber numberWithUnsignedInt:displayID];
[NSApp performSelectorOnMainThread:@selector(render_frame_received:) withObject:arg waitUntilDone:NO];
[arg release];
return kCVReturnSuccess;
}
static inline void createDisplayLink(CGDirectDisplayID displayID) {
[_glfw.ns.displayLinks.lock lock];
if (_glfw.ns.displayLinks.count >= sizeof(_glfw.ns.displayLinks.entries)/sizeof(_glfw.ns.displayLinks.entries[0]) - 1) return;
for (size_t i = 0; i < _glfw.ns.displayLinks.count; i++) {
if (_glfw.ns.displayLinks.entries[i].displayID == displayID) return;
@@ -295,26 +278,24 @@ static inline void createDisplayLink(CGDirectDisplayID displayID) {
entry->displayID = displayID;
CVDisplayLinkCreateWithCGDisplay(displayID, &entry->displayLink);
CVDisplayLinkSetOutputCallback(entry->displayLink, &displayLinkCallback, (void*)(uintptr_t)displayID);
[_glfw.ns.displayLinks.lock unlock];
}
// Poll for changes in the set of connected monitors
//
void _glfwPollMonitorsNS(void)
{
uint32_t i, j, displayCount, disconnectedCount;
CGDirectDisplayID* displays;
_GLFWmonitor** disconnected = NULL;
uint32_t displayCount;
CGGetOnlineDisplayList(0, NULL, &displayCount);
displays = calloc(displayCount, sizeof(CGDirectDisplayID));
CGDirectDisplayID* displays = calloc(displayCount, sizeof(CGDirectDisplayID));
CGGetOnlineDisplayList(displayCount, displays, &displayCount);
_glfwClearDisplayLinks();
for (i = 0; i < _glfw.monitorCount; i++)
for (int i = 0; i < _glfw.monitorCount; i++)
_glfw.monitors[i]->ns.screen = nil;
disconnectedCount = _glfw.monitorCount;
_GLFWmonitor** disconnected = NULL;
uint32_t disconnectedCount = _glfw.monitorCount;
if (disconnectedCount)
{
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
@@ -323,19 +304,18 @@ void _glfwPollMonitorsNS(void)
_glfw.monitorCount * sizeof(_GLFWmonitor*));
}
for (i = 0; i < displayCount; i++)
for (uint32_t i = 0; i < displayCount; i++)
{
_GLFWmonitor* monitor;
const uint32_t unitNumber = CGDisplayUnitNumber(displays[i]);
if (CGDisplayIsAsleep(displays[i]))
continue;
for (j = 0; j < disconnectedCount; j++)
// HACK: Compare unit numbers instead of display IDs to work around
// display replacement on machines with automatic graphics
// switching
const uint32_t unitNumber = CGDisplayUnitNumber(displays[i]);
for (uint32_t j = 0; j < disconnectedCount; j++)
{
// HACK: Compare unit numbers instead of display IDs to work around
// display replacement on machines with automatic graphics
// switching
if (disconnected[j] && disconnected[j]->ns.unitNumber == unitNumber)
{
disconnected[j] = NULL;
@@ -348,7 +328,7 @@ void _glfwPollMonitorsNS(void)
if (!name)
name = _glfw_strdup("Unknown");
monitor = _glfwAllocMonitor(name, size.width, size.height);
_GLFWmonitor* monitor = _glfwAllocMonitor(name, size.width, size.height);
monitor->ns.displayID = displays[i];
monitor->ns.unitNumber = unitNumber;
createDisplayLink(monitor->ns.displayID);
@@ -358,7 +338,7 @@ void _glfwPollMonitorsNS(void)
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
}
for (i = 0; i < disconnectedCount; i++)
for (uint32_t i = 0; i < disconnectedCount; i++)
{
if (disconnected[i])
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
@@ -366,30 +346,27 @@ void _glfwPollMonitorsNS(void)
free(disconnected);
free(displays);
_glfwRestartDisplayLinks();
}
// Change the current video mode
//
void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired)
{
CFArrayRef modes;
CFIndex count, i;
CVDisplayLinkRef link;
CGDisplayModeRef native = NULL;
GLFWvidmode current;
const GLFWvidmode* best;
best = _glfwChooseVideoMode(monitor, desired);
const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired);
_glfwPlatformGetVideoMode(monitor, &current);
if (_glfwCompareVideoModes(&current, best) == 0)
return;
CVDisplayLinkRef link;
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
count = CFArrayGetCount(modes);
CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
const CFIndex count = CFArrayGetCount(modes);
CGDisplayModeRef native = NULL;
for (i = 0; i < count; i++)
for (CFIndex i = 0; i < count; i++)
{
CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
if (!modeIsGood(dm))
@@ -438,7 +415,7 @@ void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor)
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor UNUSED)
{
}
@@ -467,7 +444,9 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
*yscale = (float) (pixels.size.height / points.size.height);
}
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height)
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
int* xpos, int* ypos,
int* width, int* height)
{
if (!refreshMonitorScreen(monitor))
return;
@@ -487,20 +466,16 @@ void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
{
CFArrayRef modes;
CFIndex found, i, j;
GLFWvidmode* result;
CVDisplayLinkRef link;
*count = 0;
CVDisplayLinkRef link;
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
found = CFArrayGetCount(modes);
result = calloc(found, sizeof(GLFWvidmode));
CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
const CFIndex found = CFArrayGetCount(modes);
GLFWvidmode* result = calloc(found, sizeof(GLFWvidmode));
for (i = 0; i < found; i++)
for (CFIndex i = 0; i < found; i++)
{
CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
if (!modeIsGood(dm))
@@ -508,7 +483,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
const GLFWvidmode mode = vidmodeFromCGDisplayMode(dm, link);
for (j = 0; j < *count; j++)
for (CFIndex j = 0; j < *count; j++)
{
if (_glfwCompareVideoModes(result + j, &mode) == 0)
break;
@@ -529,21 +504,20 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode)
{
CGDisplayModeRef displayMode;
CVDisplayLinkRef link;
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
displayMode = CGDisplayCopyDisplayMode(monitor->ns.displayID);
*mode = vidmodeFromCGDisplayMode(displayMode, link);
CGDisplayModeRelease(displayMode);
CGDisplayModeRef native = CGDisplayCopyDisplayMode(monitor->ns.displayID);
*mode = vidmodeFromCGDisplayMode(native, link);
CGDisplayModeRelease(native);
CVDisplayLinkRelease(link);
}
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{
uint32_t i, size = CGDisplayGammaTableCapacity(monitor->ns.displayID);
uint32_t size = CGDisplayGammaTableCapacity(monitor->ns.displayID);
CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue));
CGGetDisplayTransferByTable(monitor->ns.displayID,
@@ -555,7 +529,7 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
_glfwAllocGammaArrays(ramp, size);
for (i = 0; i < size; i++)
for (uint32_t i = 0; i < size; i++)
{
ramp->red[i] = (unsigned short) (values[i] * 65535);
ramp->green[i] = (unsigned short) (values[i + size] * 65535);
@@ -563,15 +537,14 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
}
free(values);
return GLFW_TRUE;
return true;
}
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{
int i;
CGGammaValue* values = calloc(ramp->size * 3, sizeof(CGGammaValue));
for (i = 0; i < ramp->size; i++)
for (unsigned int i = 0; i < ramp->size; i++)
{
values[i] = ramp->red[i] / 65535.f;
values[i + ramp->size] = ramp->green[i] / 65535.f;

22
glfw/cocoa_platform.h vendored
View File

@@ -1,7 +1,7 @@
//========================================================================
// GLFW 3.3 macOS - www.glfw.org
// GLFW 3.4 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -116,8 +116,8 @@ typedef struct _GLFWwindowNS
id view;
id layer;
GLFWbool maximized;
GLFWbool retina;
bool maximized;
bool retina;
// Cached window properties to filter out duplicate events
int width, height;
@@ -136,7 +136,7 @@ typedef struct _GLFWwindowNS
// Dead key state
UInt32 deadKeyState;
// Whether a render frame has been requested for this window
GLFWbool renderFrameRequested;
bool renderFrameRequested;
GLFWcocoarenderframefun renderFrameCallback;
} _GLFWwindowNS;
@@ -144,8 +144,7 @@ typedef struct _GLFWDisplayLinkNS
{
CVDisplayLinkRef displayLink;
CGDirectDisplayID displayID;
GLFWbool displayLinkStarted;
GLFWbool renderFrameRequested;
double lastRenderFrameRequestedAt;
} _GLFWDisplayLinkNS;
// Cocoa-specific global data
@@ -154,7 +153,7 @@ typedef struct _GLFWlibraryNS
{
CGEventSourceRef eventSource;
id delegate;
GLFWbool cursorHidden;
bool cursorHidden;
TISInputSourceRef inputSource;
IOHIDManagerRef hidManager;
id unicodeData;
@@ -184,7 +183,6 @@ typedef struct _GLFWlibraryNS
struct {
_GLFWDisplayLinkNS entries[256];
size_t count;
id lock;
} displayLinks;
} _GLFWlibraryNS;
@@ -222,8 +220,12 @@ void _glfwInitTimerNS(void);
void _glfwPollMonitorsNS(void);
void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired);
void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor);
float _glfwTransformYNS(float y);
void _glfwClearDisplayLinks(void);
void _glfwCocoaPostEmptyEvent(short subtype, long data1, bool at_start);
void _glfwRestartDisplayLinks(void);
void _glfwDispatchTickCallback(void);
void _glfwDispatchRenderFrame(CGDirectDisplayID);
void _glfwShutdownCVDisplayLink(unsigned long long, void*);
void _glfwCocoaPostEmptyEvent(void);

4
glfw/cocoa_time.c vendored
View File

@@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.3 macOS - www.glfw.org
// GLFW 3.4 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
//
@@ -23,6 +23,8 @@
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include "internal.h"

File diff suppressed because it is too large Load Diff

70
glfw/context.c vendored
View File

@@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.3 - www.glfw.org
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
@@ -24,6 +24,8 @@
// distribution.
//
//========================================================================
// Please use C89 style variable declarations in this file because VS 2010
//========================================================================
#include "internal.h"
@@ -44,7 +46,7 @@
// exists and whether all relevant options have supported and non-conflicting
// values
//
GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
bool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
{
if (ctxconfig->share)
{
@@ -52,7 +54,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
ctxconfig->share->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return GLFW_FALSE;
return false;
}
}
@@ -63,7 +65,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid context creation API 0x%08X",
ctxconfig->source);
return GLFW_FALSE;
return false;
}
if (ctxconfig->client != GLFW_NO_API &&
@@ -73,7 +75,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid client API 0x%08X",
ctxconfig->client);
return GLFW_FALSE;
return false;
}
if (ctxconfig->client == GLFW_OPENGL_API)
@@ -92,7 +94,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid OpenGL version %i.%i",
ctxconfig->major, ctxconfig->minor);
return GLFW_FALSE;
return false;
}
if (ctxconfig->profile)
@@ -103,7 +105,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid OpenGL profile 0x%08X",
ctxconfig->profile);
return GLFW_FALSE;
return false;
}
if (ctxconfig->major <= 2 ||
@@ -114,7 +116,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
_glfwInputError(GLFW_INVALID_VALUE,
"Context profiles are only defined for OpenGL version 3.2 and above");
return GLFW_FALSE;
return false;
}
}
@@ -123,7 +125,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
// Forward-compatible contexts are only defined for OpenGL version 3.0 and above
_glfwInputError(GLFW_INVALID_VALUE,
"Forward-compatibility is only defined for OpenGL version 3.0 and above");
return GLFW_FALSE;
return false;
}
}
else if (ctxconfig->client == GLFW_OPENGL_ES_API)
@@ -140,7 +142,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid OpenGL ES version %i.%i",
ctxconfig->major, ctxconfig->minor);
return GLFW_FALSE;
return false;
}
}
@@ -152,7 +154,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid context robustness mode 0x%08X",
ctxconfig->robustness);
return GLFW_FALSE;
return false;
}
}
@@ -164,11 +166,11 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid context release behavior 0x%08X",
ctxconfig->release);
return GLFW_FALSE;
return false;
}
}
return GLFW_TRUE;
return true;
}
// Chooses the framebuffer config that best matches the desired one
@@ -341,7 +343,7 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
// Retrieves the attributes of the current context
//
GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
bool _glfwRefreshContextAttribs(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig)
{
int i;
@@ -369,7 +371,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
{
_glfwInputError(GLFW_PLATFORM_ERROR, "Entry point retrieval is broken");
glfwMakeContextCurrent((GLFWwindow*) previous);
return GLFW_FALSE;
return false;
}
version = (const char*) window->context.GetString(GL_VERSION);
@@ -387,7 +389,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
}
glfwMakeContextCurrent((GLFWwindow*) previous);
return GLFW_FALSE;
return false;
}
for (i = 0; prefixes[i]; i++)
@@ -419,7 +421,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
}
glfwMakeContextCurrent((GLFWwindow*) previous);
return GLFW_FALSE;
return false;
}
if (window->context.major < ctxconfig->major ||
@@ -449,7 +451,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
}
glfwMakeContextCurrent((GLFWwindow*) previous);
return GLFW_FALSE;
return false;
}
if (window->context.major >= 3)
@@ -465,7 +467,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
_glfwInputError(GLFW_PLATFORM_ERROR,
"Entry point retrieval is broken");
glfwMakeContextCurrent((GLFWwindow*) previous);
return GLFW_FALSE;
return false;
}
}
@@ -478,21 +480,21 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
window->context.GetIntegerv(GL_CONTEXT_FLAGS, &flags);
if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
window->context.forward = GLFW_TRUE;
window->context.forward = true;
if (flags & GL_CONTEXT_FLAG_DEBUG_BIT)
window->context.debug = GLFW_TRUE;
window->context.debug = true;
else if (glfwExtensionSupported("GL_ARB_debug_output") &&
ctxconfig->debug)
{
// HACK: This is a workaround for older drivers (pre KHR_debug)
// not setting the debug bit in the context flags for
// debug contexts
window->context.debug = GLFW_TRUE;
window->context.debug = true;
}
if (flags & GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR)
window->context.noerror = GLFW_TRUE;
window->context.noerror = true;
}
// Read back OpenGL context profile (OpenGL 3.2 and above)
@@ -572,12 +574,12 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
}
glfwMakeContextCurrent((GLFWwindow*) previous);
return GLFW_TRUE;
return true;
}
// Searches an extension string for the specified extension
//
GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions)
bool _glfwStringInExtensionString(const char* string, const char* extensions)
{
const char* start = extensions;
@@ -588,7 +590,7 @@ GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions
where = strstr(start, string);
if (!where)
return GLFW_FALSE;
return false;
terminator = where + strlen(string);
if (where == start || *(where - 1) == ' ')
@@ -600,7 +602,7 @@ GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions
start = terminator;
}
return GLFW_TRUE;
return true;
}
@@ -677,20 +679,20 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
_GLFWwindow* window;
assert(extension != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
_GLFW_REQUIRE_INIT_OR_RETURN(false);
window = _glfwPlatformGetTls(&_glfw.contextSlot);
if (!window)
{
_glfwInputError(GLFW_NO_CURRENT_CONTEXT,
"Cannot query extension without a current OpenGL or OpenGL ES context");
return GLFW_FALSE;
return false;
}
if (*extension == '\0')
{
_glfwInputError(GLFW_INVALID_VALUE, "Extension name cannot be an empty string");
return GLFW_FALSE;
return false;
}
if (window->context.major >= 3)
@@ -710,11 +712,11 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Extension string retrieval is broken");
return GLFW_FALSE;
return false;
}
if (strcmp(en, extension) == 0)
return GLFW_TRUE;
return true;
}
}
else
@@ -727,11 +729,11 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Extension string retrieval is broken");
return GLFW_FALSE;
return false;
}
if (_glfwStringInExtensionString(extension, extensions))
return GLFW_TRUE;
return true;
}
// Check if extension is in the platform-specific string

52
glfw/dbus_glfw.c vendored
View File

@@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.3 XKB - www.glfw.org
// GLFW 3.4 XKB - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2018 Kovid Goyal <kovid@kovidgoyal.net>
//
@@ -45,15 +45,15 @@ report_error(DBusError *err, const char *fmt, ...) {
static _GLFWDBUSData *dbus_data = NULL;
static DBusConnection *session_bus = NULL;
GLFWbool
bool
glfw_dbus_init(_GLFWDBUSData *dbus, EventLoopData *eld) {
dbus->eld = eld;
dbus_data = dbus;
return GLFW_TRUE;
return true;
}
static void
on_dbus_watch_ready(int fd, int events, void *data) {
on_dbus_watch_ready(int fd UNUSED, int events, void *data) {
DBusWatch *watch = (DBusWatch*)data;
unsigned int flags = 0;
if (events & POLLERR) flags |= DBUS_WATCH_ERROR;
@@ -84,19 +84,19 @@ add_dbus_watch(DBusWatch *watch, void *data) {
}
static void
remove_dbus_watch(DBusWatch *watch, void *data) {
remove_dbus_watch(DBusWatch *watch, void *data UNUSED) {
id_type *idp = dbus_watch_get_data(watch);
if (idp) removeWatch(dbus_data->eld, *idp);
}
static void
toggle_dbus_watch(DBusWatch *watch, void *data) {
toggle_dbus_watch(DBusWatch *watch, void *data UNUSED) {
id_type *idp = dbus_watch_get_data(watch);
if (idp) toggleWatch(dbus_data->eld, *idp, dbus_watch_get_enabled(watch));
}
static void
on_dbus_timer_ready(id_type timer_id, void *data) {
on_dbus_timer_ready(id_type timer_id UNUSED, void *data) {
if (data) {
DBusTimeout *t = (DBusTimeout*)data;
dbus_timeout_handle(t);
@@ -123,20 +123,20 @@ add_dbus_timeout(DBusTimeout *timeout, void *data) {
}
static void
remove_dbus_timeout(DBusTimeout *timeout, void *data) {
remove_dbus_timeout(DBusTimeout *timeout, void *data UNUSED) {
id_type *idp = dbus_timeout_get_data(timeout);
if (idp) removeTimer(dbus_data->eld, *idp);
}
static void
toggle_dbus_timeout(DBusTimeout *timeout, void *data) {
toggle_dbus_timeout(DBusTimeout *timeout, void *data UNUSED) {
id_type *idp = dbus_timeout_get_data(timeout);
if (idp) toggleTimer(dbus_data->eld, *idp, dbus_timeout_get_enabled(timeout));
}
DBusConnection*
glfw_dbus_connect_to(const char *path, const char* err_msg, const char *name, GLFWbool register_on_bus) {
glfw_dbus_connect_to(const char *path, const char* err_msg, const char *name, bool register_on_bus) {
DBusError err;
dbus_error_init(&err);
DBusConnection *ans = dbus_connection_open_private(path, &err);
@@ -178,7 +178,7 @@ glfw_dbus_session_bus_dispatch() {
}
void
glfw_dbus_terminate(_GLFWDBUSData *dbus) {
glfw_dbus_terminate(_GLFWDBUSData *dbus UNUSED) {
if (dbus_data) {
dbus_data->eld = NULL;
dbus_data = NULL;
@@ -195,14 +195,14 @@ glfw_dbus_close_connection(DBusConnection *conn) {
dbus_connection_unref(conn);
}
GLFWbool
bool
glfw_dbus_get_args(DBusMessage *msg, const char *failmsg, ...) {
DBusError err;
dbus_error_init(&err);
va_list ap;
va_start(ap, failmsg);
int firstarg = va_arg(ap, int);
GLFWbool ret = dbus_message_get_args_valist(msg, &err, firstarg, ap) ? GLFW_TRUE : GLFW_FALSE;
bool ret = dbus_message_get_args_valist(msg, &err, firstarg, ap) ? true : false;
va_end(ap);
if (!ret) report_error(&err, failmsg);
return ret;
@@ -233,25 +233,25 @@ method_reply_received(DBusPendingCall *pending, void *user_data) {
}
}
GLFWbool
bool
call_method_with_msg(DBusConnection *conn, DBusMessage *msg, int timeout, dbus_pending_callback callback, void *user_data) {
GLFWbool retval = GLFW_FALSE;
bool retval = false;
#define REPORT(errs) _glfwInputError(GLFW_PLATFORM_ERROR, "Failed to call DBUS method: node=%s path=%s interface=%s method=%s, with error: %s", dbus_message_get_destination(msg), dbus_message_get_path(msg), dbus_message_get_interface(msg), dbus_message_get_member(msg), errs)
if (callback) {
DBusPendingCall *pending = NULL;
if (dbus_connection_send_with_reply(conn, msg, &pending, timeout)) {
MethodResponse *res = malloc(sizeof(MethodResponse));
if (!res) return GLFW_FALSE;
if (!res) return false;
res->callback = callback;
res->user_data = user_data;
dbus_pending_call_set_notify(pending, method_reply_received, res, free);
retval = GLFW_TRUE;
retval = true;
} else {
REPORT("out of memory");
}
} else {
if (dbus_connection_send(conn, msg, NULL)) {
retval = GLFW_TRUE;
retval = true;
} else {
REPORT("out of memory");
}
@@ -260,12 +260,12 @@ call_method_with_msg(DBusConnection *conn, DBusMessage *msg, int timeout, dbus_p
#undef REPORT
}
static GLFWbool
static bool
call_method(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, int timeout, dbus_pending_callback callback, void *user_data, va_list ap) {
if (!conn) return GLFW_FALSE;
if (!conn) return false;
DBusMessage *msg = dbus_message_new_method_call(node, path, interface, method);
if (!msg) return GLFW_FALSE;
GLFWbool retval = GLFW_FALSE;
if (!msg) return false;
bool retval = false;
int firstarg = va_arg(ap, int);
if ((firstarg == DBUS_TYPE_INVALID) || dbus_message_append_args_valist(msg, firstarg, ap)) {
@@ -278,9 +278,9 @@ call_method(DBusConnection *conn, const char *node, const char *path, const char
return retval;
}
GLFWbool
bool
glfw_dbus_call_method_with_reply(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, int timeout, dbus_pending_callback callback, void* user_data, ...) {
GLFWbool retval;
bool retval;
va_list ap;
va_start(ap, user_data);
retval = call_method(conn, node, path, interface, method, timeout, callback, user_data, ap);
@@ -288,9 +288,9 @@ glfw_dbus_call_method_with_reply(DBusConnection *conn, const char *node, const c
return retval;
}
GLFWbool
bool
glfw_dbus_call_method_no_reply(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...) {
GLFWbool retval;
bool retval;
va_list ap;
va_start(ap, method);
retval = call_method(conn, node, path, interface, method, DBUS_TIMEOUT_USE_DEFAULT, NULL, NULL, ap);

14
glfw/dbus_glfw.h vendored
View File

@@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.3 XKB - www.glfw.org
// GLFW 3.4 XKB - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2018 Kovid Goyal <kovid@kovidgoyal.net>
//
@@ -37,18 +37,18 @@ typedef struct {
} _GLFWDBUSData;
GLFWbool glfw_dbus_init(_GLFWDBUSData *dbus, EventLoopData *eld);
bool glfw_dbus_init(_GLFWDBUSData *dbus, EventLoopData *eld);
void glfw_dbus_terminate(_GLFWDBUSData *dbus);
DBusConnection* glfw_dbus_connect_to(const char *path, const char* err_msg, const char* name, GLFWbool register_on_bus);
DBusConnection* glfw_dbus_connect_to(const char *path, const char* err_msg, const char* name, bool register_on_bus);
void glfw_dbus_close_connection(DBusConnection *conn);
GLFWbool
bool
call_method_with_msg(DBusConnection *conn, DBusMessage *msg, int timeout, dbus_pending_callback callback, void *user_data);
GLFWbool
bool
glfw_dbus_call_method_no_reply(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...);
GLFWbool
bool
glfw_dbus_call_method_with_reply(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, int timeout_ms, dbus_pending_callback callback, void *user_data, ...);
void glfw_dbus_dispatch(DBusConnection *);
void glfw_dbus_session_bus_dispatch(void);
GLFWbool glfw_dbus_get_args(DBusMessage *msg, const char *failmsg, ...);
bool glfw_dbus_get_args(DBusMessage *msg, const char *failmsg, ...);
int glfw_dbus_match_signal(DBusMessage *msg, const char *interface, ...);
DBusConnection* glfw_dbus_session_bus(void);

112
glfw/egl_context.c vendored
View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 EGL - www.glfw.org
// GLFW 3.4 EGL - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -24,6 +24,8 @@
// distribution.
//
//========================================================================
// Please use C89 style variable declarations in this file because VS 2010
//========================================================================
#include "internal.h"
@@ -85,7 +87,7 @@ static int getEGLConfigAttrib(EGLConfig config, int attrib)
// Return the EGLConfig most closely matching the specified hints
//
static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
static bool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* desired,
EGLConfig* result)
{
@@ -98,7 +100,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
if (!nativeCount)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: No EGLConfigs returned");
return GLFW_FALSE;
return false;
}
nativeConfigs = calloc(nativeCount, sizeof(EGLConfig));
@@ -170,7 +172,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
u->stencilBits = getEGLConfigAttrib(n, EGL_STENCIL_SIZE);
u->samples = getEGLConfigAttrib(n, EGL_SAMPLES);
u->doublebuffer = GLFW_TRUE;
u->doublebuffer = true;
u->handle = (uintptr_t) n;
usableCount++;
@@ -241,10 +243,10 @@ static int extensionSupportedEGL(const char* extension)
if (extensions)
{
if (_glfwStringInExtensionString(extension, extensions))
return GLFW_TRUE;
return true;
}
return GLFW_FALSE;
return false;
}
static GLFWglproc getProcAddressEGL(const char* procname)
@@ -253,8 +255,8 @@ static GLFWglproc getProcAddressEGL(const char* procname)
if (window->context.egl.client)
{
GLFWglproc proc = (GLFWglproc) _glfw_dlsym(window->context.egl.client,
procname);
GLFWglproc proc = NULL;
glfw_dlsym(proc, window->context.egl.client, procname);
if (proc)
return proc;
}
@@ -297,7 +299,7 @@ static void destroyContextEGL(_GLFWwindow* window)
// Initialize EGL
//
GLFWbool _glfwInitEGL(void)
bool _glfwInitEGL(void)
{
int i;
const char* sonames[] =
@@ -318,7 +320,7 @@ GLFWbool _glfwInitEGL(void)
};
if (_glfw.egl.handle)
return GLFW_TRUE;
return true;
for (i = 0; sonames[i]; i++)
{
@@ -330,43 +332,27 @@ GLFWbool _glfwInitEGL(void)
if (!_glfw.egl.handle)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: Library not found");
return GLFW_FALSE;
return false;
}
_glfw.egl.prefix = (strncmp(sonames[i], "lib", 3) == 0);
_glfw.egl.GetConfigAttrib = (PFN_eglGetConfigAttrib)
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigAttrib");
_glfw.egl.GetConfigs = (PFN_eglGetConfigs)
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigs");
_glfw.egl.GetDisplay = (PFN_eglGetDisplay)
_glfw_dlsym(_glfw.egl.handle, "eglGetDisplay");
_glfw.egl.GetError = (PFN_eglGetError)
_glfw_dlsym(_glfw.egl.handle, "eglGetError");
_glfw.egl.Initialize = (PFN_eglInitialize)
_glfw_dlsym(_glfw.egl.handle, "eglInitialize");
_glfw.egl.Terminate = (PFN_eglTerminate)
_glfw_dlsym(_glfw.egl.handle, "eglTerminate");
_glfw.egl.BindAPI = (PFN_eglBindAPI)
_glfw_dlsym(_glfw.egl.handle, "eglBindAPI");
_glfw.egl.CreateContext = (PFN_eglCreateContext)
_glfw_dlsym(_glfw.egl.handle, "eglCreateContext");
_glfw.egl.DestroySurface = (PFN_eglDestroySurface)
_glfw_dlsym(_glfw.egl.handle, "eglDestroySurface");
_glfw.egl.DestroyContext = (PFN_eglDestroyContext)
_glfw_dlsym(_glfw.egl.handle, "eglDestroyContext");
_glfw.egl.CreateWindowSurface = (PFN_eglCreateWindowSurface)
_glfw_dlsym(_glfw.egl.handle, "eglCreateWindowSurface");
_glfw.egl.MakeCurrent = (PFN_eglMakeCurrent)
_glfw_dlsym(_glfw.egl.handle, "eglMakeCurrent");
_glfw.egl.SwapBuffers = (PFN_eglSwapBuffers)
_glfw_dlsym(_glfw.egl.handle, "eglSwapBuffers");
_glfw.egl.SwapInterval = (PFN_eglSwapInterval)
_glfw_dlsym(_glfw.egl.handle, "eglSwapInterval");
_glfw.egl.QueryString = (PFN_eglQueryString)
_glfw_dlsym(_glfw.egl.handle, "eglQueryString");
_glfw.egl.GetProcAddress = (PFN_eglGetProcAddress)
_glfw_dlsym(_glfw.egl.handle, "eglGetProcAddress");
glfw_dlsym(_glfw.egl.GetConfigAttrib, _glfw.egl.handle, "eglGetConfigAttrib");
glfw_dlsym(_glfw.egl.GetConfigs, _glfw.egl.handle, "eglGetConfigs");
glfw_dlsym(_glfw.egl.GetDisplay, _glfw.egl.handle, "eglGetDisplay");
glfw_dlsym(_glfw.egl.GetError, _glfw.egl.handle, "eglGetError");
glfw_dlsym(_glfw.egl.Initialize, _glfw.egl.handle, "eglInitialize");
glfw_dlsym(_glfw.egl.Terminate, _glfw.egl.handle, "eglTerminate");
glfw_dlsym(_glfw.egl.BindAPI, _glfw.egl.handle, "eglBindAPI");
glfw_dlsym(_glfw.egl.CreateContext, _glfw.egl.handle, "eglCreateContext");
glfw_dlsym(_glfw.egl.DestroySurface, _glfw.egl.handle, "eglDestroySurface");
glfw_dlsym(_glfw.egl.DestroyContext, _glfw.egl.handle, "eglDestroyContext");
glfw_dlsym(_glfw.egl.CreateWindowSurface, _glfw.egl.handle, "eglCreateWindowSurface");
glfw_dlsym(_glfw.egl.MakeCurrent, _glfw.egl.handle, "eglMakeCurrent");
glfw_dlsym(_glfw.egl.SwapBuffers, _glfw.egl.handle, "eglSwapBuffers");
glfw_dlsym(_glfw.egl.SwapInterval, _glfw.egl.handle, "eglSwapInterval");
glfw_dlsym(_glfw.egl.QueryString, _glfw.egl.handle, "eglQueryString");
glfw_dlsym(_glfw.egl.GetProcAddress, _glfw.egl.handle, "eglGetProcAddress");
if (!_glfw.egl.GetConfigAttrib ||
!_glfw.egl.GetConfigs ||
@@ -389,7 +375,7 @@ GLFWbool _glfwInitEGL(void)
"EGL: Failed to load required entry points");
_glfwTerminateEGL();
return GLFW_FALSE;
return false;
}
_glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY);
@@ -400,7 +386,7 @@ GLFWbool _glfwInitEGL(void)
getEGLErrorString(eglGetError()));
_glfwTerminateEGL();
return GLFW_FALSE;
return false;
}
if (!eglInitialize(_glfw.egl.display, &_glfw.egl.major, &_glfw.egl.minor))
@@ -410,7 +396,7 @@ GLFWbool _glfwInitEGL(void)
getEGLErrorString(eglGetError()));
_glfwTerminateEGL();
return GLFW_FALSE;
return false;
}
_glfw.egl.KHR_create_context =
@@ -424,7 +410,7 @@ GLFWbool _glfwInitEGL(void)
_glfw.egl.KHR_context_flush_control =
extensionSupportedEGL("EGL_KHR_context_flush_control");
return GLFW_TRUE;
return true;
}
// Terminate EGL
@@ -446,14 +432,14 @@ void _glfwTerminateEGL(void)
#define setAttrib(a, v) \
{ \
assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \
attribs[index++] = v; \
}
// Create the OpenGL or OpenGL ES context
//
GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
bool _glfwCreateContextEGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
@@ -465,7 +451,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
if (!_glfw.egl.display)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: API not available");
return GLFW_FALSE;
return false;
}
if (ctxconfig->share)
@@ -475,7 +461,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"EGL: Failed to find a suitable EGLConfig");
return GLFW_FALSE;
return false;
}
if (ctxconfig->client == GLFW_OPENGL_ES_API)
@@ -485,7 +471,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to bind OpenGL ES: %s",
getEGLErrorString(eglGetError()));
return GLFW_FALSE;
return false;
}
}
else
@@ -495,7 +481,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to bind OpenGL: %s",
getEGLErrorString(eglGetError()));
return GLFW_FALSE;
return false;
}
}
@@ -536,7 +522,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
if (ctxconfig->noerror)
{
if (_glfw.egl.KHR_create_context_no_error)
setAttrib(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE);
setAttrib(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, true);
}
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
@@ -581,7 +567,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"EGL: Failed to create context: %s",
getEGLErrorString(eglGetError()));
return GLFW_FALSE;
return false;
}
// Set up attributes for surface creation
@@ -607,7 +593,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGL: Failed to create window surface: %s",
getEGLErrorString(eglGetError()));
return GLFW_FALSE;
return false;
}
window->context.egl.config = config;
@@ -695,7 +681,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to load client library");
return GLFW_FALSE;
return false;
}
}
@@ -706,7 +692,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
window->context.getProcAddress = getProcAddressEGL;
window->context.destroy = destroyContextEGL;
return GLFW_TRUE;
return true;
}
#undef setAttrib
@@ -714,7 +700,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
// Returns the Visual and depth of the chosen EGLConfig
//
#if defined(_GLFW_X11)
GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
bool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig UNUSED,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth)
@@ -729,7 +715,7 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"EGL: Failed to find a suitable EGLConfig");
return GLFW_FALSE;
return false;
}
eglGetConfigAttrib(_glfw.egl.display, native,
@@ -743,14 +729,14 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGL: Failed to retrieve Visual for EGLConfig");
return GLFW_FALSE;
return false;
}
*visual = result->visual;
*depth = result->depth;
XFree(result);
return GLFW_TRUE;
return true;
}
#endif // _GLFW_X11

22
glfw/egl_context.h vendored
View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 EGL - www.glfw.org
// GLFW 3.4 EGL - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -173,13 +173,13 @@ typedef struct _GLFWlibraryEGL
{
EGLDisplay display;
EGLint major, minor;
GLFWbool prefix;
bool prefix;
GLFWbool KHR_create_context;
GLFWbool KHR_create_context_no_error;
GLFWbool KHR_gl_colorspace;
GLFWbool KHR_get_all_proc_addresses;
GLFWbool KHR_context_flush_control;
bool KHR_create_context;
bool KHR_create_context_no_error;
bool KHR_gl_colorspace;
bool KHR_get_all_proc_addresses;
bool KHR_context_flush_control;
void* handle;
@@ -203,13 +203,13 @@ typedef struct _GLFWlibraryEGL
} _GLFWlibraryEGL;
GLFWbool _glfwInitEGL(void);
bool _glfwInitEGL(void);
void _glfwTerminateEGL(void);
GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
bool _glfwCreateContextEGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
#if defined(_GLFW_X11)
GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
bool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth);

View File

@@ -8,7 +8,6 @@ import re
import sys
_plat = sys.platform.lower()
is_macos = 'darwin' in _plat
is_freebsd = 'freebsd' in _plat
is_netbsd = 'netbsd' in _plat
is_dragonflybsd = 'dragonfly' in _plat
@@ -23,26 +22,12 @@ def wayland_protocol_file_name(base, ext='c'):
def init_env(env, pkg_config, at_least_version, test_compile, module='x11'):
ans = env.copy()
ans.cflags = [
x for x in ans.cflags
if x not in '-Wpedantic -Wextra -pedantic-errors'.split()
]
if not is_macos:
ans.cflags.append('-pthread')
ans.ldpaths.append('-pthread')
ans.cflags.append('-fpic')
ans.cppflags.append('-D_GLFW_' + module.upper())
ans.cppflags.append('-D_GLFW_BUILD_DLL')
if is_macos:
ans.cppflags.append('-DGL_SILENCE_DEPRECATION')
ans.ldpaths.extend(
"-framework Cocoa -framework IOKit -framework CoreFoundation -framework CoreVideo".
split()
)
else:
ans.ldpaths.extend('-lrt -lm -ldl'.split())
sinfo = json.load(open(os.path.join(base, 'source-info.json')))
with open(os.path.join(base, 'source-info.json')) as f:
sinfo = json.load(f)
module_sources = list(sinfo[module]['sources'])
if module in ('x11', 'wayland'):
remove = 'linux_joystick.c' if is_bsd else 'null_joystick.c'
@@ -52,6 +37,9 @@ def init_env(env, pkg_config, at_least_version, test_compile, module='x11'):
ans.all_headers = [x for x in os.listdir(base) if x.endswith('.h')]
if module in ('x11', 'wayland'):
ans.cflags.append('-pthread')
ans.ldpaths.append('-pthread')
ans.ldpaths.extend('-lrt -lm -ldl'.split())
at_least_version('xkbcommon', 0, 5)
if module == 'x11':
@@ -60,6 +48,7 @@ def init_env(env, pkg_config, at_least_version, test_compile, module='x11'):
ans.ldpaths.extend(pkg_config(dep, '--libs'))
elif module == 'cocoa':
ans.cppflags.append('-DGL_SILENCE_DEPRECATION')
for f in 'Cocoa IOKit CoreFoundation CoreVideo'.split():
ans.ldpaths.extend(('-framework', f))
@@ -88,7 +77,8 @@ def init_env(env, pkg_config, at_least_version, test_compile, module='x11'):
return ans
def build_wayland_protocols(env, run_tool, emphasis, newer, dest_dir):
def build_wayland_protocols(env, Command, parallel_run, emphasis, newer, dest_dir):
items = []
for protocol in env.wayland_protocols:
src = os.path.join(env.wayland_packagedir, protocol)
if not os.path.exists(src):
@@ -98,8 +88,12 @@ def build_wayland_protocols(env, run_tool, emphasis, newer, dest_dir):
dest = os.path.join(dest_dir, dest)
if newer(dest, src):
q = 'client-header' if ext == 'h' else env.wayland_scanner_code
run_tool([env.wayland_scanner, q, src, dest],
desc='Generating {} ...'.format(emphasis(os.path.basename(dest))))
items.append(Command(
'Generating {} ...'.format(emphasis(os.path.basename(dest))),
[env.wayland_scanner, q, src, dest],
lambda: True, None, None, None))
if items:
parallel_run(items)
class Arg:
@@ -156,7 +150,8 @@ class Function:
def generate_wrappers(glfw_header):
src = open(glfw_header).read()
with open(glfw_header) as f:
src = f.read()
functions = []
first = None
for m in re.finditer(r'^GLFWAPI\s+(.+[)]);\s*$', src, flags=re.MULTILINE):

144
glfw/glfw3.h vendored
View File

@@ -1,9 +1,9 @@
/*************************************************************************
* GLFW 3.3 - www.glfw.org
* GLFW 3.4 - www.glfw.org
* A library for OpenGL, window and input
*------------------------------------------------------------------------
* Copyright (c) 2002-2006 Marcus Geelnard
* Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
* Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
@@ -261,7 +261,7 @@ extern "C" {
* backward-compatible.
* @ingroup init
*/
#define GLFW_VERSION_MINOR 3
#define GLFW_VERSION_MINOR 4
/*! @brief The revision number of the GLFW library.
*
* This is incremented when a bug fix release is made that does not contain any
@@ -271,24 +271,6 @@ extern "C" {
#define GLFW_VERSION_REVISION 0
/*! @} */
/*! @name Boolean values
* @{ */
/*! @brief One.
*
* One. Seriously. You don't _need_ to use this symbol in your code. It's
* semantic sugar for the number 1. You can also use `1` or `true` or `_True`
* or `GL_TRUE` or whatever you want.
*/
#define GLFW_TRUE true
/*! @brief Zero.
*
* Zero. Seriously. You don't _need_ to use this symbol in your code. It's
* semantic sugar for the number 0. You can also use `0` or `false` or
* `_False` or `GL_FALSE` or whatever you want.
*/
#define GLFW_FALSE false
/*! @} */
/*! @name Key and button actions
* @{ */
/*! @brief The key or mouse button was released.
@@ -342,7 +324,7 @@ extern "C" {
*
* The naming of the key codes follow these rules:
* - The US keyboard layout is used
* - Names of printable alpha-numeric characters are used (e.g. "A", "R",
* - Names of printable alphanumeric characters are used (e.g. "A", "R",
* "3", etc.)
* - For non-alphanumeric characters, Unicode:ish names are used (e.g.
* "COMMA", "LEFT_SQUARE_BRACKET", etc.). Note that some names do not
@@ -410,6 +392,7 @@ extern "C" {
#define GLFW_KEY_WORLD_1 161 /* non-US #1 */
#define GLFW_KEY_WORLD_2 162 /* non-US #2 */
#define GLFW_KEY_PLUS 163
#define GLFW_KEY_UNDERSCORE 164
/* Function keys */
#define GLFW_KEY_ESCAPE 256
@@ -922,62 +905,62 @@ extern "C" {
#define GLFW_CLIENT_API 0x00022001
/*! @brief Context client API major version hint and attribute.
*
* Context client API major version [hint](@ref GLFW_CLIENT_API_hint) and
* [attribute](@ref GLFW_CLIENT_API_attrib).
* Context client API major version [hint](@ref GLFW_CONTEXT_VERSION_MAJOR_hint)
* and [attribute](@ref GLFW_CONTEXT_VERSION_MAJOR_attrib).
*/
#define GLFW_CONTEXT_VERSION_MAJOR 0x00022002
/*! @brief Context client API minor version hint and attribute.
*
* Context client API minor version [hint](@ref GLFW_CLIENT_API_hint) and
* [attribute](@ref GLFW_CLIENT_API_attrib).
* Context client API minor version [hint](@ref GLFW_CONTEXT_VERSION_MINOR_hint)
* and [attribute](@ref GLFW_CONTEXT_VERSION_MINOR_attrib).
*/
#define GLFW_CONTEXT_VERSION_MINOR 0x00022003
/*! @brief Context client API revision number hint and attribute.
*
* Context client API revision number [hint](@ref GLFW_CLIENT_API_hint) and
* [attribute](@ref GLFW_CLIENT_API_attrib).
* Context client API revision number
* [attribute](@ref GLFW_CONTEXT_REVISION_attrib).
*/
#define GLFW_CONTEXT_REVISION 0x00022004
/*! @brief Context robustness hint and attribute.
*
* Context client API revision number [hint](@ref GLFW_CLIENT_API_hint) and
* [attribute](@ref GLFW_CLIENT_API_attrib).
* Context client API revision number [hint](@ref GLFW_CONTEXT_ROBUSTNESS_hint)
* and [attribute](@ref GLFW_CONTEXT_ROBUSTNESS_attrib).
*/
#define GLFW_CONTEXT_ROBUSTNESS 0x00022005
/*! @brief OpenGL forward-compatibility hint and attribute.
*
* OpenGL forward-compatibility [hint](@ref GLFW_CLIENT_API_hint) and
* [attribute](@ref GLFW_CLIENT_API_attrib).
* OpenGL forward-compatibility [hint](@ref GLFW_OPENGL_FORWARD_COMPAT_hint)
* and [attribute](@ref GLFW_OPENGL_FORWARD_COMPAT_attrib).
*/
#define GLFW_OPENGL_FORWARD_COMPAT 0x00022006
/*! @brief OpenGL debug context hint and attribute.
*
* OpenGL debug context [hint](@ref GLFW_CLIENT_API_hint) and
* [attribute](@ref GLFW_CLIENT_API_attrib).
* OpenGL debug context [hint](@ref GLFW_OPENGL_DEBUG_CONTEXT_hint) and
* [attribute](@ref GLFW_OPENGL_DEBUG_CONTEXT_attrib).
*/
#define GLFW_OPENGL_DEBUG_CONTEXT 0x00022007
/*! @brief OpenGL profile hint and attribute.
*
* OpenGL profile [hint](@ref GLFW_CLIENT_API_hint) and
* [attribute](@ref GLFW_CLIENT_API_attrib).
* OpenGL profile [hint](@ref GLFW_OPENGL_PROFILE_hint) and
* [attribute](@ref GLFW_OPENGL_PROFILE_attrib).
*/
#define GLFW_OPENGL_PROFILE 0x00022008
/*! @brief Context flush-on-release hint and attribute.
*
* Context flush-on-release [hint](@ref GLFW_CLIENT_API_hint) and
* [attribute](@ref GLFW_CLIENT_API_attrib).
* Context flush-on-release [hint](@ref GLFW_CONTEXT_RELEASE_BEHAVIOR_hint) and
* [attribute](@ref GLFW_CONTEXT_RELEASE_BEHAVIOR_attrib).
*/
#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009
/*! @brief Context error suppression hint and attribute.
*
* Context error suppression [hint](@ref GLFW_CLIENT_API_hint) and
* [attribute](@ref GLFW_CLIENT_API_attrib).
* Context error suppression [hint](@ref GLFW_CONTEXT_NO_ERROR_hint) and
* [attribute](@ref GLFW_CONTEXT_NO_ERROR_attrib).
*/
#define GLFW_CONTEXT_NO_ERROR 0x0002200A
/*! @brief Context creation API hint and attribute.
*
* Context creation API [hint](@ref GLFW_CLIENT_API_hint) and
* [attribute](@ref GLFW_CLIENT_API_attrib).
* Context creation API [hint](@ref GLFW_CONTEXT_CREATION_API_hint) and
* [attribute](@ref GLFW_CONTEXT_CREATION_API_attrib).
*/
#define GLFW_CONTEXT_CREATION_API 0x0002200B
/*! @brief Window content area scaling window
@@ -1221,8 +1204,8 @@ typedef void (* GLFWwindowrefreshfun)(GLFWwindow*);
* This is the function signature for window focus callback functions.
*
* @param[in] window The window that gained or lost input focus.
* @param[in] focused `GLFW_TRUE` if the window was given input focus, or
* `GLFW_FALSE` if it lost it.
* @param[in] focused `true` if the window was given input focus, or
* `false` if it lost it.
*
* @sa @ref window_focus
* @sa @ref glfwSetWindowFocusCallback
@@ -1238,7 +1221,7 @@ typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int);
* This is the function signature for window occlusion callback functions.
*
* @param[in] window The window whose occlusion state changed.
* @param[in] occluded `GLFW_TRUE` if the window was occluded, or `GLFW_FALSE`
* @param[in] occluded `true` if the window was occluded, or `false`
* if the window is no longer occluded.
*
* @sa @ref window_occlusion
@@ -1257,8 +1240,8 @@ typedef void (* GLFWwindowocclusionfun)(GLFWwindow*, bool);
* functions.
*
* @param[in] window The window that was iconified or restored.
* @param[in] iconified `GLFW_TRUE` if the window was iconified, or
* `GLFW_FALSE` if it was restored.
* @param[in] iconified `true` if the window was iconified, or
* `false` if it was restored.
*
* @sa @ref window_iconify
* @sa @ref glfwSetWindowIconifyCallback
@@ -1275,8 +1258,8 @@ typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int);
* functions.
*
* @param[in] window The window that was maximized or restored.
* @param[in] iconified `GLFW_TRUE` if the window was maximized, or
* `GLFW_FALSE` if it was restored.
* @param[in] iconified `true` if the window was maximized, or
* `false` if it was restored.
*
* @sa @ref window_maximize
* @sa glfwSetWindowMaximizeCallback
@@ -1368,8 +1351,8 @@ typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double);
* This is the function signature for cursor enter/leave callback functions.
*
* @param[in] window The window that received the event.
* @param[in] entered `GLFW_TRUE` if the cursor entered the window's client
* area, or `GLFW_FALSE` if it left it.
* @param[in] entered `true` if the cursor entered the window's client
* area, or `false` if it left it.
*
* @sa @ref cursor_enter
* @sa @ref glfwSetCursorEnterCallback
@@ -1621,9 +1604,9 @@ typedef struct GLFWgamepadstate
* succeeds, you should call @ref glfwTerminate before the application exits.
*
* Additional calls to this function after successful initialization but before
* termination will return `GLFW_TRUE` immediately.
* termination will return `true` immediately.
*
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
* @return `true` if successful, or `false` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_PLATFORM_ERROR.
@@ -1645,7 +1628,6 @@ typedef struct GLFWgamepadstate
GLFWAPI int glfwInit(void);
GLFWAPI void glfwRunMainLoop(GLFWtickcallback callback, void *callback_data);
GLFWAPI void glfwStopMainLoop(void);
GLFWAPI void glfwRequestTickCallback(void);
GLFWAPI unsigned long long glfwAddTimer(double interval, bool repeats, GLFWuserdatafun callback, void * callback_data, GLFWuserdatafun free_callback);
GLFWAPI void glfwUpdateTimer(unsigned long long timer_id, double interval, bool enabled);
GLFWAPI void glfwRemoveTimer(unsigned long long);
@@ -2193,7 +2175,7 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
*
* @remark @wayland Gamma handling is a priviledged protocol, this function
* @remark @wayland Gamma handling is a privileged protocol, this function
* will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR.
*
* @thread_safety This function must only be called from the main thread.
@@ -2217,7 +2199,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @remark @wayland Gamma handling is a priviledged protocol, this function
* @remark @wayland Gamma handling is a privileged protocol, this function
* will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR while
* returning `NULL`.
*
@@ -2261,7 +2243,7 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);
*
* @remark @win32 The gamma ramp size must be 256.
*
* @remark @wayland Gamma handling is a priviledged protocol, this function
* @remark @wayland Gamma handling is a privileged protocol, this function
* will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR.
*
* @pointer_lifetime The specified gamma ramp is copied before this function
@@ -2471,7 +2453,7 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
* @remark @macos On OS X 10.10 and later the window frame will not be rendered
* at full resolution on Retina displays unless the
* [GLFW_COCOA_RETINA_FRAMEBUFFER](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint)
* hint is `GLFW_TRUE` and the `NSHighResolutionCapable` key is enabled in the
* hint is `true` and the `NSHighResolutionCapable` key is enabled in the
* application bundle's `Info.plist`. For more information, see
* [High Resolution Guidelines for OS X](https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html)
* in the Mac Developer Library. The GLFW test and example programs use
@@ -2480,7 +2462,7 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
*
* @remark @macos When activating frame autosaving with
* [GLFW_COCOA_FRAME_NAME](@ref GLFW_COCOA_FRAME_NAME_hint), the specified
* window size and position may be overriden by previously saved values.
* window size and position may be overridden by previously saved values.
*
* @remark @x11 Some window managers will not respect the placement of
* initially hidden windows.
@@ -3272,7 +3254,7 @@ GLFWAPI void glfwRequestWindowAttention(GLFWwindow* window);
* supported. Currently (macOS, Windows, X11 and Wayland).
*
* @param[in] window The window with which the bell is associated.
* @return GLFW_TRUE if the bell succeeded otherwise GLFW_FALSE
* @return true if the bell succeeded otherwise false
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
@@ -3422,7 +3404,7 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);
*
* @param[in] window The window to set the attribute for.
* @param[in] attrib A supported window attribute.
* @param[in] value `GLFW_TRUE` or `GLFW_FALSE`.
* @param[in] value `true` or `false`.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
@@ -3804,23 +3786,23 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
* and unlimited cursor movement. This is useful for implementing for
* example 3D camera controls.
*
* If the mode is `GLFW_STICKY_KEYS`, the value must be either `GLFW_TRUE` to
* enable sticky keys, or `GLFW_FALSE` to disable it. If sticky keys are
* If the mode is `GLFW_STICKY_KEYS`, the value must be either `true` to
* enable sticky keys, or `false` to disable it. If sticky keys are
* enabled, a key press will ensure that @ref glfwGetKey returns `GLFW_PRESS`
* the next time it is called even if the key had been released before the
* call. This is useful when you are only interested in whether keys have been
* pressed but not when or in which order.
*
* If the mode is `GLFW_STICKY_MOUSE_BUTTONS`, the value must be either
* `GLFW_TRUE` to enable sticky mouse buttons, or `GLFW_FALSE` to disable it.
* `true` to enable sticky mouse buttons, or `false` to disable it.
* If sticky mouse buttons are enabled, a mouse button press will ensure that
* @ref glfwGetMouseButton returns `GLFW_PRESS` the next time it is called even
* if the mouse button had been released before the call. This is useful when
* you are only interested in whether mouse buttons have been pressed but not
* when or in which order.
*
* If the mode is `GLFW_LOCK_KEY_MODS`, the value must be either `GLFW_TRUE` to
* enable lock key modifier bits, or `GLFW_FALSE` to disable them. If enabled,
* If the mode is `GLFW_LOCK_KEY_MODS`, the value must be either `true` to
* enable lock key modifier bits, or `false` to disable them. If enabled,
* callbacks that receive modifier bits will also have the @ref
* GLFW_MOD_CAPS_LOCK bit set when the event was generated with Caps Lock on,
* and the @ref GLFW_MOD_NUM_LOCK bit when Num Lock was on.
@@ -4365,7 +4347,7 @@ GLFWAPI GLFWliveresizefun glfwSetLiveResizeCallback(GLFWwindow* window, GLFWlive
* work.
*
* @param[in] jid The [joystick](@ref joysticks) to query.
* @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise.
* @return `true` if the joystick is present, or `false` otherwise.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
@@ -4542,7 +4524,7 @@ GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count);
*/
GLFWAPI const char* glfwGetJoystickName(int jid);
/*! @brief Returns the SDL comaptible GUID of the specified joystick.
/*! @brief Returns the SDL compatible GUID of the specified joystick.
*
* This function returns the SDL compatible GUID, as a UTF-8 encoded
* hexadecimal string, of the specified joystick. The returned string is
@@ -4639,13 +4621,13 @@ GLFWAPI void* glfwGetJoystickUserPointer(int jid);
* a gamepad mapping.
*
* If the specified joystick is present but does not have a gamepad mapping
* this function will return `GLFW_FALSE` but will not generate an error. Call
* this function will return `false` but will not generate an error. Call
* @ref glfwJoystickPresent to check if a joystick is present regardless of
* whether it has a mapping.
*
* @param[in] jid The [joystick](@ref joysticks) to query.
* @return `GLFW_TRUE` if a joystick is both present and has a gamepad mapping,
* or `GLFW_FALSE` otherwise.
* @return `true` if a joystick is both present and has a gamepad mapping,
* or `false` otherwise.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_INVALID_ENUM.
@@ -4706,7 +4688,7 @@ GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun);
* default.
*
* @param[in] string The string containing the gamepad mappings.
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
* @return `true` if successful, or `false` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
@@ -4756,11 +4738,11 @@ GLFWAPI const char* glfwGetGamepadName(int jid);
/*! @brief Retrieves the state of the specified joystick remapped as a gamepad.
*
* This function retrives the state of the specified joystick remapped to
* This function retrieves the state of the specified joystick remapped to
* an Xbox-like gamepad.
*
* If the specified joystick is not present or does not have a gamepad mapping
* this function will return `GLFW_FALSE` but will not generate an error. Call
* this function will return `false` but will not generate an error. Call
* @ref glfwJoystickPresent to check whether it is present regardless of
* whether it has a mapping.
*
@@ -4773,7 +4755,7 @@ GLFWAPI const char* glfwGetGamepadName(int jid);
*
* @param[in] jid The [joystick](@ref joysticks) to query.
* @param[out] state The gamepad input state of the joystick.
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if no joystick is
* @return `true` if successful, or `false` if no joystick is
* connected, it has no gamepad mapping or an [error](@ref error_handling)
* occurred.
*
@@ -5106,7 +5088,7 @@ GLFWAPI void glfwSwapInterval(int interval);
* and `vkEnumerateDeviceExtensionProperties` instead.
*
* @param[in] extension The ASCII encoded name of the extension.
* @return `GLFW_TRUE` if the extension is available, or `GLFW_FALSE`
* @return `true` if the extension is available, or `false`
* otherwise.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
@@ -5179,7 +5161,7 @@ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname);
* and @ref glfwGetPhysicalDevicePresentationSupport to check whether a queue
* family of a physical device supports image presentation.
*
* @return `GLFW_TRUE` if Vulkan is minimally available, or `GLFW_FALSE`
* @return `true` if Vulkan is minimally available, or `false`
* otherwise.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
@@ -5291,7 +5273,7 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* p
*
* If Vulkan or the required window surface creation instance extensions are
* not available on the machine, or if the specified instance was not created
* with the required extensions, this function returns `GLFW_FALSE` and
* with the required extensions, this function returns `false` and
* generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported
* to check whether Vulkan is at least minimally available and @ref
* glfwGetRequiredInstanceExtensions to check what instance extensions are
@@ -5300,13 +5282,13 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* p
* @param[in] instance The instance that the physical device belongs to.
* @param[in] device The physical device that the queue family belongs to.
* @param[in] queuefamily The index of the queue family to query.
* @return `GLFW_TRUE` if the queue family supports presentation, or
* `GLFW_FALSE` otherwise.
* @return `true` if the queue family supports presentation, or
* `false` otherwise.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
*
* @remark @macos This function currently always returns `GLFW_TRUE`, as the
* @remark @macos This function currently always returns `true`, as the
* `VK_MVK_macos_surface` extension does not provide
* a `vkGetPhysicalDevice*PresentationSupport` type function.
*

151
glfw/glx_context.c vendored
View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 GLX - www.glfw.org
// GLFW 3.4 GLX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -24,6 +24,8 @@
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include "internal.h"
@@ -47,7 +49,7 @@ static int getGLXFBConfigAttrib(GLXFBConfig fbconfig, int attrib)
// Return the GLXFBConfig most closely matching the specified hints
//
static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
static bool chooseGLXFBConfig(const _GLFWfbconfig* desired,
GLXFBConfig* result)
{
GLXFBConfig* nativeConfigs;
@@ -55,20 +57,20 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
const _GLFWfbconfig* closest;
int i, nativeCount, usableCount;
const char* vendor;
GLFWbool trustWindowBit = GLFW_TRUE;
bool trustWindowBit = true;
// HACK: This is a (hopefully temporary) workaround for Chromium
// (VirtualBox GL) not setting the window bit on any GLXFBConfigs
vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR);
if (vendor && strcmp(vendor, "Chromium") == 0)
trustWindowBit = GLFW_FALSE;
trustWindowBit = false;
nativeConfigs =
glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, &nativeCount);
if (!nativeConfigs || !nativeCount)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned");
return GLFW_FALSE;
return false;
}
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
@@ -116,9 +118,9 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
u->auxBuffers = getGLXFBConfigAttrib(n, GLX_AUX_BUFFERS);
if (getGLXFBConfigAttrib(n, GLX_STEREO))
u->stereo = GLFW_TRUE;
u->stereo = true;
if (getGLXFBConfigAttrib(n, GLX_DOUBLEBUFFER))
u->doublebuffer = GLFW_TRUE;
u->doublebuffer = true;
if (_glfw.glx.ARB_multisample)
u->samples = getGLXFBConfigAttrib(n, GLX_SAMPLES);
@@ -142,7 +144,7 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
// Create the OpenGL context using legacy API
//
static GLXContext createLegacyContextGLX(_GLFWwindow* window,
static GLXContext createLegacyContextGLX(_GLFWwindow* window UNUSED,
GLXFBConfig fbconfig,
GLXContext share)
{
@@ -210,10 +212,10 @@ static int extensionSupportedGLX(const char* extension)
if (extensions)
{
if (_glfwStringInExtensionString(extension, extensions))
return GLFW_TRUE;
return true;
}
return GLFW_FALSE;
return false;
}
static GLFWglproc getProcAddressGLX(const char* procname)
@@ -222,12 +224,13 @@ static GLFWglproc getProcAddressGLX(const char* procname)
return _glfw.glx.GetProcAddress((const GLubyte*) procname);
else if (_glfw.glx.GetProcAddressARB)
return _glfw.glx.GetProcAddressARB((const GLubyte*) procname);
else
return _glfw_dlsym(_glfw.glx.handle, procname);
else {
GLFWglproc ans = NULL;
glfw_dlsym(ans, _glfw.glx.handle, procname);
return ans;
}
}
// Destroy the OpenGL context
//
static void destroyContextGLX(_GLFWwindow* window)
{
if (window->context.glx.window)
@@ -250,7 +253,7 @@ static void destroyContextGLX(_GLFWwindow* window)
// Initialize GLX
//
GLFWbool _glfwInitGLX(void)
bool _glfwInitGLX(void)
{
int i;
const char* sonames[] =
@@ -267,7 +270,7 @@ GLFWbool _glfwInitGLX(void)
};
if (_glfw.glx.handle)
return GLFW_TRUE;
return true;
for (i = 0; sonames[i]; i++)
{
@@ -279,39 +282,24 @@ GLFWbool _glfwInitGLX(void)
if (!_glfw.glx.handle)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: Failed to load GLX");
return GLFW_FALSE;
return false;
}
_glfw.glx.GetFBConfigs =
_glfw_dlsym(_glfw.glx.handle, "glXGetFBConfigs");
_glfw.glx.GetFBConfigAttrib =
_glfw_dlsym(_glfw.glx.handle, "glXGetFBConfigAttrib");
_glfw.glx.GetClientString =
_glfw_dlsym(_glfw.glx.handle, "glXGetClientString");
_glfw.glx.QueryExtension =
_glfw_dlsym(_glfw.glx.handle, "glXQueryExtension");
_glfw.glx.QueryVersion =
_glfw_dlsym(_glfw.glx.handle, "glXQueryVersion");
_glfw.glx.DestroyContext =
_glfw_dlsym(_glfw.glx.handle, "glXDestroyContext");
_glfw.glx.MakeCurrent =
_glfw_dlsym(_glfw.glx.handle, "glXMakeCurrent");
_glfw.glx.SwapBuffers =
_glfw_dlsym(_glfw.glx.handle, "glXSwapBuffers");
_glfw.glx.QueryExtensionsString =
_glfw_dlsym(_glfw.glx.handle, "glXQueryExtensionsString");
_glfw.glx.CreateNewContext =
_glfw_dlsym(_glfw.glx.handle, "glXCreateNewContext");
_glfw.glx.CreateWindow =
_glfw_dlsym(_glfw.glx.handle, "glXCreateWindow");
_glfw.glx.DestroyWindow =
_glfw_dlsym(_glfw.glx.handle, "glXDestroyWindow");
_glfw.glx.GetProcAddress =
_glfw_dlsym(_glfw.glx.handle, "glXGetProcAddress");
_glfw.glx.GetProcAddressARB =
_glfw_dlsym(_glfw.glx.handle, "glXGetProcAddressARB");
_glfw.glx.GetVisualFromFBConfig =
_glfw_dlsym(_glfw.glx.handle, "glXGetVisualFromFBConfig");
glfw_dlsym(_glfw.glx.GetFBConfigs, _glfw.glx.handle, "glXGetFBConfigs");
glfw_dlsym(_glfw.glx.GetFBConfigAttrib, _glfw.glx.handle, "glXGetFBConfigAttrib");
glfw_dlsym(_glfw.glx.GetClientString, _glfw.glx.handle, "glXGetClientString");
glfw_dlsym(_glfw.glx.QueryExtension, _glfw.glx.handle, "glXQueryExtension");
glfw_dlsym(_glfw.glx.QueryVersion, _glfw.glx.handle, "glXQueryVersion");
glfw_dlsym(_glfw.glx.DestroyContext, _glfw.glx.handle, "glXDestroyContext");
glfw_dlsym(_glfw.glx.MakeCurrent, _glfw.glx.handle, "glXMakeCurrent");
glfw_dlsym(_glfw.glx.SwapBuffers, _glfw.glx.handle, "glXSwapBuffers");
glfw_dlsym(_glfw.glx.QueryExtensionsString, _glfw.glx.handle, "glXQueryExtensionsString");
glfw_dlsym(_glfw.glx.CreateNewContext, _glfw.glx.handle, "glXCreateNewContext");
glfw_dlsym(_glfw.glx.CreateWindow, _glfw.glx.handle, "glXCreateWindow");
glfw_dlsym(_glfw.glx.DestroyWindow, _glfw.glx.handle, "glXDestroyWindow");
glfw_dlsym(_glfw.glx.GetProcAddress, _glfw.glx.handle, "glXGetProcAddress");
glfw_dlsym(_glfw.glx.GetProcAddressARB, _glfw.glx.handle, "glXGetProcAddressARB");
glfw_dlsym(_glfw.glx.GetVisualFromFBConfig, _glfw.glx.handle, "glXGetVisualFromFBConfig");
if (!_glfw.glx.GetFBConfigs ||
!_glfw.glx.GetFBConfigAttrib ||
@@ -331,7 +319,7 @@ GLFWbool _glfwInitGLX(void)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"GLX: Failed to load required entry points");
return GLFW_FALSE;
return false;
}
if (!glXQueryExtension(_glfw.x11.display,
@@ -339,21 +327,21 @@ GLFWbool _glfwInitGLX(void)
&_glfw.glx.eventBase))
{
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: GLX extension not found");
return GLFW_FALSE;
return false;
}
if (!glXQueryVersion(_glfw.x11.display, &_glfw.glx.major, &_glfw.glx.minor))
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"GLX: Failed to query GLX version");
return GLFW_FALSE;
return false;
}
if (_glfw.glx.major == 1 && _glfw.glx.minor < 3)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"GLX: GLX version 1.3 is required");
return GLFW_FALSE;
return false;
}
if (extensionSupportedGLX("GLX_EXT_swap_control"))
@@ -362,7 +350,7 @@ GLFWbool _glfwInitGLX(void)
getProcAddressGLX("glXSwapIntervalEXT");
if (_glfw.glx.SwapIntervalEXT)
_glfw.glx.EXT_swap_control = GLFW_TRUE;
_glfw.glx.EXT_swap_control = true;
}
if (extensionSupportedGLX("GLX_SGI_swap_control"))
@@ -371,7 +359,7 @@ GLFWbool _glfwInitGLX(void)
getProcAddressGLX("glXSwapIntervalSGI");
if (_glfw.glx.SwapIntervalSGI)
_glfw.glx.SGI_swap_control = GLFW_TRUE;
_glfw.glx.SGI_swap_control = true;
}
if (extensionSupportedGLX("GLX_MESA_swap_control"))
@@ -380,17 +368,17 @@ GLFWbool _glfwInitGLX(void)
getProcAddressGLX("glXSwapIntervalMESA");
if (_glfw.glx.SwapIntervalMESA)
_glfw.glx.MESA_swap_control = GLFW_TRUE;
_glfw.glx.MESA_swap_control = true;
}
if (extensionSupportedGLX("GLX_ARB_multisample"))
_glfw.glx.ARB_multisample = GLFW_TRUE;
_glfw.glx.ARB_multisample = true;
if (extensionSupportedGLX("GLX_ARB_framebuffer_sRGB"))
_glfw.glx.ARB_framebuffer_sRGB = GLFW_TRUE;
_glfw.glx.ARB_framebuffer_sRGB = true;
if (extensionSupportedGLX("GLX_EXT_framebuffer_sRGB"))
_glfw.glx.EXT_framebuffer_sRGB = GLFW_TRUE;
_glfw.glx.EXT_framebuffer_sRGB = true;
if (extensionSupportedGLX("GLX_ARB_create_context"))
{
@@ -398,25 +386,25 @@ GLFWbool _glfwInitGLX(void)
getProcAddressGLX("glXCreateContextAttribsARB");
if (_glfw.glx.CreateContextAttribsARB)
_glfw.glx.ARB_create_context = GLFW_TRUE;
_glfw.glx.ARB_create_context = true;
}
if (extensionSupportedGLX("GLX_ARB_create_context_robustness"))
_glfw.glx.ARB_create_context_robustness = GLFW_TRUE;
_glfw.glx.ARB_create_context_robustness = true;
if (extensionSupportedGLX("GLX_ARB_create_context_profile"))
_glfw.glx.ARB_create_context_profile = GLFW_TRUE;
_glfw.glx.ARB_create_context_profile = true;
if (extensionSupportedGLX("GLX_EXT_create_context_es2_profile"))
_glfw.glx.EXT_create_context_es2_profile = GLFW_TRUE;
_glfw.glx.EXT_create_context_es2_profile = true;
if (extensionSupportedGLX("GLX_ARB_create_context_no_error"))
_glfw.glx.ARB_create_context_no_error = GLFW_TRUE;
_glfw.glx.ARB_create_context_no_error = true;
if (extensionSupportedGLX("GLX_ARB_context_flush_control"))
_glfw.glx.ARB_context_flush_control = GLFW_TRUE;
_glfw.glx.ARB_context_flush_control = true;
return GLFW_TRUE;
return true;
}
// Terminate GLX
@@ -435,14 +423,14 @@ void _glfwTerminateGLX(void)
#define setAttrib(a, v) \
{ \
assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \
attribs[index++] = v; \
}
// Create the OpenGL or OpenGL ES context
//
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
bool _glfwCreateContextGLX(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
@@ -457,7 +445,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"GLX: Failed to find a suitable GLXFBConfig");
return GLFW_FALSE;
return false;
}
if (ctxconfig->client == GLFW_OPENGL_ES_API)
@@ -468,7 +456,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"GLX: OpenGL ES requested but GLX_EXT_create_context_es2_profile is unavailable");
return GLFW_FALSE;
return false;
}
}
@@ -478,7 +466,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"GLX: Forward compatibility requested but GLX_ARB_create_context_profile is unavailable");
return GLFW_FALSE;
return false;
}
}
@@ -489,7 +477,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"GLX: An OpenGL profile requested but GLX_ARB_create_context_profile is unavailable");
return GLFW_FALSE;
return false;
}
}
@@ -554,7 +542,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
if (ctxconfig->noerror)
{
if (_glfw.glx.ARB_create_context_no_error)
setAttrib(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
setAttrib(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, true);
}
// NOTE: Only request an explicitly versioned context when necessary, as
@@ -590,7 +578,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
if (_glfw.x11.errorCode == _glfw.glx.errorBase + GLXBadProfileARB &&
ctxconfig->client == GLFW_OPENGL_API &&
ctxconfig->profile == GLFW_OPENGL_ANY_PROFILE &&
ctxconfig->forward == GLFW_FALSE)
ctxconfig->forward == false)
{
window->context.glx.handle =
createLegacyContextGLX(window, native, share);
@@ -608,7 +596,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
if (!window->context.glx.handle)
{
_glfwInputErrorX11(GLFW_VERSION_UNAVAILABLE, "GLX: Failed to create context");
return GLFW_FALSE;
return false;
}
window->context.glx.window =
@@ -616,7 +604,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
if (!window->context.glx.window)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to create window");
return GLFW_FALSE;
return false;
}
window->context.makeCurrent = makeContextCurrentGLX;
@@ -626,15 +614,15 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
window->context.getProcAddress = getProcAddressGLX;
window->context.destroy = destroyContextGLX;
return GLFW_TRUE;
return true;
}
#undef setAttrib
// Returns the Visual and depth of the chosen GLXFBConfig
//
GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
bool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig UNUSED,
const _GLFWctxconfig* ctxconfig UNUSED,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth)
{
@@ -645,7 +633,7 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"GLX: Failed to find a suitable GLXFBConfig");
return GLFW_FALSE;
return false;
}
result = glXGetVisualFromFBConfig(_glfw.x11.display, native);
@@ -653,14 +641,14 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"GLX: Failed to retrieve Visual for GLXFBConfig");
return GLFW_FALSE;
return false;
}
*visual = result->visual;
*depth = result->depth;
XFree(result);
return GLFW_TRUE;
return true;
}
@@ -695,4 +683,3 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
return window->context.glx.window;
}

39
glfw/glx_context.h vendored
View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 GLX - www.glfw.org
// GLFW 3.4 GLX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -107,8 +107,8 @@ typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display*,GLXFBConfig,GLX
#define glXCreateWindow _glfw.glx.CreateWindow
#define glXDestroyWindow _glfw.glx.DestroyWindow
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX glx
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX glx;
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx;
// GLX-specific per-context data
@@ -153,29 +153,28 @@ typedef struct _GLFWlibraryGLX
PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT;
PFNGLXSWAPINTERVALMESAPROC SwapIntervalMESA;
PFNGLXCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
GLFWbool SGI_swap_control;
GLFWbool EXT_swap_control;
GLFWbool MESA_swap_control;
GLFWbool ARB_multisample;
GLFWbool ARB_framebuffer_sRGB;
GLFWbool EXT_framebuffer_sRGB;
GLFWbool ARB_create_context;
GLFWbool ARB_create_context_profile;
GLFWbool ARB_create_context_robustness;
GLFWbool EXT_create_context_es2_profile;
GLFWbool ARB_create_context_no_error;
GLFWbool ARB_context_flush_control;
bool SGI_swap_control;
bool EXT_swap_control;
bool MESA_swap_control;
bool ARB_multisample;
bool ARB_framebuffer_sRGB;
bool EXT_framebuffer_sRGB;
bool ARB_create_context;
bool ARB_create_context_profile;
bool ARB_create_context_robustness;
bool EXT_create_context_es2_profile;
bool ARB_create_context_no_error;
bool ARB_context_flush_control;
} _GLFWlibraryGLX;
GLFWbool _glfwInitGLX(void);
bool _glfwInitGLX(void);
void _glfwTerminateGLX(void);
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
bool _glfwCreateContextGLX(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
void _glfwDestroyContextGLX(_GLFWwindow* window);
GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
bool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth);

78
glfw/ibus_glfw.c vendored
View File

@@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.3 XKB - www.glfw.org
// GLFW 3.4 XKB - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2018 Kovid Goyal <kovid@kovidgoyal.net>
//
@@ -50,14 +50,14 @@ enum Capabilities {
};
static inline GLFWbool
static inline bool
test_env_var(const char *name, const char *val) {
const char *q = getenv(name);
return (q && strcmp(q, val) == 0) ? GLFW_TRUE : GLFW_FALSE;
return (q && strcmp(q, val) == 0) ? true : false;
}
static inline size_t
MIN(size_t a, size_t b) {
GLFW_MIN(size_t a, size_t b) {
return a < b ? a : b;
}
@@ -117,7 +117,7 @@ send_text(const char *text, int state) {
// Connection handling {{{
static DBusHandlerResult
message_handler(DBusConnection *conn, DBusMessage *msg, void *user_data) {
message_handler(DBusConnection *conn UNUSED, DBusMessage *msg, void *user_data) {
// To monitor signals from IBUS, use
//  dbus-monitor --address `ibus address` "type='signal',interface='org.freedesktop.IBus.InputContext'"
_GLFWIBUSData *ibus = (_GLFWIBUSData*)user_data;
@@ -151,7 +151,7 @@ get_ibus_address_file_name(void) {
addr = getenv("IBUS_ADDRESS");
int offset = 0;
if (addr && addr[0]) {
memcpy(ans, addr, MIN(strlen(addr), sizeof(ans)));
memcpy(ans, addr, GLFW_MIN(strlen(addr), sizeof(ans)));
return ans;
}
@@ -193,39 +193,39 @@ get_ibus_address_file_name(void) {
}
static inline GLFWbool
static inline bool
read_ibus_address(_GLFWIBUSData *ibus) {
static char buf[1024];
struct stat s;
FILE *addr_file = fopen(ibus->address_file_name, "r");
if (!addr_file) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to open IBUS address file: %s with error: %s", ibus->address_file_name, strerror(errno));
return GLFW_FALSE;
return false;
}
int stat_result = fstat(fileno(addr_file), &s);
GLFWbool found = GLFW_FALSE;
bool found = false;
while (fgets(buf, sizeof(buf), addr_file)) {
if (strncmp(buf, "IBUS_ADDRESS=", sizeof("IBUS_ADDRESS=")-1) == 0) {
size_t sz = strlen(buf);
if (buf[sz-1] == '\n') buf[sz-1] = 0;
if (buf[sz-2] == '\r') buf[sz-2] = 0;
found = GLFW_TRUE;
found = true;
break;
}
}
fclose(addr_file); addr_file = NULL;
if (stat_result != 0) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to stat IBUS address file: %s with error: %s", ibus->address_file_name, strerror(errno));
return GLFW_FALSE;
return false;
}
ibus->address_file_mtime = s.st_mtime;
if (found) {
free((void*)ibus->address);
ibus->address = _glfw_strdup(buf + sizeof("IBUS_ADDRESS=") - 1);
return GLFW_TRUE;
return true;
}
_glfwInputError(GLFW_PLATFORM_ERROR, "Could not find IBUS_ADDRESS in %s", ibus->address_file_name);
return GLFW_FALSE;
return false;
}
void
@@ -245,35 +245,35 @@ input_context_created(DBusMessage *msg, const char* errmsg, void *data) {
dbus_connection_try_register_object_path(ibus->conn, ibus->input_ctx_path, &ibus_vtable, ibus, NULL);
enum Capabilities caps = IBUS_CAP_FOCUS | IBUS_CAP_PREEDIT_TEXT;
if (!glfw_dbus_call_method_no_reply(ibus->conn, IBUS_SERVICE, ibus->input_ctx_path, IBUS_INPUT_INTERFACE, "SetCapabilities", DBUS_TYPE_UINT32, &caps, DBUS_TYPE_INVALID)) return;
ibus->ok = GLFW_TRUE;
glfw_ibus_set_focused(ibus, GLFW_FALSE);
ibus->ok = true;
glfw_ibus_set_focused(ibus, false);
glfw_ibus_set_cursor_geometry(ibus, 0, 0, 0, 0);
debug("Connected to IBUS daemon for IME input management\n");
}
GLFWbool
bool
setup_connection(_GLFWIBUSData *ibus) {
const char *client_name = "GLFW_Application";
const char *address_file_name = get_ibus_address_file_name();
ibus->ok = GLFW_FALSE;
if (!address_file_name) return GLFW_FALSE;
ibus->ok = false;
if (!address_file_name) return false;
free((void*)ibus->address_file_name);
ibus->address_file_name = _glfw_strdup(address_file_name);
if (!read_ibus_address(ibus)) return GLFW_FALSE;
if (!read_ibus_address(ibus)) return false;
if (ibus->conn) {
glfw_dbus_close_connection(ibus->conn);
ibus->conn = NULL;
}
debug("Connecting to IBUS daemon @ %s for IME input management\n", ibus->address);
ibus->conn = glfw_dbus_connect_to(ibus->address, "Failed to connect to the IBUS daemon, with error", "ibus", GLFW_FALSE);
if (!ibus->conn) return GLFW_FALSE;
ibus->conn = glfw_dbus_connect_to(ibus->address, "Failed to connect to the IBUS daemon, with error", "ibus", false);
if (!ibus->conn) return false;
free((void*)ibus->input_ctx_path); ibus->input_ctx_path = NULL;
if (!glfw_dbus_call_method_with_reply(
ibus->conn, IBUS_SERVICE, IBUS_PATH, IBUS_INTERFACE, "CreateInputContext", DBUS_TIMEOUT_USE_DEFAULT, input_context_created, ibus,
DBUS_TYPE_STRING, &client_name, DBUS_TYPE_INVALID)) {
return GLFW_FALSE;
return false;
}
return GLFW_TRUE;
return true;
}
@@ -281,7 +281,7 @@ void
glfw_connect_to_ibus(_GLFWIBUSData *ibus) {
if (ibus->inited) return;
if (!test_env_var("GLFW_IM_MODULE", "ibus")) return;
ibus->inited = GLFW_TRUE;
ibus->inited = true;
setup_connection(ibus);
}
@@ -297,21 +297,21 @@ glfw_ibus_terminate(_GLFWIBUSData *ibus) {
F(address_file_name);
#undef F
ibus->ok = GLFW_FALSE;
ibus->ok = false;
}
static GLFWbool
static bool
check_connection(_GLFWIBUSData *ibus) {
if (!ibus->inited) return GLFW_FALSE;
if (!ibus->inited) return false;
if (ibus->conn && dbus_connection_get_is_connected(ibus->conn)) {
return ibus->ok;
}
struct stat s;
if (stat(ibus->address_file_name, &s) != 0 || s.st_mtime != ibus->address_file_mtime) {
if (!read_ibus_address(ibus)) return GLFW_FALSE;
if (!read_ibus_address(ibus)) return false;
setup_connection(ibus);
}
return GLFW_FALSE;
return false;
}
@@ -329,7 +329,7 @@ simple_message(_GLFWIBUSData *ibus, const char *method) {
}
void
glfw_ibus_set_focused(_GLFWIBUSData *ibus, GLFWbool focused) {
glfw_ibus_set_focused(_GLFWIBUSData *ibus, bool focused) {
simple_message(ibus, focused ? "FocusIn" : "FocusOut");
}
@@ -394,24 +394,24 @@ void
key_event_processed(DBusMessage *msg, const char* errmsg, void *data) {
uint32_t handled = 0;
KeyEvent *ev = (KeyEvent*)data;
GLFWbool is_release = ev->action == GLFW_RELEASE;
GLFWbool failed = GLFW_FALSE;
bool is_release = ev->action == GLFW_RELEASE;
bool failed = false;
if (errmsg) {
_glfwInputError(GLFW_PLATFORM_ERROR, "IBUS: Failed to process key with error: %s", errmsg);
failed = GLFW_TRUE;
failed = true;
} else {
glfw_dbus_get_args(msg, "Failed to get IBUS handled key from reply", DBUS_TYPE_BOOLEAN, &handled, DBUS_TYPE_INVALID);
debug("IBUS processed scancode: 0x%x release: %d handled: %u\n", ev->keycode, is_release, handled);
}
glfw_xkb_key_from_ime(ev, handled ? GLFW_TRUE : GLFW_FALSE, failed);
glfw_xkb_key_from_ime(ev, handled ? true : false, failed);
free(ev);
}
GLFWbool
bool
ibus_process_key(const KeyEvent *ev_, _GLFWIBUSData *ibus) {
if (!check_connection(ibus)) return GLFW_FALSE;
if (!check_connection(ibus)) return false;
KeyEvent *ev = malloc(sizeof(KeyEvent));
if (!ev) return GLFW_FALSE;
if (!ev) return false;
memcpy(ev, ev_, sizeof(KeyEvent));
uint32_t state = ibus_key_state(ev->glfw_modifiers, ev->action);
if (!glfw_dbus_call_method_with_reply(
@@ -420,7 +420,7 @@ ibus_process_key(const KeyEvent *ev_, _GLFWIBUSData *ibus) {
DBUS_TYPE_UINT32, &ev->ibus_sym, DBUS_TYPE_UINT32, &ev->ibus_keycode, DBUS_TYPE_UINT32,
&state, DBUS_TYPE_INVALID)) {
free(ev);
return GLFW_FALSE;
return false;
}
return GLFW_TRUE;
return true;
}

8
glfw/ibus_glfw.h vendored
View File

@@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.3 XKB - www.glfw.org
// GLFW 3.4 XKB - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2018 Kovid Goyal <kovid@kovidgoyal.net>
//
@@ -31,7 +31,7 @@
#include <xkbcommon/xkbcommon.h>
typedef struct {
GLFWbool ok, inited;
bool ok, inited;
time_t address_file_mtime;
DBusConnection *conn;
const char *input_ctx_path, *address_file_name, *address;
@@ -49,7 +49,7 @@ typedef struct {
void glfw_connect_to_ibus(_GLFWIBUSData *ibus);
void glfw_ibus_terminate(_GLFWIBUSData *ibus);
void glfw_ibus_set_focused(_GLFWIBUSData *ibus, GLFWbool focused);
void glfw_ibus_set_focused(_GLFWIBUSData *ibus, bool focused);
void glfw_ibus_dispatch(_GLFWIBUSData *ibus);
GLFWbool ibus_process_key(const KeyEvent *ev_, _GLFWIBUSData *ibus);
bool ibus_process_key(const KeyEvent *ev_, _GLFWIBUSData *ibus);
void glfw_ibus_set_cursor_geometry(_GLFWIBUSData *ibus, int x, int y, int w, int h);

36
glfw/init.c vendored
View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 - www.glfw.org
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -24,6 +24,8 @@
// distribution.
//
//========================================================================
// Please use C89 style variable declarations in this file because VS 2010
//========================================================================
#include "internal.h"
#include "mappings.h"
@@ -41,7 +43,7 @@
// Global state shared between compilation units of GLFW
//
_GLFWlibrary _glfw = { GLFW_FALSE };
_GLFWlibrary _glfw = { false };
// These are outside of _glfw so they can be used before initialization and
// after termination
@@ -50,12 +52,12 @@ static _GLFWerror _glfwMainThreadError;
static GLFWerrorfun _glfwErrorCallback;
static _GLFWinitconfig _glfwInitHints =
{
GLFW_TRUE, // hat buttons
GLFW_FALSE, // debug keyboard
GLFW_TRUE, // enable joystick
true, // hat buttons
false, // debug keyboard
true, // enable joystick
{
GLFW_TRUE, // macOS menu bar
GLFW_TRUE // macOS bundle chdir
true, // macOS menu bar
true // macOS bundle chdir
}
};
@@ -92,7 +94,7 @@ static void terminate(void)
_glfwTerminateVulkan();
_glfwPlatformTerminate();
_glfw.initialized = GLFW_FALSE;
_glfw.initialized = false;
while (_glfw.errorListHead)
{
@@ -215,7 +217,7 @@ _glfwDebug(const char *format, ...) {
GLFWAPI int glfwInit(void)
{
if (_glfw.initialized)
return GLFW_TRUE;
return true;
memset(&_glfw, 0, sizeof(_glfw));
_glfw.hints.init = _glfwInitHints;
@@ -223,7 +225,7 @@ GLFWAPI int glfwInit(void)
if (!_glfwPlatformInit())
{
terminate();
return GLFW_FALSE;
return false;
}
if (!_glfwPlatformCreateMutex(&_glfw.errorLock) ||
@@ -231,12 +233,12 @@ GLFWAPI int glfwInit(void)
!_glfwPlatformCreateTls(&_glfw.contextSlot))
{
terminate();
return GLFW_FALSE;
return false;
}
_glfwPlatformSetTls(&_glfw.errorSlot, &_glfwMainThreadError);
_glfw.initialized = GLFW_TRUE;
_glfw.initialized = true;
_glfw.timer.offset = _glfwPlatformGetTimerValue();
glfwDefaultWindowHints();
@@ -249,12 +251,12 @@ GLFWAPI int glfwInit(void)
if (!glfwUpdateGamepadMappings(_glfwDefaultMappings[i]))
{
terminate();
return GLFW_FALSE;
return false;
}
}
}
return GLFW_TRUE;
return true;
}
GLFWAPI void glfwTerminate(void)
@@ -342,10 +344,6 @@ GLFWAPI void glfwRunMainLoop(GLFWtickcallback callback, void *data)
_glfwPlatformRunMainLoop(callback, data);
}
GLFWAPI void glfwRequestTickCallback(void) {
_glfwPlatformRequestTickCallback();
}
GLFWAPI void glfwStopMainLoop(void) {
_GLFW_REQUIRE_INIT();
_glfwPlatformStopMainLoop();

97
glfw/input.c vendored
View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 - www.glfw.org
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -24,6 +24,8 @@
// distribution.
//
//========================================================================
// Please use C89 style variable declarations in this file because VS 2010
//========================================================================
#include "internal.h"
@@ -58,17 +60,17 @@ static _GLFWmapping* findMapping(const char* guid)
// Checks whether a gamepad mapping element is present in the hardware
//
static GLFWbool isValidElementForJoystick(const _GLFWmapelement* e,
static bool isValidElementForJoystick(const _GLFWmapelement* e,
const _GLFWjoystick* js)
{
if (e->type == _GLFW_JOYSTICK_HATBIT && (e->index >> 4) >= js->hatCount)
return GLFW_FALSE;
return false;
else if (e->type == _GLFW_JOYSTICK_BUTTON && e->index >= js->buttonCount)
return GLFW_FALSE;
return false;
else if (e->type == _GLFW_JOYSTICK_AXIS && e->index >= js->axisCount)
return GLFW_FALSE;
return false;
return GLFW_TRUE;
return true;
}
// Finds a mapping based on joystick GUID and verifies element indices
@@ -110,7 +112,7 @@ static _GLFWmapping* findValidMapping(const _GLFWjoystick* js)
// Parses an SDL_GameControllerDB line and adds it to the mapping list
//
static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
static bool parseMapping(_GLFWmapping* mapping, const char* string)
{
const char* c = string;
size_t i, length;
@@ -148,7 +150,7 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
if (length != 32 || c[length] != ',')
{
_glfwInputError(GLFW_INVALID_VALUE, NULL);
return GLFW_FALSE;
return false;
}
memcpy(mapping->guid, c, length);
@@ -158,7 +160,7 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
if (length >= sizeof(mapping->name) || c[length] != ',')
{
_glfwInputError(GLFW_INVALID_VALUE, NULL);
return GLFW_FALSE;
return false;
}
memcpy(mapping->name, c, length);
@@ -168,7 +170,7 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
{
// TODO: Implement output modifiers
if (*c == '+' || *c == '-')
return GLFW_FALSE;
return false;
for (i = 0; i < sizeof(fields) / sizeof(fields[0]); i++)
{
@@ -229,7 +231,7 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
{
length = strlen(_GLFW_PLATFORM_MAPPING_NAME);
if (strncmp(c, _GLFW_PLATFORM_MAPPING_NAME, length) != 0)
return GLFW_FALSE;
return false;
}
break;
@@ -246,7 +248,7 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
}
_glfwPlatformUpdateGamepadGUID(mapping->guid);
return GLFW_TRUE;
return true;
}
@@ -254,19 +256,19 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
////// GLFW event API //////
//////////////////////////////////////////////////////////////////////////
// Notifies shared code of a key event
// Notifies shared code of a physical key event
//
void _glfwInputKeyboard(_GLFWwindow* window, int key, int scancode, int action, int mods, const char* text, int state)
{
if (key >= 0 && key <= GLFW_KEY_LAST)
{
GLFWbool repeated = GLFW_FALSE;
bool repeated = false;
if (action == GLFW_RELEASE && window->keys[key] == GLFW_RELEASE)
return;
if (action == GLFW_PRESS && window->keys[key] == GLFW_PRESS)
repeated = GLFW_TRUE;
repeated = true;
if (action == GLFW_RELEASE && window->stickyKeys)
window->keys[key] = _GLFW_STICK;
@@ -328,7 +330,7 @@ void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos)
// Notifies shared code of a cursor enter/leave event
//
void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered)
void _glfwInputCursorEnter(_GLFWwindow* window, bool entered)
{
if (window->callbacks.cursorEnter)
window->callbacks.cursorEnter((GLFWwindow*) window, entered);
@@ -406,10 +408,10 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
return NULL;
js = _glfw.joysticks + jid;
js->present = GLFW_TRUE;
js->present = true;
js->name = _glfw_strdup(name);
js->axes = calloc(axisCount, sizeof(float));
js->buttons = calloc(buttonCount + hatCount * 4, 1);
js->buttons = calloc(buttonCount + (size_t) hatCount * 4, 1);
js->hats = calloc(hatCount, 1);
js->axisCount = axisCount;
js->buttonCount = buttonCount;
@@ -488,6 +490,7 @@ const char* _glfwGetKeyName(int key)
case GLFW_KEY_WORLD_1: return "WORLD 1";
case GLFW_KEY_WORLD_2: return "WORLD 2";
case GLFW_KEY_PLUS: return "PLUS";
case GLFW_KEY_UNDERSCORE: return "UNDERSCORE";
// Function keys
case GLFW_KEY_ESCAPE: return "ESCAPE";
@@ -546,7 +549,7 @@ const char* _glfwGetKeyName(int key)
case GLFW_KEY_KP_8: return "KEYPAD 8";
case GLFW_KEY_KP_9: return "KEYPAD 9";
case GLFW_KEY_KP_DIVIDE: return "KEYPAD DIVIDE";
case GLFW_KEY_KP_MULTIPLY: return "KEYPAD MULTPLY";
case GLFW_KEY_KP_MULTIPLY: return "KEYPAD MULTIPLY";
case GLFW_KEY_KP_SUBTRACT: return "KEYPAD SUBTRACT";
case GLFW_KEY_KP_ADD: return "KEYPAD ADD";
case GLFW_KEY_KP_DECIMAL: return "KEYPAD DECIMAL";
@@ -565,15 +568,17 @@ const char* _glfwGetKeyName(int key)
}
}
// Center the cursor in the middle of the content area of the specified window
// Center the cursor in the content area of the specified window
//
void _glfwCenterCursorInContentArea(_GLFWwindow* window)
{
int width, height;
_glfwPlatformGetWindowSize(window, &width, &height);
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
@@ -632,7 +637,7 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
}
else if (mode == GLFW_STICKY_KEYS)
{
value = value ? GLFW_TRUE : GLFW_FALSE;
value = value ? true : false;
if (window->stickyKeys == value)
return;
@@ -652,7 +657,7 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
}
else if (mode == GLFW_STICKY_MOUSE_BUTTONS)
{
value = value ? GLFW_TRUE : GLFW_FALSE;
value = value ? true : false;
if (window->stickyMouseButtons == value)
return;
@@ -671,7 +676,9 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
window->stickyMouseButtons = value;
}
else if (mode == GLFW_LOCK_KEY_MODS)
window->lockKeyMods = value ? GLFW_TRUE : GLFW_FALSE;
{
window->lockKeyMods = value ? true : false;
}
else
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
}
@@ -987,17 +994,17 @@ GLFWAPI int glfwJoystickPresent(int jid)
assert(jid >= GLFW_JOYSTICK_1);
assert(jid <= GLFW_JOYSTICK_LAST);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
_GLFW_REQUIRE_INIT_OR_RETURN(false);
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
return GLFW_FALSE;
return false;
}
js = _glfw.joysticks + jid;
if (!js->present)
return GLFW_FALSE;
return false;
return _glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE);
}
@@ -1189,7 +1196,7 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string)
assert(string != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
_GLFW_REQUIRE_INIT_OR_RETURN(false);
while (*c)
{
@@ -1239,7 +1246,7 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string)
js->mapping = findValidMapping(js);
}
return GLFW_TRUE;
return true;
}
GLFWAPI int glfwJoystickIsGamepad(int jid)
@@ -1249,20 +1256,20 @@ GLFWAPI int glfwJoystickIsGamepad(int jid)
assert(jid >= GLFW_JOYSTICK_1);
assert(jid <= GLFW_JOYSTICK_LAST);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
_GLFW_REQUIRE_INIT_OR_RETURN(false);
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
return GLFW_FALSE;
return false;
}
js = _glfw.joysticks + jid;
if (!js->present)
return GLFW_FALSE;
return false;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
return GLFW_FALSE;
return false;
return js->mapping != NULL;
}
@@ -1306,23 +1313,23 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
memset(state, 0, sizeof(GLFWgamepadstate));
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
_GLFW_REQUIRE_INIT_OR_RETURN(false);
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
return GLFW_FALSE;
return false;
}
js = _glfw.joysticks + jid;
if (!js->present)
return GLFW_FALSE;
return false;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_ALL))
return GLFW_FALSE;
return false;
if (!js->mapping)
return GLFW_FALSE;
return false;
for (i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++)
{
@@ -1358,15 +1365,17 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
const unsigned int bit = e->index & 0xf;
if (js->hats[hat] & bit)
state->axes[i] = 1.f;
else
state->axes[i] = -1.f;
}
else if (e->type == _GLFW_JOYSTICK_BUTTON)
state->axes[i] = (float) js->buttons[e->index];
state->axes[i] = js->buttons[e->index] * 2.f - 1.f;
}
return GLFW_TRUE;
return true;
}
GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
GLFWAPI void glfwSetClipboardString(GLFWwindow* handle UNUSED, const char* string)
{
assert(string != NULL);
@@ -1374,14 +1383,14 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
_glfwPlatformSetClipboardString(string);
}
GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle)
GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle UNUSED)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return _glfwPlatformGetClipboardString();
}
#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND)
GLFWAPI void glfwSetPrimarySelectionString(GLFWwindow* handle, const char* string)
GLFWAPI void glfwSetPrimarySelectionString(GLFWwindow* handle UNUSED, const char* string)
{
assert(string != NULL);
@@ -1389,7 +1398,7 @@ GLFWAPI void glfwSetPrimarySelectionString(GLFWwindow* handle, const char* strin
_glfwPlatformSetPrimarySelectionString(string);
}
GLFWAPI const char* glfwGetPrimarySelectionString(GLFWwindow* handle)
GLFWAPI const char* glfwGetPrimarySelectionString(GLFWwindow* handle UNUSED)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return _glfwPlatformGetPrimarySelectionString();

163
glfw/internal.h vendored
View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 - www.glfw.org
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -60,7 +60,6 @@
#define _GLFW_MESSAGE_SIZE 1024
typedef bool GLFWbool;
typedef unsigned long long GLFWid;
typedef struct _GLFWerror _GLFWerror;
@@ -196,6 +195,13 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void);
#error "No supported window creation API selected"
#endif
#define remove_i_from_array(array, i, count) { \
(count)--; \
if ((i) < (count)) { \
memmove((array) + (i), (array) + (i) + 1, sizeof((array)[0]) * ((count) - (i))); \
}}
// Constructs a version number string from the public header macros
#define _GLFW_CONCAT_VERSION(m, n, r) #m "." #n "." #r
#define _GLFW_MAKE_VERSION(m, n, r) _GLFW_CONCAT_VERSION(m, n, r)
@@ -219,12 +225,32 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void);
// Swaps the provided pointers
#define _GLFW_SWAP_POINTERS(x, y) \
{ \
void* t; \
do{ \
__typeof__(x) t; \
t = x; \
x = y; \
y = t; \
}
}while(0)
// Suppress some pedantic warnings
#ifdef __clang__
#define START_ALLOW_CASE_RANGE _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wpedantic\"")
#define END_ALLOW_CASE_RANGE _Pragma("clang diagnostic pop")
#define ALLOW_UNUSED_RESULT _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wunused-result\"")
#define END_ALLOW_UNUSED_RESULT _Pragma("clang diagnostic pop")
#else
#define START_ALLOW_CASE_RANGE _Pragma("GCC diagnostic ignored \"-Wpedantic\"")
#define END_ALLOW_CASE_RANGE _Pragma("GCC diagnostic pop")
#define ALLOW_UNUSED_RESULT _Pragma("GCC diagnostic ignored \"-Wunused-result\"")
#define END_ALLOW_UNUSED_RESULT _Pragma("GCC diagnostic pop")
#endif
// dlsym that works with -Wpedantic
#define glfw_dlsym(dest, handle, name) do {*(void **)&(dest) = _glfw_dlsym(handle, name);}while (0)
// Mark function arguments as unused
#define UNUSED __attribute__ ((unused))
// Per-thread error structure
//
@@ -241,12 +267,12 @@ struct _GLFWerror
//
struct _GLFWinitconfig
{
GLFWbool hatButtons;
GLFWbool debugKeyboard;
GLFWbool enableJoysticks;
bool hatButtons;
bool debugKeyboard;
bool enableJoysticks;
struct {
GLFWbool menubar;
GLFWbool chdir;
bool menubar;
bool chdir;
} ns;
};
@@ -261,18 +287,18 @@ struct _GLFWwndconfig
int width;
int height;
const char* title;
GLFWbool resizable;
GLFWbool visible;
GLFWbool decorated;
GLFWbool focused;
GLFWbool autoIconify;
GLFWbool floating;
GLFWbool maximized;
GLFWbool centerCursor;
GLFWbool focusOnShow;
GLFWbool scaleToMonitor;
bool resizable;
bool visible;
bool decorated;
bool focused;
bool autoIconify;
bool floating;
bool maximized;
bool centerCursor;
bool focusOnShow;
bool scaleToMonitor;
struct {
GLFWbool retina;
bool retina;
char frameName[256];
} ns;
struct {
@@ -296,15 +322,15 @@ struct _GLFWctxconfig
int source;
int major;
int minor;
GLFWbool forward;
GLFWbool debug;
GLFWbool noerror;
bool forward;
bool debug;
bool noerror;
int profile;
int robustness;
int release;
_GLFWwindow* share;
struct {
GLFWbool offline;
bool offline;
} nsgl;
};
@@ -329,11 +355,11 @@ struct _GLFWfbconfig
int accumBlueBits;
int accumAlphaBits;
int auxBuffers;
GLFWbool stereo;
bool stereo;
int samples;
GLFWbool sRGB;
GLFWbool doublebuffer;
GLFWbool transparent;
bool sRGB;
bool doublebuffer;
bool transparent;
uintptr_t handle;
};
@@ -344,7 +370,7 @@ struct _GLFWcontext
int client;
int source;
int major, minor, revision;
GLFWbool forward, debug, noerror;
bool forward, debug, noerror;
int profile;
int robustness;
int release;
@@ -361,7 +387,7 @@ struct _GLFWcontext
_GLFWdestroycontextfun destroy;
// This is defined in the context API's context.h
_GLFW_PLATFORM_CONTEXT_STATE;
_GLFW_PLATFORM_CONTEXT_STATE
// This is defined in egl_context.h
_GLFW_EGL_CONTEXT_STATE;
// This is defined in osmesa_context.h
@@ -375,12 +401,12 @@ struct _GLFWwindow
struct _GLFWwindow* next;
// Window settings and state
GLFWbool resizable;
GLFWbool decorated;
GLFWbool autoIconify;
GLFWbool floating;
GLFWbool focusOnShow;
GLFWbool shouldClose;
bool resizable;
bool decorated;
bool autoIconify;
bool floating;
bool focusOnShow;
bool shouldClose;
void* userPointer;
GLFWid id;
GLFWvidmode videoMode;
@@ -391,9 +417,9 @@ struct _GLFWwindow
int maxwidth, maxheight;
int numer, denom;
GLFWbool stickyKeys;
GLFWbool stickyMouseButtons;
GLFWbool lockKeyMods;
bool stickyKeys;
bool stickyMouseButtons;
bool lockKeyMods;
int cursorMode;
char mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1];
char keys[GLFW_KEY_LAST + 1];
@@ -484,7 +510,7 @@ struct _GLFWmapping
//
struct _GLFWjoystick
{
GLFWbool present;
bool present;
float* axes;
int axisCount;
unsigned char* buttons;
@@ -520,7 +546,7 @@ struct _GLFWmutex
//
struct _GLFWlibrary
{
GLFWbool initialized;
bool initialized;
struct {
_GLFWinitconfig init;
@@ -553,23 +579,23 @@ struct _GLFWlibrary
} timer;
struct {
GLFWbool available;
bool available;
void* handle;
char* extensions[2];
#if !defined(_GLFW_VULKAN_STATIC)
PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
#endif
GLFWbool KHR_surface;
bool KHR_surface;
#if defined(_GLFW_WIN32)
GLFWbool KHR_win32_surface;
bool KHR_win32_surface;
#elif defined(_GLFW_COCOA)
GLFWbool MVK_macos_surface;
bool MVK_macos_surface;
#elif defined(_GLFW_X11)
GLFWbool KHR_xlib_surface;
GLFWbool KHR_xcb_surface;
bool KHR_xlib_surface;
bool KHR_xcb_surface;
#elif defined(_GLFW_WAYLAND)
GLFWbool KHR_wayland_surface;
bool KHR_wayland_surface;
#endif
} vk;
@@ -581,9 +607,9 @@ struct _GLFWlibrary
// This is defined in the window API's platform.h
_GLFW_PLATFORM_LIBRARY_WINDOW_STATE;
// This is defined in the context API's context.h
_GLFW_PLATFORM_LIBRARY_CONTEXT_STATE;
_GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
// This is defined in the platform's joystick.h
_GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE;
_GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE
// This is defined in egl_context.h
_GLFW_EGL_LIBRARY_CONTEXT_STATE;
// This is defined in osmesa_context.h
@@ -622,7 +648,7 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height);
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count);
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode);
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
void _glfwPlatformSetClipboardString(const char* string);
@@ -682,9 +708,9 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window);
int _glfwPlatformWindowHovered(_GLFWwindow* window);
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window);
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window);
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled);
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled);
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled);
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, bool enabled);
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, bool enabled);
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, bool enabled);
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity);
void _glfwPlatformUpdateIMEState(_GLFWwindow *w, int which, int a, int b, int c, int d);
@@ -702,12 +728,12 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface);
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls);
bool _glfwPlatformCreateTls(_GLFWtls* tls);
void _glfwPlatformDestroyTls(_GLFWtls* tls);
void* _glfwPlatformGetTls(_GLFWtls* tls);
void _glfwPlatformSetTls(_GLFWtls* tls, void* value);
GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex);
bool _glfwPlatformCreateMutex(_GLFWmutex* mutex);
void _glfwPlatformDestroyMutex(_GLFWmutex* mutex);
void _glfwPlatformLockMutex(_GLFWmutex* mutex);
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex);
@@ -717,15 +743,15 @@ void _glfwPlatformUnlockMutex(_GLFWmutex* mutex);
////// GLFW event API //////
//////////////////////////////////////////////////////////////////////////
void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused);
void _glfwInputWindowOcclusion(_GLFWwindow* window, GLFWbool occluded);
void _glfwInputWindowFocus(_GLFWwindow* window, bool focused);
void _glfwInputWindowOcclusion(_GLFWwindow* window, bool occluded);
void _glfwInputWindowPos(_GLFWwindow* window, int xpos, int ypos);
void _glfwInputWindowSize(_GLFWwindow* window, int width, int height);
void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height);
void _glfwInputWindowContentScale(_GLFWwindow* window,
float xscale, float yscale);
void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified);
void _glfwInputWindowMaximize(_GLFWwindow* window, GLFWbool maximized);
void _glfwInputWindowIconify(_GLFWwindow* window, bool iconified);
void _glfwInputWindowMaximize(_GLFWwindow* window, bool maximized);
void _glfwInputWindowDamage(_GLFWwindow* window);
void _glfwInputWindowCloseRequest(_GLFWwindow* window);
void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor);
@@ -734,7 +760,7 @@ void _glfwInputKeyboard(_GLFWwindow* window, int key, int scancode, int action,
void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset, int flags);
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods);
void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos);
void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered);
void _glfwInputCursorEnter(_GLFWwindow* window, bool entered);
void _glfwInputDrop(_GLFWwindow* window, int count, const char** names);
void _glfwInputJoystick(_GLFWjoystick* js, int event);
void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value);
@@ -764,13 +790,13 @@ void _glfwDebug(const char* format, ...);
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions);
bool _glfwStringInExtensionString(const char* string, const char* extensions);
const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
const _GLFWfbconfig* alternatives,
unsigned int count);
GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
bool _glfwRefreshContextAttribs(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig);
GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig);
bool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig);
const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor,
const GLFWvidmode* desired);
@@ -790,16 +816,15 @@ void _glfwFreeJoystick(_GLFWjoystick* js);
const char* _glfwGetKeyName(int key);
void _glfwCenterCursorInContentArea(_GLFWwindow* window);
GLFWbool _glfwInitVulkan(int mode);
bool _glfwInitVulkan(int mode);
void _glfwTerminateVulkan(void);
const char* _glfwGetVulkanResultString(VkResult result);
_GLFWwindow* _glfwFocusedWindow(void);
_GLFWwindow* _glfwWindowForId(GLFWid id);
void _glfwPlatformRunMainLoop(GLFWtickcallback, void*);
void _glfwPlatformRequestTickCallback(void);
void _glfwPlatformStopMainLoop(void);
unsigned long long _glfwPlatformAddTimer(double interval, bool repeats, GLFWuserdatafun callback, void *callback_data, GLFWuserdatafun free_callback);
void _glfwPlatformUpdateTimer(unsigned long long timer_id, double interval, GLFWbool enabled);
void _glfwPlatformUpdateTimer(unsigned long long timer_id, double interval, bool enabled);
void _glfwPlatformRemoveTimer(unsigned long long timer_id);
char* _glfw_strdup(const char* source);

95
glfw/linux_joystick.c vendored
View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 Linux - www.glfw.org
// GLFW 3.4 Linux - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -24,6 +24,8 @@
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include "internal.h"
@@ -104,9 +106,7 @@ static void handleAbsEvent(_GLFWjoystick* js, int code, int value)
//
static void pollAbsState(_GLFWjoystick* js)
{
int code;
for (code = 0; code < ABS_CNT; code++)
for (int code = 0; code < ABS_CNT; code++)
{
if (js->linjs.absMap[code] < 0)
continue;
@@ -124,53 +124,52 @@ static void pollAbsState(_GLFWjoystick* js)
// Attempt to open the specified joystick device
//
static GLFWbool openJoystickDevice(const char* path)
static bool openJoystickDevice(const char* path)
{
int jid, code;
char name[256] = "";
char guid[33] = "";
char evBits[(EV_CNT + 7) / 8] = {0};
char keyBits[(KEY_CNT + 7) / 8] = {0};
char absBits[(ABS_CNT + 7) / 8] = {0};
int axisCount = 0, buttonCount = 0, hatCount = 0;
struct input_id id;
_GLFWjoystickLinux linjs = {0};
_GLFWjoystick* js = NULL;
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
if (!_glfw.joysticks[jid].present)
continue;
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
return GLFW_FALSE;
return false;
}
_GLFWjoystickLinux linjs = {0};
linjs.fd = open(path, O_RDONLY | O_NONBLOCK);
if (linjs.fd == -1)
return GLFW_FALSE;
return false;
if (ioctl(linjs.fd, EVIOCGBIT(0, sizeof(evBits)), evBits) < 0 ||
ioctl(linjs.fd, EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits) < 0 ||
ioctl(linjs.fd, EVIOCGBIT(EV_ABS, sizeof(absBits)), absBits) < 0 ||
ioctl(linjs.fd, EVIOCGID, &id) < 0)
char evBits[(EV_CNT + 7) / 8] = {0};
char keyBits[(KEY_CNT + 7) / 8] = {0};
char absBits[(ABS_CNT + 7) / 8] = {0};
struct input_id id;
if (ioctl(linjs.fd, (int32_t)EVIOCGBIT(0, sizeof(evBits)), evBits) < 0 ||
ioctl(linjs.fd, (int32_t)EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits) < 0 ||
ioctl(linjs.fd, (int32_t)EVIOCGBIT(EV_ABS, sizeof(absBits)), absBits) < 0 ||
ioctl(linjs.fd, (int32_t)EVIOCGID, &id) < 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Linux: Failed to query input device: %s",
strerror(errno));
close(linjs.fd);
return GLFW_FALSE;
return false;
}
// Ensure this device supports the events expected of a joystick
if (!isBitSet(EV_KEY, evBits) || !isBitSet(EV_ABS, evBits))
{
close(linjs.fd);
return GLFW_FALSE;
return false;
}
if (ioctl(linjs.fd, EVIOCGNAME(sizeof(name)), name) < 0)
char name[256] = "";
if (ioctl(linjs.fd, (int32_t)EVIOCGNAME(sizeof(name)), name) < 0)
strncpy(name, "Unknown", sizeof(name));
char guid[33] = "";
// Generate a joystick GUID that matches the SDL 2.0.5+ one
if (id.vendor && id.product && id.version)
{
@@ -189,7 +188,9 @@ static GLFWbool openJoystickDevice(const char* path)
name[8], name[9], name[10]);
}
for (code = BTN_MISC; code < KEY_CNT; code++)
int axisCount = 0, buttonCount = 0, hatCount = 0;
for (int code = BTN_MISC; code < KEY_CNT; code++)
{
if (!isBitSet(code, keyBits))
continue;
@@ -198,7 +199,7 @@ static GLFWbool openJoystickDevice(const char* path)
buttonCount++;
}
for (code = 0; code < ABS_CNT; code++)
for (int code = 0; code < ABS_CNT; code++)
{
linjs.absMap[code] = -1;
if (!isBitSet(code, absBits))
@@ -221,11 +222,11 @@ static GLFWbool openJoystickDevice(const char* path)
}
}
js = _glfwAllocJoystick(name, guid, axisCount, buttonCount, hatCount);
_GLFWjoystick* js = _glfwAllocJoystick(name, guid, axisCount, buttonCount, hatCount);
if (!js)
{
close(linjs.fd);
return GLFW_FALSE;
return false;
}
strncpy(linjs.path, path, sizeof(linjs.path) - 1);
@@ -234,7 +235,7 @@ static GLFWbool openJoystickDevice(const char* path)
pollAbsState(js);
_glfwInputJoystick(js, GLFW_CONNECTED);
return GLFW_TRUE;
return true;
}
#undef isBitSet
@@ -264,10 +265,8 @@ static int compareJoysticks(const void* fp, const void* sp)
// Initialize joystick interface
//
GLFWbool _glfwInitJoysticksLinux(void)
bool _glfwInitJoysticksLinux(void)
{
DIR* dir;
int count = 0;
const char* dirname = "/dev/input";
_glfw.linjs.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
@@ -286,10 +285,12 @@ GLFWbool _glfwInitJoysticksLinux(void)
if (regcomp(&_glfw.linjs.regex, "^event[0-9]\\+$", 0) != 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "Linux: Failed to compile regex");
return GLFW_FALSE;
return false;
}
dir = opendir(dirname);
int count = 0;
DIR* dir = opendir(dirname);
if (dir)
{
struct dirent* entry;
@@ -314,8 +315,8 @@ GLFWbool _glfwInitJoysticksLinux(void)
// Continue with no joysticks if enumeration fails
qsort(_glfw.joysticks, count, sizeof(_GLFWjoystick), compareJoysticks);
return GLFW_TRUE;
qsort(_glfw.joysticks, count, sizeof(_glfw.joysticks[0]), compareJoysticks);
return true;
}
// Close all opened joystick handles
@@ -344,12 +345,12 @@ void _glfwTerminateJoysticksLinux(void)
void _glfwDetectJoystickConnectionLinux(void)
{
ssize_t offset = 0;
char buffer[16384];
if (_glfw.linjs.inotify <= 0)
return;
ssize_t offset = 0;
char buffer[16384];
const ssize_t size = read(_glfw.linjs.inotify, buffer, sizeof(buffer));
while (size > offset)
@@ -369,9 +370,7 @@ void _glfwDetectJoystickConnectionLinux(void)
openJoystickDevice(path);
else if (e->mask & IN_DELETE)
{
int jid;
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
{
@@ -388,7 +387,7 @@ void _glfwDetectJoystickConnectionLinux(void)
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode UNUSED)
{
// Read all queued events (non-blocking)
for (;;)
@@ -408,10 +407,10 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
if (e.type == EV_SYN)
{
if (e.code == SYN_DROPPED)
_glfw.linjs.dropped = GLFW_TRUE;
_glfw.linjs.dropped = true;
else if (e.code == SYN_REPORT)
{
_glfw.linjs.dropped = GLFW_FALSE;
_glfw.linjs.dropped = false;
pollAbsState(js);
}
}
@@ -428,6 +427,6 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
return js->present;
}
void _glfwPlatformUpdateGamepadGUID(char* guid)
void _glfwPlatformUpdateGamepadGUID(char* guid UNUSED)
{
}

View File

@@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.3 Linux - www.glfw.org
// GLFW 3.4 Linux - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
//
@@ -29,7 +29,7 @@
#include <regex.h>
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickLinux linjs
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs;
#define _GLFW_PLATFORM_MAPPING_NAME "Linux"
@@ -52,11 +52,10 @@ typedef struct _GLFWlibraryLinux
int inotify;
int watch;
regex_t regex;
GLFWbool dropped;
bool dropped;
} _GLFWlibraryLinux;
GLFWbool _glfwInitJoysticksLinux(void);
bool _glfwInitJoysticksLinux(void);
void _glfwTerminateJoysticksLinux(void);
void _glfwDetectJoystickConnectionLinux(void);

3
glfw/linux_notify.c vendored
View File

@@ -43,8 +43,7 @@ notification_created(DBusMessage *msg, const char* errmsg, void *data) {
}
static DBusHandlerResult
message_handler(DBusConnection *conn, DBusMessage *msg, void *user_data) {
(void)(user_data);
message_handler(DBusConnection *conn UNUSED, DBusMessage *msg, void *user_data UNUSED) {
/* printf("session_bus message_handler invoked interface: %s member: %s\n", dbus_message_get_interface(msg), dbus_message_get_member(msg)); */
if (dbus_message_is_signal(msg, NOTIFICATIONS_IFACE, "ActionInvoked")) {
uint32_t notification_id;

19
glfw/main_loop.h vendored
View File

@@ -12,25 +12,28 @@
#define GLFW_LOOP_BACKEND x11
#endif
static GLFWbool keep_going = GLFW_FALSE;
static bool keep_going = false;
void _glfwPlatformRequestTickCallback() {
}
void _glfwPlatformStopMainLoop(void) {
if (keep_going) {
keep_going = GLFW_FALSE;
keep_going = false;
_glfwPlatformPostEmptyEvent();
}
}
void _glfwPlatformRunMainLoop(GLFWtickcallback tick_callback, void* data) {
keep_going = GLFW_TRUE;
keep_going = 1;
EventLoopData *eld = &_glfw.GLFW_LOOP_BACKEND.eventLoopData;
while(keep_going) {
_glfwPlatformWaitEvents();
EVDBG("loop tick");
tick_callback(data);
EVDBG("--------- loop tick, wakeups_happened: %d ----------", eld->wakeup_data_read);
if (eld->wakeup_data_read) {
eld->wakeup_data_read = false;
tick_callback(data);
}
}
EVDBG("main loop exiting");
}
unsigned long long _glfwPlatformAddTimer(double interval, bool repeats, GLFWuserdatafreefun callback, void *callback_data, GLFWuserdatafreefun free_callback) {
@@ -41,7 +44,7 @@ void _glfwPlatformRemoveTimer(unsigned long long timer_id) {
removeTimer(&_glfw.GLFW_LOOP_BACKEND.eventLoopData, timer_id);
}
void _glfwPlatformUpdateTimer(unsigned long long timer_id, double interval, GLFWbool enabled) {
void _glfwPlatformUpdateTimer(unsigned long long timer_id, double interval, bool enabled) {
changeTimerInterval(&_glfw.GLFW_LOOP_BACKEND.eventLoopData, timer_id, interval);
toggleTimer(&_glfw.GLFW_LOOP_BACKEND.eventLoopData, timer_id, enabled);
}

4
glfw/mappings.h vendored
View File

@@ -1,7 +1,7 @@
//========================================================================
// GLFW 3.3 - www.glfw.org
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages

34
glfw/monitor.c vendored
View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 - www.glfw.org
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -24,6 +24,8 @@
// distribution.
//
//========================================================================
// Please use C89 style variable declarations in this file because VS 2010
//========================================================================
#include "internal.h"
@@ -60,25 +62,25 @@ static int compareVideoModes(const void* fp, const void* sp)
// Retrieves the available modes for the specified monitor
//
static GLFWbool refreshVideoModes(_GLFWmonitor* monitor)
static bool refreshVideoModes(_GLFWmonitor* monitor)
{
int modeCount;
GLFWvidmode* modes;
if (monitor->modes)
return GLFW_TRUE;
return true;
modes = _glfwPlatformGetVideoModes(monitor, &modeCount);
if (!modes)
return GLFW_FALSE;
return false;
qsort(modes, modeCount, sizeof(GLFWvidmode), compareVideoModes);
qsort(modes, modeCount, sizeof(modes[0]), compareVideoModes);
free(monitor->modes);
monitor->modes = modes;
monitor->modeCount = modeCount;
return GLFW_TRUE;
return true;
}
@@ -100,7 +102,7 @@ void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement)
{
memmove(_glfw.monitors + 1,
_glfw.monitors,
(_glfw.monitorCount - 1) * sizeof(_GLFWmonitor*));
((size_t) _glfw.monitorCount - 1) * sizeof(_GLFWmonitor*));
_glfw.monitors[0] = monitor;
}
else
@@ -127,10 +129,7 @@ void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement)
{
if (_glfw.monitors[i] == monitor)
{
_glfw.monitorCount--;
memmove(_glfw.monitors + i,
_glfw.monitors + i + 1,
(_glfw.monitorCount - i) * sizeof(_GLFWmonitor*));
remove_i_from_array(_glfw.monitors, i, _glfw.monitorCount);
break;
}
}
@@ -330,7 +329,9 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos)
_glfwPlatformGetMonitorPos(monitor, xpos, ypos);
}
GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle, int* xpos, int* ypos, int* width, int* height)
GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle,
int* xpos, int* ypos,
int* width, int* height)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
@@ -451,7 +452,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
GLFWgammaramp ramp;
const GLFWgammaramp* original;
assert(handle != NULL);
assert(gamma >= 0.f);
assert(gamma > 0.f);
assert(gamma <= FLT_MAX);
_GLFW_REQUIRE_INIT();
@@ -461,6 +462,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
_glfwInputError(GLFW_INVALID_VALUE, "Invalid gamma value %f", gamma);
return;
}
original = glfwGetGammaRamp(handle);
if (!original)
return;
@@ -475,10 +477,8 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
value = i / (float) (original->size - 1);
// Apply gamma curve
value = powf(value, 1.f / gamma) * 65535.f + 0.5f;
// Clamp to value range
if (value > 65535.f)
value = 65535.f;
value = fminf(value, 65535.f);
values[i] = (unsigned short) value;
}

13
glfw/nsgl_context.h vendored
View File

@@ -1,7 +1,7 @@
//========================================================================
// GLFW 3.3 macOS - www.glfw.org
// GLFW 3.4 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -24,8 +24,8 @@
//
//========================================================================
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL nsgl
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL nsgl;
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl;
// NSGL-specific per-context data
@@ -47,10 +47,9 @@ typedef struct _GLFWlibraryNSGL
} _GLFWlibraryNSGL;
GLFWbool _glfwInitNSGL(void);
bool _glfwInitNSGL(void);
void _glfwTerminateNSGL(void);
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
bool _glfwCreateContextNSGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
void _glfwDestroyContextNSGL(_GLFWwindow* window);

View File

@@ -1,7 +1,7 @@
//========================================================================
// GLFW 3.3 macOS - www.glfw.org
// GLFW 3.4 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -23,6 +23,8 @@
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include "internal.h"
@@ -43,18 +45,17 @@ static void swapBuffersNSGL(_GLFWwindow* window)
[window->context.nsgl.object flushBuffer];
}
static void swapIntervalNSGL(int interval)
static void swapIntervalNSGL(int interval UNUSED)
{
// As of Mojave this does not work so we use CVDisplayLink instead
(void)(interval);
_glfwInputError(GLFW_API_UNAVAILABLE,
"NSGL: Swap intervals do not work on macOS");
}
static int extensionSupportedNSGL(const char* extension)
static int extensionSupportedNSGL(const char* extension UNUSED)
{
// There are no NSGL extensions
return GLFW_FALSE;
return false;
}
static GLFWglproc getProcAddressNSGL(const char* procname)
@@ -63,16 +64,15 @@ static GLFWglproc getProcAddressNSGL(const char* procname)
procname,
kCFStringEncodingASCII);
GLFWglproc symbol = CFBundleGetFunctionPointerForName(_glfw.nsgl.framework,
symbolName);
GLFWglproc symbol;
*(void **) &symbol = CFBundleGetFunctionPointerForName(_glfw.nsgl.framework,
symbolName);
CFRelease(symbolName);
return symbol;
}
// Destroy the OpenGL context
//
static void destroyContextNSGL(_GLFWwindow* window)
{
[window->context.nsgl.pixelFormat release];
@@ -89,10 +89,10 @@ static void destroyContextNSGL(_GLFWwindow* window)
// Initialize OpenGL support
//
GLFWbool _glfwInitNSGL(void)
bool _glfwInitNSGL(void)
{
if (_glfw.nsgl.framework)
return GLFW_TRUE;
return true;
_glfw.nsgl.framework =
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
@@ -100,10 +100,10 @@ GLFWbool _glfwInitNSGL(void)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"NSGL: Failed to locate OpenGL framework");
return GLFW_FALSE;
return false;
}
return GLFW_TRUE;
return true;
}
// Terminate OpenGL support
@@ -114,7 +114,7 @@ void _glfwTerminateNSGL(void)
// Create the OpenGL context
//
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
bool _glfwCreateContextNSGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
@@ -122,7 +122,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"NSGL: OpenGL ES is not available on macOS");
return GLFW_FALSE;
return false;
}
if (ctxconfig->major > 2)
@@ -131,14 +131,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"NSGL: The targeted version of macOS does not support OpenGL 3.0 or 3.1 but may support 3.2 and above");
return GLFW_FALSE;
}
if (!ctxconfig->forward || ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"NSGL: The targeted version of macOS only supports forward-compatible core profile contexts for OpenGL 3.2 and above");
return GLFW_FALSE;
return false;
}
}
@@ -239,7 +232,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"NSGL: Stereo rendering is deprecated");
return GLFW_FALSE;
return false;
#else
addAttrib(NSOpenGLPFAStereo);
#endif
@@ -275,7 +268,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"NSGL: Failed to find a suitable pixel format");
return GLFW_FALSE;
return false;
}
NSOpenGLContext* share = NULL;
@@ -290,13 +283,14 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"NSGL: Failed to create OpenGL context");
return GLFW_FALSE;
return false;
}
if (fbconfig->transparent)
{
GLint opaque = 0;
[window->context.nsgl.object setValues:&opaque forParameter:NSOpenGLContextParameterSurfaceOpacity];
[window->context.nsgl.object setValues:&opaque
forParameter:NSOpenGLContextParameterSurfaceOpacity];
}
if (window->ns.retina)
@@ -315,7 +309,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
window->context.getProcAddress = getProcAddressNSGL;
window->context.destroy = destroyContextNSGL;
return GLFW_TRUE;
return true;
}

8
glfw/null_init.c vendored
View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 - www.glfw.org
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -24,6 +24,8 @@
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include "internal.h"
@@ -35,7 +37,7 @@
int _glfwPlatformInit(void)
{
_glfwInitTimerPOSIX();
return GLFW_TRUE;
return true;
}
void _glfwPlatformTerminate(void)

View File

@@ -1,7 +1,7 @@
//========================================================================
// GLFW 3.3 - www.glfw.org
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -23,6 +23,8 @@
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include "internal.h"
@@ -33,7 +35,7 @@
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
{
return GLFW_FALSE;
return false;
}
void _glfwPlatformUpdateGamepadGUID(char* guid)

View File

@@ -1,7 +1,7 @@
//========================================================================
// GLFW 3.3 - www.glfw.org
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -25,7 +25,6 @@
//========================================================================
#define _GLFW_PLATFORM_JOYSTICK_STATE int nulljs
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE int nulljs
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE int nulljs;
#define _GLFW_PLATFORM_MAPPING_NAME ""

15
glfw/null_monitor.c vendored
View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 - www.glfw.org
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2016-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -24,6 +24,8 @@
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include "internal.h"
@@ -49,7 +51,9 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
*yscale = 1.f;
}
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height)
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
int* xpos, int* ypos,
int* width, int* height)
{
}
@@ -62,11 +66,12 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
{
}
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{
return GLFW_FALSE;
return false;
}
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{
}

View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 - www.glfw.org
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages

47
glfw/null_window.c vendored
View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 - www.glfw.org
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2016-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -24,6 +24,8 @@
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include "internal.h"
@@ -34,7 +36,7 @@ static int createNativeWindow(_GLFWwindow* window,
window->null.width = wndconfig->width;
window->null.height = wndconfig->height;
return GLFW_TRUE;
return true;
}
@@ -48,7 +50,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
const _GLFWfbconfig* fbconfig)
{
if (!createNativeWindow(window, wndconfig))
return GLFW_FALSE;
return false;
if (ctxconfig->client != GLFW_NO_API)
{
@@ -56,18 +58,18 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
{
if (!_glfwInitOSMesa())
return GLFW_FALSE;
return false;
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
return GLFW_FALSE;
return false;
}
else
{
_glfwInputError(GLFW_API_UNAVAILABLE, "Null: EGL not available");
return GLFW_FALSE;
return false;
}
}
return GLFW_TRUE;
return true;
}
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
@@ -167,28 +169,28 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
int _glfwPlatformWindowMaximized(_GLFWwindow* window)
{
return GLFW_FALSE;
return false;
}
int _glfwPlatformWindowHovered(_GLFWwindow* window)
{
return GLFW_FALSE;
return false;
}
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
{
return GLFW_FALSE;
return false;
}
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, bool enabled)
{
}
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, bool enabled)
{
}
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, bool enabled)
{
}
@@ -212,7 +214,7 @@ void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
int _glfwPlatformWindowBell(_GLFWwindow* window)
{
return GLFW_FALSE;
return false;
}
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
@@ -229,22 +231,22 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window)
int _glfwPlatformWindowFocused(_GLFWwindow* window)
{
return GLFW_FALSE;
return false;
}
int _glfwPlatformWindowOccluded(_GLFWwindow* window)
{
return GLFW_FALSE;
return false;
}
int _glfwPlatformWindowIconified(_GLFWwindow* window)
{
return GLFW_FALSE;
return false;
}
int _glfwPlatformWindowVisible(_GLFWwindow* window)
{
return GLFW_FALSE;
return false;
}
void _glfwPlatformPollEvents(void)
@@ -279,12 +281,12 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
const GLFWimage* image,
int xhot, int yhot, int count)
{
return GLFW_TRUE;
return true;
}
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
{
return GLFW_TRUE;
return true;
}
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
@@ -322,7 +324,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
return GLFW_FALSE;
return false;
}
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
@@ -333,3 +335,4 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
// This seems like the most appropriate error to return here
return VK_ERROR_INITIALIZATION_FAILED;
}

73
glfw/osmesa_context.c vendored
View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 OSMesa - www.glfw.org
// GLFW 3.4 OSMesa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -24,6 +24,8 @@
// distribution.
//
//========================================================================
// Please use C89 style variable declarations in this file because VS 2010
//========================================================================
#include <stdlib.h>
#include <string.h>
@@ -47,7 +49,7 @@ static void makeContextCurrentOSMesa(_GLFWwindow* window)
free(window->context.osmesa.buffer);
// Allocate the new buffer (width * height * 8-bit RGBA)
window->context.osmesa.buffer = calloc(4, width * height);
window->context.osmesa.buffer = calloc(4, (size_t) width * height);
window->context.osmesa.width = width;
window->context.osmesa.height = height;
}
@@ -87,20 +89,20 @@ static void destroyContextOSMesa(_GLFWwindow* window)
}
}
static void swapBuffersOSMesa(_GLFWwindow* window)
static void swapBuffersOSMesa(_GLFWwindow* window UNUSED)
{
// No double buffering on OSMesa
}
static void swapIntervalOSMesa(int interval)
static void swapIntervalOSMesa(int interval UNUSED)
{
// No swap interval on OSMesa
}
static int extensionSupportedOSMesa(const char* extension)
static int extensionSupportedOSMesa(const char* extension UNUSED)
{
// OSMesa does not have extensions
return GLFW_FALSE;
return false;
}
@@ -108,7 +110,7 @@ static int extensionSupportedOSMesa(const char* extension)
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwInitOSMesa(void)
bool _glfwInitOSMesa(void)
{
int i;
const char* sonames[] =
@@ -130,7 +132,7 @@ GLFWbool _glfwInitOSMesa(void)
};
if (_glfw.osmesa.handle)
return GLFW_TRUE;
return true;
for (i = 0; sonames[i]; i++)
{
@@ -142,23 +144,16 @@ GLFWbool _glfwInitOSMesa(void)
if (!_glfw.osmesa.handle)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "OSMesa: Library not found");
return GLFW_FALSE;
return false;
}
_glfw.osmesa.CreateContextExt = (PFN_OSMesaCreateContextExt)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaCreateContextExt");
_glfw.osmesa.CreateContextAttribs = (PFN_OSMesaCreateContextAttribs)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaCreateContextAttribs");
_glfw.osmesa.DestroyContext = (PFN_OSMesaDestroyContext)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaDestroyContext");
_glfw.osmesa.MakeCurrent = (PFN_OSMesaMakeCurrent)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaMakeCurrent");
_glfw.osmesa.GetColorBuffer = (PFN_OSMesaGetColorBuffer)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetColorBuffer");
_glfw.osmesa.GetDepthBuffer = (PFN_OSMesaGetDepthBuffer)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetDepthBuffer");
_glfw.osmesa.GetProcAddress = (PFN_OSMesaGetProcAddress)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetProcAddress");
glfw_dlsym(_glfw.osmesa.CreateContextExt, _glfw.osmesa.handle, "OSMesaCreateContextExt");
glfw_dlsym(_glfw.osmesa.CreateContextAttribs, _glfw.osmesa.handle, "OSMesaCreateContextAttribs");
glfw_dlsym(_glfw.osmesa.DestroyContext, _glfw.osmesa.handle, "OSMesaDestroyContext");
glfw_dlsym(_glfw.osmesa.MakeCurrent, _glfw.osmesa.handle, "OSMesaMakeCurrent");
glfw_dlsym(_glfw.osmesa.GetColorBuffer, _glfw.osmesa.handle, "OSMesaGetColorBuffer");
glfw_dlsym(_glfw.osmesa.GetDepthBuffer, _glfw.osmesa.handle, "OSMesaGetDepthBuffer");
glfw_dlsym(_glfw.osmesa.GetProcAddress, _glfw.osmesa.handle, "OSMesaGetProcAddress");
if (!_glfw.osmesa.CreateContextExt ||
!_glfw.osmesa.DestroyContext ||
@@ -171,10 +166,10 @@ GLFWbool _glfwInitOSMesa(void)
"OSMesa: Failed to load required entry points");
_glfwTerminateOSMesa();
return GLFW_FALSE;
return false;
}
return GLFW_TRUE;
return true;
}
void _glfwTerminateOSMesa(void)
@@ -188,12 +183,12 @@ void _glfwTerminateOSMesa(void)
#define setAttrib(a, v) \
{ \
assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \
attribs[index++] = v; \
}
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
bool _glfwCreateContextOSMesa(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
@@ -207,7 +202,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"OSMesa: OpenGL ES is not available on OSMesa");
return GLFW_FALSE;
return false;
}
if (ctxconfig->share)
@@ -241,7 +236,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"OSMesa: Forward-compatible contexts not supported");
return GLFW_FALSE;
return false;
}
setAttrib(0, 0);
@@ -255,7 +250,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"OSMesa: OpenGL profiles unavailable");
return GLFW_FALSE;
return false;
}
window->context.osmesa.handle =
@@ -270,7 +265,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"OSMesa: Failed to create context");
return GLFW_FALSE;
return false;
}
window->context.makeCurrent = makeContextCurrentOSMesa;
@@ -280,7 +275,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
window->context.getProcAddress = getProcAddressOSMesa;
window->context.destroy = destroyContextOSMesa;
return GLFW_TRUE;
return true;
}
#undef setAttrib
@@ -298,7 +293,7 @@ GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width,
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
_GLFW_REQUIRE_INIT_OR_RETURN(false);
if (!OSMesaGetColorBuffer(window->context.osmesa.handle,
&mesaWidth, &mesaHeight,
@@ -306,7 +301,7 @@ GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width,
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"OSMesa: Failed to retrieve color buffer");
return GLFW_FALSE;
return false;
}
if (width)
@@ -318,7 +313,7 @@ GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width,
if (buffer)
*buffer = mesaBuffer;
return GLFW_TRUE;
return true;
}
GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
@@ -331,7 +326,7 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
_GLFW_REQUIRE_INIT_OR_RETURN(false);
if (!OSMesaGetDepthBuffer(window->context.osmesa.handle,
&mesaWidth, &mesaHeight,
@@ -339,7 +334,7 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"OSMesa: Failed to retrieve depth buffer");
return GLFW_FALSE;
return false;
}
if (width)
@@ -351,7 +346,7 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
if (buffer)
*buffer = mesaBuffer;
return GLFW_TRUE;
return true;
}
GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle)

View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 OSMesa - www.glfw.org
// GLFW 3.4 OSMesa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -86,9 +86,9 @@ typedef struct _GLFWlibraryOSMesa
} _GLFWlibraryOSMesa;
GLFWbool _glfwInitOSMesa(void);
bool _glfwInitOSMesa(void);
void _glfwTerminateOSMesa(void);
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
bool _glfwCreateContextOSMesa(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);

32
glfw/posix_thread.c vendored
View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 POSIX - www.glfw.org
// GLFW 3.4 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -24,6 +24,8 @@
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include "internal.h"
@@ -35,19 +37,19 @@
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls)
bool _glfwPlatformCreateTls(_GLFWtls* tls)
{
assert(tls->posix.allocated == GLFW_FALSE);
assert(tls->posix.allocated == false);
if (pthread_key_create(&tls->posix.key, NULL) != 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"POSIX: Failed to create context TLS");
return GLFW_FALSE;
return false;
}
tls->posix.allocated = GLFW_TRUE;
return GLFW_TRUE;
tls->posix.allocated = true;
return true;
}
void _glfwPlatformDestroyTls(_GLFWtls* tls)
@@ -59,27 +61,27 @@ void _glfwPlatformDestroyTls(_GLFWtls* tls)
void* _glfwPlatformGetTls(_GLFWtls* tls)
{
assert(tls->posix.allocated == GLFW_TRUE);
assert(tls->posix.allocated == true);
return pthread_getspecific(tls->posix.key);
}
void _glfwPlatformSetTls(_GLFWtls* tls, void* value)
{
assert(tls->posix.allocated == GLFW_TRUE);
assert(tls->posix.allocated == true);
pthread_setspecific(tls->posix.key, value);
}
GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex)
bool _glfwPlatformCreateMutex(_GLFWmutex* mutex)
{
assert(mutex->posix.allocated == GLFW_FALSE);
assert(mutex->posix.allocated == false);
if (pthread_mutex_init(&mutex->posix.handle, NULL) != 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "POSIX: Failed to create mutex");
return GLFW_FALSE;
return false;
}
return mutex->posix.allocated = GLFW_TRUE;
return mutex->posix.allocated = true;
}
void _glfwPlatformDestroyMutex(_GLFWmutex* mutex)
@@ -91,13 +93,13 @@ void _glfwPlatformDestroyMutex(_GLFWmutex* mutex)
void _glfwPlatformLockMutex(_GLFWmutex* mutex)
{
assert(mutex->posix.allocated == GLFW_TRUE);
assert(mutex->posix.allocated == true);
pthread_mutex_lock(&mutex->posix.handle);
}
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex)
{
assert(mutex->posix.allocated == GLFW_TRUE);
assert(mutex->posix.allocated == true);
pthread_mutex_unlock(&mutex->posix.handle);
}

8
glfw/posix_thread.h vendored
View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 POSIX - www.glfw.org
// GLFW 3.4 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -35,7 +35,7 @@
//
typedef struct _GLFWtlsPOSIX
{
GLFWbool allocated;
bool allocated;
pthread_key_t key;
} _GLFWtlsPOSIX;
@@ -44,7 +44,7 @@ typedef struct _GLFWtlsPOSIX
//
typedef struct _GLFWmutexPOSIX
{
GLFWbool allocated;
bool allocated;
pthread_mutex_t handle;
} _GLFWmutexPOSIX;

10
glfw/posix_time.c vendored
View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 POSIX - www.glfw.org
// GLFW 3.4 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -24,6 +24,8 @@
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include "internal.h"
@@ -44,13 +46,13 @@ void _glfwInitTimerPOSIX(void)
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
{
_glfw.timer.posix.monotonic = GLFW_TRUE;
_glfw.timer.posix.monotonic = true;
_glfw.timer.posix.frequency = 1000000000;
}
else
#endif
{
_glfw.timer.posix.monotonic = GLFW_FALSE;
_glfw.timer.posix.monotonic = false;
_glfw.timer.posix.frequency = 1000000;
}
}

6
glfw/posix_time.h vendored
View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 POSIX - www.glfw.org
// GLFW 3.4 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -34,7 +34,7 @@
//
typedef struct _GLFWtimerPOSIX
{
GLFWbool monotonic;
bool monotonic;
uint64_t frequency;
} _GLFWtimerPOSIX;

48
glfw/vulkan.c vendored
View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 - www.glfw.org
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -24,6 +24,8 @@
// distribution.
//
//========================================================================
// Please use C89 style variable declarations in this file because VS 2010
//========================================================================
#include "internal.h"
@@ -39,14 +41,14 @@
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwInitVulkan(int mode)
bool _glfwInitVulkan(int mode)
{
VkResult err;
VkExtensionProperties* ep;
uint32_t i, count;
if (_glfw.vk.available)
return GLFW_TRUE;
return true;
#if !defined(_GLFW_VULKAN_STATIC)
#if defined(_GLFW_VULKAN_LIBRARY)
@@ -63,10 +65,10 @@ GLFWbool _glfwInitVulkan(int mode)
if (mode == _GLFW_REQUIRE_LOADER)
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found");
return GLFW_FALSE;
return false;
}
_glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)
*(void **) &_glfw.vk.GetInstanceProcAddr =
_glfw_dlsym(_glfw.vk.handle, "vkGetInstanceProcAddr");
if (!_glfw.vk.GetInstanceProcAddr)
{
@@ -74,7 +76,7 @@ GLFWbool _glfwInitVulkan(int mode)
"Vulkan: Loader does not export vkGetInstanceProcAddr");
_glfwTerminateVulkan();
return GLFW_FALSE;
return false;
}
_glfw.vk.EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)
@@ -85,7 +87,7 @@ GLFWbool _glfwInitVulkan(int mode)
"Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties");
_glfwTerminateVulkan();
return GLFW_FALSE;
return false;
}
#endif // _GLFW_VULKAN_STATIC
@@ -101,7 +103,7 @@ GLFWbool _glfwInitVulkan(int mode)
}
_glfwTerminateVulkan();
return GLFW_FALSE;
return false;
}
ep = calloc(count, sizeof(VkExtensionProperties));
@@ -115,37 +117,37 @@ GLFWbool _glfwInitVulkan(int mode)
free(ep);
_glfwTerminateVulkan();
return GLFW_FALSE;
return false;
}
for (i = 0; i < count; i++)
{
if (strcmp(ep[i].extensionName, "VK_KHR_surface") == 0)
_glfw.vk.KHR_surface = GLFW_TRUE;
_glfw.vk.KHR_surface = true;
#if defined(_GLFW_WIN32)
else if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0)
_glfw.vk.KHR_win32_surface = GLFW_TRUE;
_glfw.vk.KHR_win32_surface = true;
#elif defined(_GLFW_COCOA)
else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0)
_glfw.vk.MVK_macos_surface = GLFW_TRUE;
_glfw.vk.MVK_macos_surface = true;
#elif defined(_GLFW_X11)
else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0)
_glfw.vk.KHR_xlib_surface = GLFW_TRUE;
_glfw.vk.KHR_xlib_surface = true;
else if (strcmp(ep[i].extensionName, "VK_KHR_xcb_surface") == 0)
_glfw.vk.KHR_xcb_surface = GLFW_TRUE;
_glfw.vk.KHR_xcb_surface = true;
#elif defined(_GLFW_WAYLAND)
else if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0)
_glfw.vk.KHR_wayland_surface = GLFW_TRUE;
_glfw.vk.KHR_wayland_surface = true;
#endif
}
free(ep);
_glfw.vk.available = GLFW_TRUE;
_glfw.vk.available = true;
_glfwPlatformGetRequiredInstanceExtensions(_glfw.vk.extensions);
return GLFW_TRUE;
return true;
}
void _glfwTerminateVulkan(void)
@@ -218,7 +220,7 @@ const char* _glfwGetVulkanResultString(VkResult result)
GLFWAPI int glfwVulkanSupported(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
_GLFW_REQUIRE_INIT_OR_RETURN(false);
return _glfwInitVulkan(_GLFW_FIND_LOADER);
}
@@ -260,7 +262,7 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance,
}
#else
if (!proc)
proc = (GLFWvkproc) _glfw_dlsym(_glfw.vk.handle, procname);
*(void **) &proc = _glfw_dlsym(_glfw.vk.handle, procname);
#endif
return proc;
@@ -273,16 +275,16 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance,
assert(instance != VK_NULL_HANDLE);
assert(device != VK_NULL_HANDLE);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
_GLFW_REQUIRE_INIT_OR_RETURN(false);
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
return GLFW_FALSE;
return false;
if (!_glfw.vk.extensions[0])
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Vulkan: Window surface creation extensions not found");
return GLFW_FALSE;
return false;
}
return _glfwPlatformGetPhysicalDevicePresentationSupport(instance,

743
glfw/wgl_context.c vendored
View File

@@ -1,743 +0,0 @@
//========================================================================
// GLFW 3.3 WGL - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#include <stdlib.h>
#include <malloc.h>
#include <assert.h>
// Returns the specified attribute of the specified pixel format
//
static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib)
{
int value = 0;
assert(_glfw.wgl.ARB_pixel_format);
if (!_glfw.wgl.GetPixelFormatAttribivARB(window->context.wgl.dc,
pixelFormat,
0, 1, &attrib, &value))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to retrieve pixel format attribute");
return 0;
}
return value;
}
// Return a list of available and usable framebuffer configs
//
static int choosePixelFormat(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
_GLFWfbconfig* usableConfigs;
const _GLFWfbconfig* closest;
int i, pixelFormat, nativeCount, usableCount;
if (_glfw.wgl.ARB_pixel_format)
{
nativeCount = getPixelFormatAttrib(window,
1,
WGL_NUMBER_PIXEL_FORMATS_ARB);
}
else
{
nativeCount = DescribePixelFormat(window->context.wgl.dc,
1,
sizeof(PIXELFORMATDESCRIPTOR),
NULL);
}
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
usableCount = 0;
for (i = 0; i < nativeCount; i++)
{
const int n = i + 1;
_GLFWfbconfig* u = usableConfigs + usableCount;
if (_glfw.wgl.ARB_pixel_format)
{
// Get pixel format attributes through "modern" extension
if (!getPixelFormatAttrib(window, n, WGL_SUPPORT_OPENGL_ARB) ||
!getPixelFormatAttrib(window, n, WGL_DRAW_TO_WINDOW_ARB))
{
continue;
}
if (getPixelFormatAttrib(window, n, WGL_PIXEL_TYPE_ARB) !=
WGL_TYPE_RGBA_ARB)
{
continue;
}
if (getPixelFormatAttrib(window, n, WGL_ACCELERATION_ARB) ==
WGL_NO_ACCELERATION_ARB)
{
continue;
}
u->redBits = getPixelFormatAttrib(window, n, WGL_RED_BITS_ARB);
u->greenBits = getPixelFormatAttrib(window, n, WGL_GREEN_BITS_ARB);
u->blueBits = getPixelFormatAttrib(window, n, WGL_BLUE_BITS_ARB);
u->alphaBits = getPixelFormatAttrib(window, n, WGL_ALPHA_BITS_ARB);
u->depthBits = getPixelFormatAttrib(window, n, WGL_DEPTH_BITS_ARB);
u->stencilBits = getPixelFormatAttrib(window, n, WGL_STENCIL_BITS_ARB);
u->accumRedBits = getPixelFormatAttrib(window, n, WGL_ACCUM_RED_BITS_ARB);
u->accumGreenBits = getPixelFormatAttrib(window, n, WGL_ACCUM_GREEN_BITS_ARB);
u->accumBlueBits = getPixelFormatAttrib(window, n, WGL_ACCUM_BLUE_BITS_ARB);
u->accumAlphaBits = getPixelFormatAttrib(window, n, WGL_ACCUM_ALPHA_BITS_ARB);
u->auxBuffers = getPixelFormatAttrib(window, n, WGL_AUX_BUFFERS_ARB);
if (getPixelFormatAttrib(window, n, WGL_STEREO_ARB))
u->stereo = GLFW_TRUE;
if (getPixelFormatAttrib(window, n, WGL_DOUBLE_BUFFER_ARB))
u->doublebuffer = GLFW_TRUE;
if (_glfw.wgl.ARB_multisample)
u->samples = getPixelFormatAttrib(window, n, WGL_SAMPLES_ARB);
if (ctxconfig->client == GLFW_OPENGL_API)
{
if (_glfw.wgl.ARB_framebuffer_sRGB ||
_glfw.wgl.EXT_framebuffer_sRGB)
{
if (getPixelFormatAttrib(window, n, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB))
u->sRGB = GLFW_TRUE;
}
}
else
{
if (_glfw.wgl.EXT_colorspace)
{
if (getPixelFormatAttrib(window, n, WGL_COLORSPACE_EXT) ==
WGL_COLORSPACE_SRGB_EXT)
{
u->sRGB = GLFW_TRUE;
}
}
}
}
else
{
// Get pixel format attributes through legacy PFDs
PIXELFORMATDESCRIPTOR pfd;
if (!DescribePixelFormat(window->context.wgl.dc,
n,
sizeof(PIXELFORMATDESCRIPTOR),
&pfd))
{
continue;
}
if (!(pfd.dwFlags & PFD_DRAW_TO_WINDOW) ||
!(pfd.dwFlags & PFD_SUPPORT_OPENGL))
{
continue;
}
if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) &&
(pfd.dwFlags & PFD_GENERIC_FORMAT))
{
continue;
}
if (pfd.iPixelType != PFD_TYPE_RGBA)
continue;
u->redBits = pfd.cRedBits;
u->greenBits = pfd.cGreenBits;
u->blueBits = pfd.cBlueBits;
u->alphaBits = pfd.cAlphaBits;
u->depthBits = pfd.cDepthBits;
u->stencilBits = pfd.cStencilBits;
u->accumRedBits = pfd.cAccumRedBits;
u->accumGreenBits = pfd.cAccumGreenBits;
u->accumBlueBits = pfd.cAccumBlueBits;
u->accumAlphaBits = pfd.cAccumAlphaBits;
u->auxBuffers = pfd.cAuxBuffers;
if (pfd.dwFlags & PFD_STEREO)
u->stereo = GLFW_TRUE;
if (pfd.dwFlags & PFD_DOUBLEBUFFER)
u->doublebuffer = GLFW_TRUE;
}
u->handle = n;
usableCount++;
}
if (!usableCount)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"WGL: The driver does not appear to support OpenGL");
free(usableConfigs);
return 0;
}
closest = _glfwChooseFBConfig(fbconfig, usableConfigs, usableCount);
if (!closest)
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"WGL: Failed to find a suitable pixel format");
free(usableConfigs);
return 0;
}
pixelFormat = (int) closest->handle;
free(usableConfigs);
return pixelFormat;
}
static void makeContextCurrentWGL(_GLFWwindow* window)
{
if (window)
{
if (wglMakeCurrent(window->context.wgl.dc, window->context.wgl.handle))
_glfwPlatformSetTls(&_glfw.contextSlot, window);
else
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to make context current");
_glfwPlatformSetTls(&_glfw.contextSlot, NULL);
}
}
else
{
if (!wglMakeCurrent(NULL, NULL))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to clear current context");
}
_glfwPlatformSetTls(&_glfw.contextSlot, NULL);
}
}
static void swapBuffersWGL(_GLFWwindow* window)
{
if (!window->monitor)
{
if (IsWindowsVistaOrGreater())
{
BOOL enabled;
// HACK: Use DwmFlush when desktop composition is enabled
if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)
{
int count = abs(window->context.wgl.interval);
while (count--)
DwmFlush();
}
}
}
SwapBuffers(window->context.wgl.dc);
}
static void swapIntervalWGL(int interval)
{
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
window->context.wgl.interval = interval;
if (!window->monitor)
{
if (IsWindowsVistaOrGreater())
{
BOOL enabled;
// HACK: Disable WGL swap interval when desktop composition is enabled to
// avoid interfering with DWM vsync
if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)
interval = 0;
}
}
if (_glfw.wgl.EXT_swap_control)
_glfw.wgl.SwapIntervalEXT(interval);
}
static int extensionSupportedWGL(const char* extension)
{
const char* extensions;
if (_glfw.wgl.GetExtensionsStringEXT)
{
extensions = _glfw.wgl.GetExtensionsStringEXT();
if (extensions)
{
if (_glfwStringInExtensionString(extension, extensions))
return GLFW_TRUE;
}
}
if (_glfw.wgl.GetExtensionsStringARB)
{
extensions = _glfw.wgl.GetExtensionsStringARB(wglGetCurrentDC());
if (extensions)
{
if (_glfwStringInExtensionString(extension, extensions))
return GLFW_TRUE;
}
}
return GLFW_FALSE;
}
static GLFWglproc getProcAddressWGL(const char* procname)
{
const GLFWglproc proc = (GLFWglproc) wglGetProcAddress(procname);
if (proc)
return proc;
return (GLFWglproc) GetProcAddress(_glfw.wgl.instance, procname);
}
// Destroy the OpenGL context
//
static void destroyContextWGL(_GLFWwindow* window)
{
if (window->context.wgl.handle)
{
wglDeleteContext(window->context.wgl.handle);
window->context.wgl.handle = NULL;
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Initialize WGL
//
GLFWbool _glfwInitWGL(void)
{
PIXELFORMATDESCRIPTOR pfd;
HGLRC prc, rc;
HDC pdc, dc;
if (_glfw.wgl.instance)
return GLFW_TRUE;
_glfw.wgl.instance = LoadLibraryA("opengl32.dll");
if (!_glfw.wgl.instance)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to load opengl32.dll");
return GLFW_FALSE;
}
_glfw.wgl.CreateContext = (PFN_wglCreateContext)
GetProcAddress(_glfw.wgl.instance, "wglCreateContext");
_glfw.wgl.DeleteContext = (PFN_wglDeleteContext)
GetProcAddress(_glfw.wgl.instance, "wglDeleteContext");
_glfw.wgl.GetProcAddress = (PFN_wglGetProcAddress)
GetProcAddress(_glfw.wgl.instance, "wglGetProcAddress");
_glfw.wgl.GetCurrentDC = (PFN_wglGetCurrentDC)
GetProcAddress(_glfw.wgl.instance, "wglGetCurrentDC");
_glfw.wgl.GetCurrentContext = (PFN_wglGetCurrentContext)
GetProcAddress(_glfw.wgl.instance, "wglGetCurrentContext");
_glfw.wgl.MakeCurrent = (PFN_wglMakeCurrent)
GetProcAddress(_glfw.wgl.instance, "wglMakeCurrent");
_glfw.wgl.ShareLists = (PFN_wglShareLists)
GetProcAddress(_glfw.wgl.instance, "wglShareLists");
// NOTE: A dummy context has to be created for opengl32.dll to load the
// OpenGL ICD, from which we can then query WGL extensions
// NOTE: This code will accept the Microsoft GDI ICD; accelerated context
// creation failure occurs during manual pixel format enumeration
dc = GetDC(_glfw.win32.helperWindowHandle);
ZeroMemory(&pfd, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
if (!SetPixelFormat(dc, ChoosePixelFormat(dc, &pfd), &pfd))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to set pixel format for dummy context");
return GLFW_FALSE;
}
rc = wglCreateContext(dc);
if (!rc)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to create dummy context");
return GLFW_FALSE;
}
pdc = wglGetCurrentDC();
prc = wglGetCurrentContext();
if (!wglMakeCurrent(dc, rc))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to make dummy context current");
wglMakeCurrent(pdc, prc);
wglDeleteContext(rc);
return GLFW_FALSE;
}
// NOTE: Functions must be loaded first as they're needed to retrieve the
// extension string that tells us whether the functions are supported
_glfw.wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)
wglGetProcAddress("wglGetExtensionsStringEXT");
_glfw.wgl.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)
wglGetProcAddress("wglGetExtensionsStringARB");
_glfw.wgl.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)
wglGetProcAddress("wglCreateContextAttribsARB");
_glfw.wgl.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)
wglGetProcAddress("wglSwapIntervalEXT");
_glfw.wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)
wglGetProcAddress("wglGetPixelFormatAttribivARB");
// NOTE: WGL_ARB_extensions_string and WGL_EXT_extensions_string are not
// checked below as we are already using them
_glfw.wgl.ARB_multisample =
extensionSupportedWGL("WGL_ARB_multisample");
_glfw.wgl.ARB_framebuffer_sRGB =
extensionSupportedWGL("WGL_ARB_framebuffer_sRGB");
_glfw.wgl.EXT_framebuffer_sRGB =
extensionSupportedWGL("WGL_EXT_framebuffer_sRGB");
_glfw.wgl.ARB_create_context =
extensionSupportedWGL("WGL_ARB_create_context");
_glfw.wgl.ARB_create_context_profile =
extensionSupportedWGL("WGL_ARB_create_context_profile");
_glfw.wgl.EXT_create_context_es2_profile =
extensionSupportedWGL("WGL_EXT_create_context_es2_profile");
_glfw.wgl.ARB_create_context_robustness =
extensionSupportedWGL("WGL_ARB_create_context_robustness");
_glfw.wgl.ARB_create_context_no_error =
extensionSupportedWGL("WGL_ARB_create_context_no_error");
_glfw.wgl.EXT_swap_control =
extensionSupportedWGL("WGL_EXT_swap_control");
_glfw.wgl.EXT_colorspace =
extensionSupportedWGL("WGL_EXT_colorspace");
_glfw.wgl.ARB_pixel_format =
extensionSupportedWGL("WGL_ARB_pixel_format");
_glfw.wgl.ARB_context_flush_control =
extensionSupportedWGL("WGL_ARB_context_flush_control");
wglMakeCurrent(pdc, prc);
wglDeleteContext(rc);
return GLFW_TRUE;
}
// Terminate WGL
//
void _glfwTerminateWGL(void)
{
if (_glfw.wgl.instance)
FreeLibrary(_glfw.wgl.instance);
}
#define setAttrib(a, v) \
{ \
assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \
attribs[index++] = v; \
}
// Create the OpenGL or OpenGL ES context
//
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
int attribs[40];
int pixelFormat;
PIXELFORMATDESCRIPTOR pfd;
HGLRC share = NULL;
if (ctxconfig->share)
share = ctxconfig->share->context.wgl.handle;
window->context.wgl.dc = GetDC(window->win32.handle);
if (!window->context.wgl.dc)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"WGL: Failed to retrieve DC for window");
return GLFW_FALSE;
}
pixelFormat = choosePixelFormat(window, ctxconfig, fbconfig);
if (!pixelFormat)
return GLFW_FALSE;
if (!DescribePixelFormat(window->context.wgl.dc,
pixelFormat, sizeof(pfd), &pfd))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to retrieve PFD for selected pixel format");
return GLFW_FALSE;
}
if (!SetPixelFormat(window->context.wgl.dc, pixelFormat, &pfd))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to set selected pixel format");
return GLFW_FALSE;
}
if (ctxconfig->client == GLFW_OPENGL_API)
{
if (ctxconfig->forward)
{
if (!_glfw.wgl.ARB_create_context)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: A forward compatible OpenGL context requested but WGL_ARB_create_context is unavailable");
return GLFW_FALSE;
}
}
if (ctxconfig->profile)
{
if (!_glfw.wgl.ARB_create_context_profile)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: OpenGL profile requested but WGL_ARB_create_context_profile is unavailable");
return GLFW_FALSE;
}
}
}
else
{
if (!_glfw.wgl.ARB_create_context ||
!_glfw.wgl.ARB_create_context_profile ||
!_glfw.wgl.EXT_create_context_es2_profile)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"WGL: OpenGL ES requested but WGL_ARB_create_context_es2_profile is unavailable");
return GLFW_FALSE;
}
}
if (_glfw.wgl.ARB_create_context)
{
int index = 0, mask = 0, flags = 0;
if (ctxconfig->client == GLFW_OPENGL_API)
{
if (ctxconfig->forward)
flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
mask |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
mask |= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
}
else
mask |= WGL_CONTEXT_ES2_PROFILE_BIT_EXT;
if (ctxconfig->debug)
flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
if (ctxconfig->robustness)
{
if (_glfw.wgl.ARB_create_context_robustness)
{
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
{
setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
WGL_NO_RESET_NOTIFICATION_ARB);
}
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
{
setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
WGL_LOSE_CONTEXT_ON_RESET_ARB);
}
flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB;
}
}
if (ctxconfig->release)
{
if (_glfw.wgl.ARB_context_flush_control)
{
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
{
setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
}
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
{
setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
}
}
}
if (ctxconfig->noerror)
{
if (_glfw.wgl.ARB_create_context_no_error)
setAttrib(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
}
// NOTE: Only request an explicitly versioned context when necessary, as
// explicitly requesting version 1.0 does not always return the
// highest version supported by the driver
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
{
setAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
setAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
}
if (flags)
setAttrib(WGL_CONTEXT_FLAGS_ARB, flags);
if (mask)
setAttrib(WGL_CONTEXT_PROFILE_MASK_ARB, mask);
setAttrib(0, 0);
window->context.wgl.handle =
_glfw.wgl.CreateContextAttribsARB(window->context.wgl.dc,
share, attribs);
if (!window->context.wgl.handle)
{
const DWORD error = GetLastError();
if (error == (0xc0070000 | ERROR_INVALID_VERSION_ARB))
{
if (ctxconfig->client == GLFW_OPENGL_API)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: Driver does not support OpenGL version %i.%i",
ctxconfig->major,
ctxconfig->minor);
}
else
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: Driver does not support OpenGL ES version %i.%i",
ctxconfig->major,
ctxconfig->minor);
}
}
else if (error == (0xc0070000 | ERROR_INVALID_PROFILE_ARB))
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: Driver does not support the requested OpenGL profile");
}
else if (error == (0xc0070000 | ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB))
{
_glfwInputError(GLFW_INVALID_VALUE,
"WGL: The share context is not compatible with the requested context");
}
else
{
if (ctxconfig->client == GLFW_OPENGL_API)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: Failed to create OpenGL context");
}
else
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: Failed to create OpenGL ES context");
}
}
return GLFW_FALSE;
}
}
else
{
window->context.wgl.handle = wglCreateContext(window->context.wgl.dc);
if (!window->context.wgl.handle)
{
_glfwInputErrorWin32(GLFW_VERSION_UNAVAILABLE,
"WGL: Failed to create OpenGL context");
return GLFW_FALSE;
}
if (share)
{
if (!wglShareLists(share, window->context.wgl.handle))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to enable sharing with specified OpenGL context");
return GLFW_FALSE;
}
}
}
window->context.makeCurrent = makeContextCurrentWGL;
window->context.swapBuffers = swapBuffersWGL;
window->context.swapInterval = swapIntervalWGL;
window->context.extensionSupported = extensionSupportedWGL;
window->context.getProcAddress = getProcAddressWGL;
window->context.destroy = destroyContextWGL;
return GLFW_TRUE;
}
#undef setAttrib
//////////////////////////////////////////////////////////////////////////
////// GLFW native API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (window->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return NULL;
}
return window->context.wgl.handle;
}

159
glfw/wgl_context.h vendored
View File

@@ -1,159 +0,0 @@
//========================================================================
// GLFW 3.3 WGL - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
#define WGL_SUPPORT_OPENGL_ARB 0x2010
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
#define WGL_PIXEL_TYPE_ARB 0x2013
#define WGL_TYPE_RGBA_ARB 0x202b
#define WGL_ACCELERATION_ARB 0x2003
#define WGL_NO_ACCELERATION_ARB 0x2025
#define WGL_RED_BITS_ARB 0x2015
#define WGL_RED_SHIFT_ARB 0x2016
#define WGL_GREEN_BITS_ARB 0x2017
#define WGL_GREEN_SHIFT_ARB 0x2018
#define WGL_BLUE_BITS_ARB 0x2019
#define WGL_BLUE_SHIFT_ARB 0x201a
#define WGL_ALPHA_BITS_ARB 0x201b
#define WGL_ALPHA_SHIFT_ARB 0x201c
#define WGL_ACCUM_BITS_ARB 0x201d
#define WGL_ACCUM_RED_BITS_ARB 0x201e
#define WGL_ACCUM_GREEN_BITS_ARB 0x201f
#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
#define WGL_DEPTH_BITS_ARB 0x2022
#define WGL_STENCIL_BITS_ARB 0x2023
#define WGL_AUX_BUFFERS_ARB 0x2024
#define WGL_STEREO_ARB 0x2012
#define WGL_DOUBLE_BUFFER_ARB 0x2011
#define WGL_SAMPLES_ARB 0x2042
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20a9
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_FLAGS_ARB 0x2094
#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
#define WGL_CONTEXT_OPENGL_NO_ERROR_ARB 0x31b3
#define WGL_COLORSPACE_EXT 0x309d
#define WGL_COLORSPACE_SRGB_EXT 0x3089
#define ERROR_INVALID_VERSION_ARB 0x2095
#define ERROR_INVALID_PROFILE_ARB 0x2096
#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC)(int);
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC)(HDC,int,int,UINT,const int*,int*);
typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC)(void);
typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC);
typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC,HGLRC,const int*);
typedef HGLRC (WINAPI * PFN_wglCreateContext)(HDC);
typedef BOOL (WINAPI * PFN_wglDeleteContext)(HGLRC);
typedef PROC (WINAPI * PFN_wglGetProcAddress)(LPCSTR);
typedef HDC (WINAPI * PFN_wglGetCurrentDC)(void);
typedef HGLRC (WINAPI * PFN_wglGetCurrentContext)(void);
typedef BOOL (WINAPI * PFN_wglMakeCurrent)(HDC,HGLRC);
typedef BOOL (WINAPI * PFN_wglShareLists)(HGLRC,HGLRC);
// opengl32.dll function pointer typedefs
#define wglCreateContext _glfw.wgl.CreateContext
#define wglDeleteContext _glfw.wgl.DeleteContext
#define wglGetProcAddress _glfw.wgl.GetProcAddress
#define wglGetCurrentDC _glfw.wgl.GetCurrentDC
#define wglGetCurrentContext _glfw.wgl.GetCurrentContext
#define wglMakeCurrent _glfw.wgl.MakeCurrent
#define wglShareLists _glfw.wgl.ShareLists
#define _GLFW_RECREATION_NOT_NEEDED 0
#define _GLFW_RECREATION_REQUIRED 1
#define _GLFW_RECREATION_IMPOSSIBLE 2
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextWGL wgl
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryWGL wgl
// WGL-specific per-context data
//
typedef struct _GLFWcontextWGL
{
HDC dc;
HGLRC handle;
int interval;
} _GLFWcontextWGL;
// WGL-specific global data
//
typedef struct _GLFWlibraryWGL
{
HINSTANCE instance;
PFN_wglCreateContext CreateContext;
PFN_wglDeleteContext DeleteContext;
PFN_wglGetProcAddress GetProcAddress;
PFN_wglGetCurrentDC GetCurrentDC;
PFN_wglGetCurrentContext GetCurrentContext;
PFN_wglMakeCurrent MakeCurrent;
PFN_wglShareLists ShareLists;
PFNWGLSWAPINTERVALEXTPROC SwapIntervalEXT;
PFNWGLGETPIXELFORMATATTRIBIVARBPROC GetPixelFormatAttribivARB;
PFNWGLGETEXTENSIONSSTRINGEXTPROC GetExtensionsStringEXT;
PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB;
PFNWGLCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
GLFWbool EXT_swap_control;
GLFWbool EXT_colorspace;
GLFWbool ARB_multisample;
GLFWbool ARB_framebuffer_sRGB;
GLFWbool EXT_framebuffer_sRGB;
GLFWbool ARB_pixel_format;
GLFWbool ARB_create_context;
GLFWbool ARB_create_context_profile;
GLFWbool EXT_create_context_es2_profile;
GLFWbool ARB_create_context_robustness;
GLFWbool ARB_create_context_no_error;
GLFWbool ARB_context_flush_control;
} _GLFWlibraryWGL;
GLFWbool _glfwInitWGL(void);
void _glfwTerminateWGL(void);
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);

80
glfw/window.c vendored
View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 - www.glfw.org
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net>
//
// This software is provided 'as-is', without any express or implied
@@ -25,6 +25,8 @@
// distribution.
//
//========================================================================
// Please use C89 style variable declarations in this file because VS 2010
//========================================================================
#include "internal.h"
@@ -40,7 +42,7 @@
// Notifies shared code that a window has lost or received input focus
//
void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused)
void _glfwInputWindowFocus(_GLFWwindow* window, bool focused)
{
if (window->callbacks.focus)
window->callbacks.focus((GLFWwindow*) window, focused);
@@ -82,7 +84,7 @@ _GLFWwindow* _glfwFocusedWindow() {
_GLFWwindow* _glfwWindowForId(GLFWid id) {
_GLFWwindow *w = _glfw.windowListHead;
while (w) {
if (w->id == _glfw.focusedWindowId) return w;
if (w->id == id) return w;
w = w->next;
}
return NULL;
@@ -90,7 +92,7 @@ _GLFWwindow* _glfwWindowForId(GLFWid id) {
// Notifies shared code that a window's occlusion state has changed
//
void _glfwInputWindowOcclusion(_GLFWwindow* window, GLFWbool occluded)
void _glfwInputWindowOcclusion(_GLFWwindow* window, bool occluded)
{
if (window->callbacks.occlusion)
window->callbacks.occlusion((GLFWwindow*) window, occluded);
@@ -116,7 +118,7 @@ void _glfwInputWindowSize(_GLFWwindow* window, int width, int height)
// Notifies shared code that a window has been iconified or restored
//
void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified)
void _glfwInputWindowIconify(_GLFWwindow* window, bool iconified)
{
if (window->callbacks.iconify)
window->callbacks.iconify((GLFWwindow*) window, iconified);
@@ -124,7 +126,7 @@ void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified)
// Notifies shared code that a window has been maximized or restored
//
void _glfwInputWindowMaximize(_GLFWwindow* window, GLFWbool maximized)
void _glfwInputWindowMaximize(_GLFWwindow* window, bool maximized)
{
if (window->callbacks.maximize)
window->callbacks.maximize((GLFWwindow*) window, maximized);
@@ -168,7 +170,7 @@ void _glfwInputWindowDamage(_GLFWwindow* window)
//
void _glfwInputWindowCloseRequest(_GLFWwindow* window)
{
window->shouldClose = GLFW_TRUE;
window->shouldClose = true;
if (window->callbacks.close)
window->callbacks.close((GLFWwindow*) window);
@@ -181,7 +183,6 @@ void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor)
window->monitor = monitor;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
@@ -300,13 +301,13 @@ void glfwDefaultWindowHints(void)
// The default is a focused, visible, resizable window with decorations
memset(&_glfw.hints.window, 0, sizeof(_glfw.hints.window));
_glfw.hints.window.resizable = GLFW_TRUE;
_glfw.hints.window.visible = GLFW_TRUE;
_glfw.hints.window.decorated = GLFW_TRUE;
_glfw.hints.window.focused = GLFW_TRUE;
_glfw.hints.window.autoIconify = GLFW_TRUE;
_glfw.hints.window.centerCursor = GLFW_TRUE;
_glfw.hints.window.focusOnShow = GLFW_TRUE;
_glfw.hints.window.resizable = true;
_glfw.hints.window.visible = true;
_glfw.hints.window.decorated = true;
_glfw.hints.window.focused = true;
_glfw.hints.window.autoIconify = true;
_glfw.hints.window.centerCursor = true;
_glfw.hints.window.focusOnShow = true;
// The default is 24 bits of color, 24 bits of depth and 8 bits of stencil,
// double buffered
@@ -317,13 +318,13 @@ void glfwDefaultWindowHints(void)
_glfw.hints.framebuffer.alphaBits = 8;
_glfw.hints.framebuffer.depthBits = 24;
_glfw.hints.framebuffer.stencilBits = 8;
_glfw.hints.framebuffer.doublebuffer = GLFW_TRUE;
_glfw.hints.framebuffer.doublebuffer = true;
// The default is to select the highest available refresh rate
_glfw.hints.refreshRate = GLFW_DONT_CARE;
// The default is to use full Retina resolution framebuffers
_glfw.hints.window.ns.retina = GLFW_TRUE;
_glfw.hints.window.ns.retina = true;
}
GLFWAPI void glfwWindowHint(int hint, int value)
@@ -366,55 +367,55 @@ GLFWAPI void glfwWindowHint(int hint, int value)
_glfw.hints.framebuffer.auxBuffers = value;
return;
case GLFW_STEREO:
_glfw.hints.framebuffer.stereo = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.framebuffer.stereo = value ? true : false;
return;
case GLFW_DOUBLEBUFFER:
_glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.framebuffer.doublebuffer = value ? true : false;
return;
case GLFW_TRANSPARENT_FRAMEBUFFER:
_glfw.hints.framebuffer.transparent = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.framebuffer.transparent = value ? true : false;
return;
case GLFW_SAMPLES:
_glfw.hints.framebuffer.samples = value;
return;
case GLFW_SRGB_CAPABLE:
_glfw.hints.framebuffer.sRGB = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.framebuffer.sRGB = value ? true : false;
return;
case GLFW_RESIZABLE:
_glfw.hints.window.resizable = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.resizable = value ? true : false;
return;
case GLFW_DECORATED:
_glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.decorated = value ? true : false;
return;
case GLFW_FOCUSED:
_glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.focused = value ? true : false;
return;
case GLFW_AUTO_ICONIFY:
_glfw.hints.window.autoIconify = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.autoIconify = value ? true : false;
return;
case GLFW_FLOATING:
_glfw.hints.window.floating = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.floating = value ? true : false;
return;
case GLFW_MAXIMIZED:
_glfw.hints.window.maximized = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.maximized = value ? true : false;
return;
case GLFW_VISIBLE:
_glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.visible = value ? true : false;
return;
case GLFW_COCOA_RETINA_FRAMEBUFFER:
_glfw.hints.window.ns.retina = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.ns.retina = value ? true : false;
return;
case GLFW_COCOA_GRAPHICS_SWITCHING:
_glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.context.nsgl.offline = value ? true : false;
return;
case GLFW_SCALE_TO_MONITOR:
_glfw.hints.window.scaleToMonitor = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.scaleToMonitor = value ? true : false;
return;
case GLFW_CENTER_CURSOR:
_glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.centerCursor = value ? true : false;
return;
case GLFW_FOCUS_ON_SHOW:
_glfw.hints.window.focusOnShow = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.window.focusOnShow = value ? true : false;
return;
case GLFW_CLIENT_API:
_glfw.hints.context.client = value;
@@ -432,13 +433,13 @@ GLFWAPI void glfwWindowHint(int hint, int value)
_glfw.hints.context.robustness = value;
return;
case GLFW_OPENGL_FORWARD_COMPAT:
_glfw.hints.context.forward = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.context.forward = value ? true : false;
return;
case GLFW_OPENGL_DEBUG_CONTEXT:
_glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.context.debug = value ? true : false;
return;
case GLFW_CONTEXT_NO_ERROR:
_glfw.hints.context.noerror = value ? GLFW_TRUE : GLFW_FALSE;
_glfw.hints.context.noerror = value ? true : false;
return;
case GLFW_OPENGL_PROFILE:
_glfw.hints.context.profile = value;
@@ -836,7 +837,7 @@ GLFWAPI int glfwWindowBell(GLFWwindow* handle)
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
_GLFW_REQUIRE_INIT_OR_RETURN(false);
return _glfwPlatformWindowBell(window);
}
@@ -932,7 +933,7 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
_GLFW_REQUIRE_INIT();
value = value ? GLFW_TRUE : GLFW_FALSE;
value = value ? true : false;
if (attrib == GLFW_AUTO_ICONIFY)
window->autoIconify = value;
@@ -1165,6 +1166,5 @@ GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow*
GLFWAPI void glfwPostEmptyEvent(void)
{
_GLFW_REQUIRE_INIT();
_glfwPlatformPostEmptyEvent();
}

225
glfw/wl_init.c vendored
View File

@@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.3 Wayland - www.glfw.org
// GLFW 3.4 Wayland - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
//
@@ -23,6 +23,8 @@
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#define _GNU_SOURCE
#include "internal.h"
@@ -31,7 +33,6 @@
#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <linux/input.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -39,6 +40,16 @@
#include <unistd.h>
#include <fcntl.h>
#include <wayland-client.h>
// Needed for the BTN_* defines
#ifdef __has_include
#if __has_include(<linux/input.h>)
#include <linux/input.h>
#elif __has_include(<dev/evdev/input.h>)
#include <dev/evdev/input.h>
#endif
#else
#include <linux/input.h>
#endif
static inline int min(int n1, int n2)
@@ -46,7 +57,8 @@ static inline int min(int n1, int n2)
return n1 < n2 ? n1 : n2;
}
static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface, int* which)
static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface,
int* which)
{
int focus;
_GLFWwindow* window = _glfw.windowListHead;
@@ -79,12 +91,12 @@ static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface,
return window;
}
static void pointerHandleEnter(void* data,
struct wl_pointer* pointer,
static void pointerHandleEnter(void* data UNUSED,
struct wl_pointer* pointer UNUSED,
uint32_t serial,
struct wl_surface* surface,
wl_fixed_t sx,
wl_fixed_t sy)
wl_fixed_t sx UNUSED,
wl_fixed_t sy UNUSED)
{
// Happens in the case we just destroyed the surface.
if (!surface)
@@ -103,27 +115,27 @@ static void pointerHandleEnter(void* data,
_glfw.wl.pointerSerial = serial;
_glfw.wl.pointerFocus = window;
window->wl.hovered = GLFW_TRUE;
window->wl.hovered = true;
_glfwPlatformSetCursor(window, window->wl.currentCursor);
_glfwInputCursorEnter(window, GLFW_TRUE);
_glfwInputCursorEnter(window, true);
}
static void pointerHandleLeave(void* data,
struct wl_pointer* pointer,
static void pointerHandleLeave(void* data UNUSED,
struct wl_pointer* pointer UNUSED,
uint32_t serial,
struct wl_surface* surface)
struct wl_surface* surface UNUSED)
{
_GLFWwindow* window = _glfw.wl.pointerFocus;
if (!window)
return;
window->wl.hovered = GLFW_FALSE;
window->wl.hovered = false;
_glfw.wl.pointerSerial = serial;
_glfw.wl.pointerFocus = NULL;
_glfwInputCursorEnter(window, GLFW_FALSE);
_glfwInputCursorEnter(window, false);
}
static void setCursor(GLFWCursorShape shape)
@@ -154,9 +166,9 @@ static void setCursor(GLFWCursorShape shape)
wl_surface_commit(surface);
}
static void pointerHandleMotion(void* data,
struct wl_pointer* pointer,
uint32_t time,
static void pointerHandleMotion(void* data UNUSED,
struct wl_pointer* pointer UNUSED,
uint32_t time UNUSED,
wl_fixed_t sx,
wl_fixed_t sy)
{
@@ -168,18 +180,14 @@ static void pointerHandleMotion(void* data,
if (window->cursorMode == GLFW_CURSOR_DISABLED)
return;
else
{
window->wl.cursorPosX = wl_fixed_to_double(sx);
window->wl.cursorPosY = wl_fixed_to_double(sy);
}
window->wl.cursorPosX = wl_fixed_to_double(sx);
window->wl.cursorPosY = wl_fixed_to_double(sy);
switch (window->wl.decorations.focus)
{
case mainWindow:
_glfwInputCursorPos(window,
wl_fixed_to_double(sx),
wl_fixed_to_double(sy));
window->wl.cursorPosX, window->wl.cursorPosY);
return;
case topDecoration:
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
@@ -213,16 +221,15 @@ static void pointerHandleMotion(void* data,
setCursor(cursorShape);
}
static void pointerHandleButton(void* data,
struct wl_pointer* pointer,
static void pointerHandleButton(void* data UNUSED,
struct wl_pointer* pointer UNUSED,
uint32_t serial,
uint32_t time,
uint32_t time UNUSED,
uint32_t button,
uint32_t state)
{
_GLFWwindow* window = _glfw.wl.pointerFocus;
int glfwButton;
uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE;
if (!window)
@@ -301,9 +308,9 @@ static void pointerHandleButton(void* data,
_glfw.wl.xkb.states.modifiers);
}
static void pointerHandleAxis(void* data,
struct wl_pointer* pointer,
uint32_t time,
static void pointerHandleAxis(void* data UNUSED,
struct wl_pointer* pointer UNUSED,
uint32_t time UNUSED,
uint32_t axis,
wl_fixed_t value)
{
@@ -331,8 +338,8 @@ static const struct wl_pointer_listener pointerListener = {
pointerHandleAxis,
};
static void keyboardHandleKeymap(void* data,
struct wl_keyboard* keyboard,
static void keyboardHandleKeymap(void* data UNUSED,
struct wl_keyboard* keyboard UNUSED,
uint32_t format,
int fd,
uint32_t size)
@@ -356,11 +363,11 @@ static void keyboardHandleKeymap(void* data,
}
static void keyboardHandleEnter(void* data,
struct wl_keyboard* keyboard,
uint32_t serial,
static void keyboardHandleEnter(void* data UNUSED,
struct wl_keyboard* keyboard UNUSED,
uint32_t serial UNUSED,
struct wl_surface* surface,
struct wl_array* keys)
struct wl_array* keys UNUSED)
{
// Happens in the case we just destroyed the surface.
if (!surface)
@@ -375,13 +382,13 @@ static void keyboardHandleEnter(void* data,
}
_glfw.wl.keyboardFocus = window;
_glfwInputWindowFocus(window, GLFW_TRUE);
_glfwInputWindowFocus(window, true);
}
static void keyboardHandleLeave(void* data,
struct wl_keyboard* keyboard,
uint32_t serial,
struct wl_surface* surface)
static void keyboardHandleLeave(void* data UNUSED,
struct wl_keyboard* keyboard UNUSED,
uint32_t serial UNUSED,
struct wl_surface* surface UNUSED)
{
_GLFWwindow* window = _glfw.wl.keyboardFocus;
@@ -389,11 +396,11 @@ static void keyboardHandleLeave(void* data,
return;
_glfw.wl.keyboardFocus = NULL;
_glfwInputWindowFocus(window, GLFW_FALSE);
_glfwInputWindowFocus(window, false);
}
static void
dispatchPendingKeyRepeats(id_type timer_id, void *data) {
dispatchPendingKeyRepeats(id_type timer_id UNUSED, void *data UNUSED) {
if (_glfw.wl.keyRepeatInfo.keyboardFocus != _glfw.wl.keyboardFocus || _glfw.wl.keyboardRepeatRate == 0) return;
glfw_xkb_handle_key_event(_glfw.wl.keyRepeatInfo.keyboardFocus, &_glfw.wl.xkb, _glfw.wl.keyRepeatInfo.key, GLFW_REPEAT);
changeTimerInterval(&_glfw.wl.eventLoopData, _glfw.wl.keyRepeatInfo.keyRepeatTimer, (1.0 / (double)_glfw.wl.keyboardRepeatRate));
@@ -401,10 +408,10 @@ dispatchPendingKeyRepeats(id_type timer_id, void *data) {
}
static void keyboardHandleKey(void* data,
struct wl_keyboard* keyboard,
uint32_t serial,
uint32_t time,
static void keyboardHandleKey(void* data UNUSED,
struct wl_keyboard* keyboard UNUSED,
uint32_t serial UNUSED,
uint32_t time UNUSED,
uint32_t key,
uint32_t state)
{
@@ -413,12 +420,12 @@ static void keyboardHandleKey(void* data,
return;
int action = state == WL_KEYBOARD_KEY_STATE_PRESSED ? GLFW_PRESS : GLFW_RELEASE;
glfw_xkb_handle_key_event(window, &_glfw.wl.xkb, key, action);
GLFWbool repeatable = GLFW_FALSE;
bool repeatable = false;
if (action == GLFW_PRESS && _glfw.wl.keyboardRepeatRate > 0 && glfw_xkb_should_repeat(&_glfw.wl.xkb, key))
{
_glfw.wl.keyRepeatInfo.key = key;
repeatable = GLFW_TRUE;
repeatable = true;
_glfw.wl.keyRepeatInfo.keyboardFocus = window;
}
if (repeatable) {
@@ -427,9 +434,9 @@ static void keyboardHandleKey(void* data,
toggleTimer(&_glfw.wl.eventLoopData, _glfw.wl.keyRepeatInfo.keyRepeatTimer, repeatable ? 1 : 0);
}
static void keyboardHandleModifiers(void* data,
struct wl_keyboard* keyboard,
uint32_t serial,
static void keyboardHandleModifiers(void* data UNUSED,
struct wl_keyboard* keyboard UNUSED,
uint32_t serial UNUSED,
uint32_t modsDepressed,
uint32_t modsLatched,
uint32_t modsLocked,
@@ -438,7 +445,7 @@ static void keyboardHandleModifiers(void* data,
glfw_xkb_update_modifiers(&_glfw.wl.xkb, modsDepressed, modsLatched, modsLocked, 0, 0, group);
}
static void keyboardHandleRepeatInfo(void* data,
static void keyboardHandleRepeatInfo(void* data UNUSED,
struct wl_keyboard* keyboard,
int32_t rate,
int32_t delay)
@@ -459,7 +466,7 @@ static const struct wl_keyboard_listener keyboardListener = {
keyboardHandleRepeatInfo,
};
static void seatHandleCapabilities(void* data,
static void seatHandleCapabilities(void* data UNUSED,
struct wl_seat* seat,
enum wl_seat_capability caps)
{
@@ -486,9 +493,9 @@ static void seatHandleCapabilities(void* data,
}
}
static void seatHandleName(void* data,
struct wl_seat* seat,
const char* name)
static void seatHandleName(void* data UNUSED,
struct wl_seat* seat UNUSED,
const char* name UNUSED)
{
}
@@ -497,7 +504,7 @@ static const struct wl_seat_listener seatListener = {
seatHandleName,
};
static void wmBaseHandlePing(void* data,
static void wmBaseHandlePing(void* data UNUSED,
struct xdg_wm_base* wmBase,
uint32_t serial)
{
@@ -508,7 +515,7 @@ static const struct xdg_wm_base_listener wmBaseListener = {
wmBaseHandlePing
};
static void registryHandleGlobal(void* data,
static void registryHandleGlobal(void* data UNUSED,
struct wl_registry* registry,
uint32_t name,
const char* interface,
@@ -614,18 +621,24 @@ static void registryHandleGlobal(void* data,
}
static void registryHandleGlobalRemove(void *data,
struct wl_registry *registry,
static void registryHandleGlobalRemove(void *data UNUSED,
struct wl_registry *registry UNUSED,
uint32_t name)
{
int i;
_GLFWmonitor* monitor;
for (i = 0; i < _glfw.monitorCount; ++i)
for (int i = 0; i < _glfw.monitorCount; ++i)
{
monitor = _glfw.monitors[i];
if (monitor->wl.name == name)
{
for (_GLFWwindow *window = _glfw.windowListHead; window; window = window->next) {
for (int m = window->wl.monitorsCount - 1; m >= 0; m--) {
if (window->wl.monitors[m] == monitor) {
remove_i_from_array(window->wl.monitors, m, window->wl.monitorsCount);
}
}
}
_glfwInputMonitor(monitor, GLFW_DISCONNECTED, 0);
return;
}
@@ -639,59 +652,81 @@ static const struct wl_registry_listener registryListener = {
};
static void registry_handle_global(void* data,
struct wl_registry* registry UNUSED,
uint32_t name UNUSED,
const char* interface,
uint32_t version UNUSED) {
if (strcmp(interface, "zxdg_decoration_manager_v1") == 0) {
bool *has_ssd = (bool*)data;
if (has_ssd) *has_ssd = true;
}
}
static void registry_handle_global_remove(void *data UNUSED,
struct wl_registry *registry UNUSED,
uint32_t name UNUSED) {}
GLFWAPI const char*
glfwWaylandCheckForServerSideDecorations(void) {
struct wl_display *display = wl_display_connect(NULL);
if (!display) return "ERR: Failed to connect to Wayland display";
static const struct wl_registry_listener rl = {
registry_handle_global, registry_handle_global_remove
};
struct wl_registry *registry = wl_display_get_registry(display);
bool has_ssd = false;
wl_registry_add_listener(registry, &rl, &has_ssd);
wl_display_roundtrip(display);
wl_registry_destroy(registry);
wl_display_flush(display);
wl_display_flush(display);
return has_ssd ? "YES" : "NO";
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
int _glfwPlatformInit(void)
{
if (pipe2(_glfw.wl.eventLoopData.wakeupFds, O_CLOEXEC | O_NONBLOCK) != 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: failed to create self pipe");
return GLFW_FALSE;
}
_glfw.wl.cursor.handle = _glfw_dlopen("libwayland-cursor.so.0");
if (!_glfw.wl.cursor.handle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Failed to open libwayland-cursor");
return GLFW_FALSE;
return false;
}
_glfw.wl.cursor.theme_load = (PFN_wl_cursor_theme_load)
_glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_theme_load");
_glfw.wl.cursor.theme_destroy = (PFN_wl_cursor_theme_destroy)
_glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_theme_destroy");
_glfw.wl.cursor.theme_get_cursor = (PFN_wl_cursor_theme_get_cursor)
_glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_theme_get_cursor");
_glfw.wl.cursor.image_get_buffer = (PFN_wl_cursor_image_get_buffer)
_glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_image_get_buffer");
glfw_dlsym(_glfw.wl.cursor.theme_load, _glfw.wl.cursor.handle, "wl_cursor_theme_load");
glfw_dlsym(_glfw.wl.cursor.theme_destroy, _glfw.wl.cursor.handle, "wl_cursor_theme_destroy");
glfw_dlsym(_glfw.wl.cursor.theme_get_cursor, _glfw.wl.cursor.handle, "wl_cursor_theme_get_cursor");
glfw_dlsym(_glfw.wl.cursor.image_get_buffer, _glfw.wl.cursor.handle, "wl_cursor_image_get_buffer");
_glfw.wl.egl.handle = _glfw_dlopen("libwayland-egl.so.1");
if (!_glfw.wl.egl.handle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Failed to open libwayland-egl");
return GLFW_FALSE;
return false;
}
_glfw.wl.egl.window_create = (PFN_wl_egl_window_create)
_glfw_dlsym(_glfw.wl.egl.handle, "wl_egl_window_create");
_glfw.wl.egl.window_destroy = (PFN_wl_egl_window_destroy)
_glfw_dlsym(_glfw.wl.egl.handle, "wl_egl_window_destroy");
_glfw.wl.egl.window_resize = (PFN_wl_egl_window_resize)
_glfw_dlsym(_glfw.wl.egl.handle, "wl_egl_window_resize");
glfw_dlsym(_glfw.wl.egl.window_create, _glfw.wl.egl.handle, "wl_egl_window_create");
glfw_dlsym(_glfw.wl.egl.window_destroy, _glfw.wl.egl.handle, "wl_egl_window_destroy");
glfw_dlsym(_glfw.wl.egl.window_resize, _glfw.wl.egl.handle, "wl_egl_window_resize");
_glfw.wl.display = wl_display_connect(NULL);
if (!_glfw.wl.display)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Failed to connect to display");
return GLFW_FALSE;
return false;
}
if (!initPollData(&_glfw.wl.eventLoopData, wl_display_get_fd(_glfw.wl.display))) {
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Failed to initialize event loop data");
}
initPollData(&_glfw.wl.eventLoopData, _glfw.wl.eventLoopData.wakeupFds[0], wl_display_get_fd(_glfw.wl.display));
glfw_dbus_init(&_glfw.wl.dbus, &_glfw.wl.eventLoopData);
_glfw.wl.keyRepeatInfo.keyRepeatTimer = addTimer(&_glfw.wl.eventLoopData, "wayland-key-repeat", 0.5, 0, true, dispatchPendingKeyRepeats, NULL, NULL);
_glfw.wl.cursorAnimationTimer = addTimer(&_glfw.wl.eventLoopData, "wayland-cursor-animation", 0.5, 0, true, animateCursorImage, NULL, NULL);
@@ -699,7 +734,7 @@ int _glfwPlatformInit(void)
_glfw.wl.registry = wl_display_get_registry(_glfw.wl.display);
wl_registry_add_listener(_glfw.wl.registry, &registryListener, NULL);
if (!glfw_xkb_create_context(&_glfw.wl.xkb)) return GLFW_FALSE;
if (!glfw_xkb_create_context(&_glfw.wl.xkb)) return false;
// Sync so we got all registry objects
wl_display_roundtrip(_glfw.wl.display);
@@ -710,7 +745,7 @@ int _glfwPlatformInit(void)
#ifdef __linux__
if (_glfw.hints.init.enableJoysticks) {
if (!_glfwInitJoysticksLinux())
return GLFW_FALSE;
return false;
}
#endif
@@ -719,7 +754,7 @@ int _glfwPlatformInit(void)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Failed to find xdg-shell in your compositor");
return GLFW_FALSE;
return false;
}
if (_glfw.wl.shm)
@@ -739,13 +774,13 @@ int _glfwPlatformInit(void)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Unable to load default cursor theme");
return GLFW_FALSE;
return false;
}
_glfw.wl.cursorSurface =
wl_compositor_create_surface(_glfw.wl.compositor);
}
return GLFW_TRUE;
return true;
}
void _glfwPlatformTerminate(void)
@@ -819,7 +854,7 @@ void _glfwPlatformTerminate(void)
wl_display_flush(_glfw.wl.display);
wl_display_disconnect(_glfw.wl.display);
}
closeFds(_glfw.wl.eventLoopData.wakeupFds, sizeof(_glfw.wl.eventLoopData.wakeupFds)/sizeof(_glfw.wl.eventLoopData.wakeupFds[0]));
finalizePollData(&_glfw.wl.eventLoopData);
free(_glfw.wl.clipboardString); _glfw.wl.clipboardString = NULL;
free(_glfw.wl.primarySelectionString); _glfw.wl.primarySelectionString = NULL;
free(_glfw.wl.pasteString); _glfw.wl.pasteString = NULL;

54
glfw/wl_monitor.c vendored
View File

@@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.3 Wayland - www.glfw.org
// GLFW 3.4 Wayland - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
//
@@ -23,6 +23,8 @@
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include "internal.h"
@@ -34,15 +36,15 @@
static void outputHandleGeometry(void* data,
struct wl_output* output,
int32_t x,
int32_t y,
int32_t physicalWidth,
int32_t physicalHeight,
int32_t subpixel,
const char* make,
const char* model,
int32_t transform)
struct wl_output* output UNUSED,
int32_t x,
int32_t y,
int32_t physicalWidth,
int32_t physicalHeight,
int32_t subpixel UNUSED,
const char* make,
const char* model,
int32_t transform UNUSED)
{
struct _GLFWmonitor *monitor = data;
char name[1024];
@@ -57,11 +59,11 @@ static void outputHandleGeometry(void* data,
}
static void outputHandleMode(void* data,
struct wl_output* output,
uint32_t flags,
int32_t width,
int32_t height,
int32_t refresh)
struct wl_output* output UNUSED,
uint32_t flags,
int32_t width,
int32_t height,
int32_t refresh)
{
struct _GLFWmonitor *monitor = data;
GLFWvidmode mode;
@@ -71,7 +73,7 @@ static void outputHandleMode(void* data,
mode.redBits = 8;
mode.greenBits = 8;
mode.blueBits = 8;
mode.refreshRate = (int)round(refresh / 1000.0);
mode.refreshRate = (int) round(refresh / 1000.0);
monitor->modeCount++;
monitor->modes =
@@ -82,16 +84,19 @@ static void outputHandleMode(void* data,
monitor->wl.currentMode = monitor->modeCount - 1;
}
static void outputHandleDone(void* data, struct wl_output* output)
static void outputHandleDone(void* data, struct wl_output* output UNUSED)
{
struct _GLFWmonitor *monitor = data;
for (int i = 0; i < _glfw.monitorCount; i++) {
if (_glfw.monitors[i] == monitor) return;
}
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
}
static void outputHandleScale(void* data,
struct wl_output* output,
int32_t factor)
struct wl_output* output UNUSED,
int32_t factor)
{
struct _GLFWmonitor *monitor = data;
if (factor > 0 && factor < 24)
@@ -170,7 +175,9 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
*yscale = (float) monitor->wl.scale;
}
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height)
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
int* xpos, int* ypos,
int* width, int* height)
{
if (xpos)
*xpos = monitor->wl.x;
@@ -193,14 +200,15 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
*mode = monitor->modes[monitor->wl.currentMode];
}
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor UNUSED, GLFWgammaramp* ramp UNUSED)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Gamma ramp access is not available");
return GLFW_FALSE;
return false;
}
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor UNUSED,
const GLFWgammaramp* ramp UNUSED)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Gamma ramp access is not available");

16
glfw/wl_platform.h vendored
View File

@@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.3 Wayland - www.glfw.org
// GLFW 3.4 Wayland - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
//
@@ -133,10 +133,10 @@ typedef struct _GLFWdecorationWayland
typedef struct _GLFWwindowWayland
{
int width, height;
GLFWbool visible;
GLFWbool maximized;
GLFWbool hovered;
GLFWbool transparent;
bool visible;
bool maximized;
bool hovered;
bool transparent;
struct wl_surface* surface;
struct wl_egl_window* native;
struct wl_callback* callback;
@@ -167,10 +167,10 @@ typedef struct _GLFWwindowWayland
struct zwp_idle_inhibitor_v1* idleInhibitor;
GLFWbool fullscreened;
bool fullscreened;
struct {
GLFWbool serverSide;
bool serverSide;
struct wl_buffer* buffer;
_GLFWdecorationWayland top, left, right, bottom;
int focus;
@@ -295,7 +295,7 @@ typedef struct _GLFWlibraryWayland
typedef struct _GLFWmonitorWayland
{
struct wl_output* output;
int name;
uint32_t name;
int currentMode;
int x;

307
glfw/wl_window.c vendored
View File

@@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.3 Wayland - www.glfw.org
// GLFW 3.4 Wayland - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
//
@@ -23,6 +23,8 @@
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#define _GNU_SOURCE
@@ -42,7 +44,7 @@
#define URI_LIST_MIME "text/uri-list"
static GLFWbool checkScaleChange(_GLFWwindow* window)
static bool checkScaleChange(_GLFWwindow* window)
{
int scale = 1;
int i;
@@ -50,7 +52,7 @@ static GLFWbool checkScaleChange(_GLFWwindow* window)
// Check if we will be able to set the buffer scale or not.
if (_glfw.wl.compositorVersion < 3)
return GLFW_FALSE;
return false;
// Get the scale factor from the highest scale monitor.
for (i = 0; i < window->wl.monitorsCount; ++i)
@@ -65,9 +67,9 @@ static GLFWbool checkScaleChange(_GLFWwindow* window)
{
window->wl.scale = scale;
wl_surface_set_buffer_scale(window->wl.surface, scale);
return GLFW_TRUE;
return true;
}
return GLFW_FALSE;
return false;
}
// Makes the surface considered as XRGB instead of ARGB.
@@ -137,8 +139,8 @@ clipboard_mime(void) {
static void dispatchChangesAfterConfigure(_GLFWwindow *window, int32_t width, int32_t height) {
if (width <= 0) width = window->wl.width;
if (height <= 0) height = window->wl.height;
GLFWbool size_changed = width != window->wl.width || height != window->wl.height;
GLFWbool scale_changed = checkScaleChange(window);
bool size_changed = width != window->wl.width || height != window->wl.height;
bool scale_changed = checkScaleChange(window);
if (size_changed) {
_glfwInputWindowSize(window, width, height);
@@ -171,7 +173,7 @@ static void dispatchChangesAfterConfigure(_GLFWwindow *window, int32_t width, in
* SCM_RIGHTS methods.
*
* posix_fallocate() is used to guarantee that disk space is available
* for the file at the given size. If disk space is insufficent, errno
* for the file at the given size. If disk space is insufficient, errno
* is set to ENOSPC. If posix_fallocate() is not supported, program may
* receive SIGBUS on accessing mmap()'ed file contents instead.
*/
@@ -239,7 +241,7 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image)
if (fd < 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Creating a buffer file for %d B failed: %m",
"Wayland: Creating a buffer file for %d B failed: %%m",
length);
return NULL;
}
@@ -248,7 +250,7 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image)
if (data == MAP_FAILED)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: mmap failed: %m");
"Wayland: mmap failed: %%m");
close(fd);
return NULL;
}
@@ -281,7 +283,7 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image)
static void createDecoration(_GLFWdecorationWayland* decoration,
struct wl_surface* parent,
struct wl_buffer* buffer, GLFWbool opaque,
struct wl_buffer* buffer, bool opaque,
int x, int y,
int width, int height)
{
@@ -313,7 +315,7 @@ static void createDecorations(_GLFWwindow* window)
{
unsigned char data[] = { 224, 224, 224, 255 };
const GLFWimage image = { 1, 1, data };
GLFWbool opaque = (data[3] == 255);
bool opaque = (data[3] == 255);
if (!_glfw.wl.viewporter || !window->decorated || window->wl.decorations.serverSide)
return;
@@ -363,12 +365,12 @@ static void destroyDecorations(_GLFWwindow* window)
}
static void xdgDecorationHandleConfigure(void* data,
struct zxdg_toplevel_decoration_v1* decoration,
struct zxdg_toplevel_decoration_v1* decoration UNUSED,
uint32_t mode)
{
_GLFWwindow* window = data;
window->wl.decorations.serverSide = (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
if (!window->wl.decorations.serverSide)
window->wl.decorations.serverSide = (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
if (!window->wl.decorations.serverSide)
createDecorations(window);
}
@@ -377,7 +379,7 @@ static const struct zxdg_toplevel_decoration_v1_listener xdgDecorationListener =
};
static void handleEnter(void *data,
struct wl_surface *surface,
struct wl_surface *surface UNUSED,
struct wl_output *output)
{
_GLFWwindow* window = data;
@@ -400,18 +402,18 @@ static void handleEnter(void *data,
}
static void handleLeave(void *data,
struct wl_surface *surface,
struct wl_surface *surface UNUSED,
struct wl_output *output)
{
_GLFWwindow* window = data;
_GLFWmonitor* monitor = wl_output_get_user_data(output);
GLFWbool found;
bool found;
int i;
for (i = 0, found = GLFW_FALSE; i < window->wl.monitorsCount - 1; ++i)
for (i = 0, found = false; i < window->wl.monitorsCount - 1; ++i)
{
if (monitor == window->wl.monitors[i])
found = GLFW_TRUE;
found = true;
if (found)
window->wl.monitors[i] = window->wl.monitors[i + 1];
}
@@ -428,7 +430,7 @@ static const struct wl_surface_listener surfaceListener = {
handleLeave
};
static void setIdleInhibitor(_GLFWwindow* window, GLFWbool enable)
static void setIdleInhibitor(_GLFWwindow* window, bool enable)
{
if (enable && !window->wl.idleInhibitor && _glfw.wl.idleInhibitManager)
{
@@ -446,12 +448,12 @@ static void setIdleInhibitor(_GLFWwindow* window, GLFWbool enable)
}
}
static GLFWbool createSurface(_GLFWwindow* window,
static bool createSurface(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig)
{
window->wl.surface = wl_compositor_create_surface(_glfw.wl.compositor);
if (!window->wl.surface)
return GLFW_FALSE;
return false;
wl_surface_add_listener(window->wl.surface,
&surfaceListener,
@@ -463,7 +465,7 @@ static GLFWbool createSurface(_GLFWwindow* window,
wndconfig->width,
wndconfig->height);
if (!window->wl.native)
return GLFW_FALSE;
return false;
window->wl.width = wndconfig->width;
window->wl.height = wndconfig->height;
@@ -472,7 +474,7 @@ static GLFWbool createSurface(_GLFWwindow* window,
if (!window->wl.transparent)
setOpaqueRegion(window);
return GLFW_TRUE;
return true;
}
static void
@@ -496,15 +498,14 @@ setFullscreen(_GLFWwindow* window, _GLFWmonitor* monitor, bool on)
}
bool
_glfwPlatformToggleFullscreen(_GLFWwindow *window, unsigned int flags) {
(void) flags;
_glfwPlatformToggleFullscreen(_GLFWwindow *window, unsigned int flags UNUSED) {
bool already_fullscreen = window->wl.fullscreened;
setFullscreen(window, NULL, !already_fullscreen);
return !already_fullscreen;
}
static void xdgToplevelHandleConfigure(void* data,
struct xdg_toplevel* toplevel,
struct xdg_toplevel* toplevel UNUSED,
int32_t width,
int32_t height,
struct wl_array* states)
@@ -513,24 +514,24 @@ static void xdgToplevelHandleConfigure(void* data,
float aspectRatio;
float targetRatio;
uint32_t* state;
GLFWbool maximized = GLFW_FALSE;
GLFWbool fullscreen = GLFW_FALSE;
GLFWbool activated = GLFW_FALSE;
bool maximized = false;
bool fullscreen = false;
bool activated = false;
wl_array_for_each(state, states)
{
switch (*state)
{
case XDG_TOPLEVEL_STATE_MAXIMIZED:
maximized = GLFW_TRUE;
maximized = true;
break;
case XDG_TOPLEVEL_STATE_FULLSCREEN:
fullscreen = GLFW_TRUE;
fullscreen = true;
break;
case XDG_TOPLEVEL_STATE_RESIZING:
break;
case XDG_TOPLEVEL_STATE_ACTIVATED:
activated = GLFW_TRUE;
activated = true;
break;
}
}
@@ -551,12 +552,18 @@ static void xdgToplevelHandleConfigure(void* data,
}
}
window->wl.fullscreened = fullscreen;
if (!fullscreen) {
if (window->decorated && !window->wl.decorations.serverSide && window->wl.decorations.buffer) {
width -= _GLFW_DECORATION_HORIZONTAL;
height -= _GLFW_DECORATION_VERTICAL;
}
}
dispatchChangesAfterConfigure(window, width, height);
_glfwInputWindowFocus(window, activated);
}
static void xdgToplevelHandleClose(void* data,
struct xdg_toplevel* toplevel)
struct xdg_toplevel* toplevel UNUSED)
{
_GLFWwindow* window = data;
_glfwInputWindowCloseRequest(window);
@@ -567,7 +574,7 @@ static const struct xdg_toplevel_listener xdgToplevelListener = {
xdgToplevelHandleClose
};
static void xdgSurfaceHandleConfigure(void* data,
static void xdgSurfaceHandleConfigure(void* data UNUSED,
struct xdg_surface* surface,
uint32_t serial)
{
@@ -594,12 +601,12 @@ static void setXdgDecorations(_GLFWwindow* window)
}
else
{
window->wl.decorations.serverSide = GLFW_FALSE;
window->wl.decorations.serverSide = false;
createDecorations(window);
}
}
static GLFWbool createXdgSurface(_GLFWwindow* window)
static bool createXdgSurface(_GLFWwindow* window)
{
window->wl.xdg.surface = xdg_wm_base_get_xdg_surface(_glfw.wl.wmBase,
window->wl.surface);
@@ -607,7 +614,7 @@ static GLFWbool createXdgSurface(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: xdg-surface creation failed");
return GLFW_FALSE;
return false;
}
xdg_surface_add_listener(window->wl.xdg.surface,
@@ -619,7 +626,7 @@ static GLFWbool createXdgSurface(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: xdg-toplevel creation failed");
return GLFW_FALSE;
return false;
}
xdg_toplevel_add_listener(window->wl.xdg.toplevel,
@@ -640,17 +647,17 @@ static GLFWbool createXdgSurface(_GLFWwindow* window)
{
xdg_toplevel_set_fullscreen(window->wl.xdg.toplevel,
window->monitor->wl.output);
setIdleInhibitor(window, GLFW_TRUE);
setIdleInhibitor(window, true);
}
else if (window->wl.maximized)
{
xdg_toplevel_set_maximized(window->wl.xdg.toplevel);
setIdleInhibitor(window, GLFW_FALSE);
setIdleInhibitor(window, false);
setXdgDecorations(window);
}
else
{
setIdleInhibitor(window, GLFW_FALSE);
setIdleInhibitor(window, false);
setXdgDecorations(window);
}
if (strlen(window->wl.appId))
@@ -659,7 +666,7 @@ static GLFWbool createXdgSurface(_GLFWwindow* window)
wl_surface_commit(window->wl.surface);
wl_display_roundtrip(_glfw.wl.display);
return GLFW_TRUE;
return true;
}
static void
@@ -720,7 +727,7 @@ incrementCursorImage(_GLFWwindow* window)
}
void
animateCursorImage(id_type timer_id, void *data) {
animateCursorImage(id_type timer_id UNUSED, void *data UNUSED) {
incrementCursorImage(_glfw.wl.pointerFocus);
}
@@ -733,6 +740,8 @@ abortOnFatalError(int last_error) {
_glfwInputWindowCloseRequest(window);
window = window->next;
}
// ensure the tick callback is called
_glfw.wl.eventLoopData.wakeup_data_read = true;
}
static void
@@ -740,16 +749,17 @@ handleEvents(double timeout)
{
struct wl_display* display = _glfw.wl.display;
errno = 0;
EVDBG("starting handleEvents(%.2f)", timeout);
while (wl_display_prepare_read(display) != 0) {
while(1) {
errno = 0;
int num_dispatched = wl_display_dispatch_pending(display);
if (num_dispatched == 0) return;
if (num_dispatched < 0) {
if (errno == EAGAIN) continue;
int last_error = wl_display_get_error(display);
if (last_error) abortOnFatalError(last_error);
wl_display_cancel_read(display);
return;
}
break;
@@ -767,10 +777,13 @@ handleEvents(double timeout)
return;
}
GLFWbool display_read_ok = pollForEvents(&_glfw.wl.eventLoopData, timeout);
bool display_read_ok = pollForEvents(&_glfw.wl.eventLoopData, timeout);
EVDBG("display_read_ok: %d", display_read_ok);
if (display_read_ok) {
wl_display_read_events(display);
wl_display_dispatch_pending(display);
int num = wl_display_dispatch_pending(display);
(void)num;
EVDBG("dispatched %d Wayland events", num);
}
else
{
@@ -778,6 +791,8 @@ handleEvents(double timeout)
}
glfw_ibus_dispatch(&_glfw.wl.xkb.ibus);
glfw_dbus_session_bus_dispatch();
EVDBG("other dispatch done");
if (_glfw.wl.eventLoopData.wakeup_fd_ready) check_for_wakeup_events(&_glfw.wl.eventLoopData);
}
static struct wl_cursor*
@@ -795,13 +810,13 @@ try_cursor_names(int arg_count, ...) {
struct wl_cursor* _glfwLoadCursor(GLFWCursorShape shape)
{
static GLFWbool warnings[GLFW_INVALID_CURSOR] = {0};
static bool warnings[GLFW_INVALID_CURSOR] = {0};
#define NUMARGS(...) (sizeof((const char*[]){__VA_ARGS__})/sizeof(const char*))
#define C(name, ...) case name: { \
ans = try_cursor_names(NUMARGS(__VA_ARGS__), __VA_ARGS__); \
if (!ans && !warnings[name]) {\
_glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Could not find standard cursor: %s", #name); \
warnings[name] = GLFW_TRUE; \
warnings[name] = true; \
} \
break; }
@@ -839,7 +854,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
strncpy(window->wl.appId, wndconfig->wl.appId, sizeof(window->wl.appId));
if (!createSurface(window, wndconfig))
return GLFW_FALSE;
return false;
if (ctxconfig->client != GLFW_NO_API)
{
@@ -847,16 +862,16 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
{
if (!_glfwInitEGL())
return GLFW_FALSE;
return false;
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
return GLFW_FALSE;
return false;
}
else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
{
if (!_glfwInitOSMesa())
return GLFW_FALSE;
return false;
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
return GLFW_FALSE;
return false;
}
}
@@ -866,15 +881,15 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (wndconfig->visible)
{
if (!createXdgSurface(window))
return GLFW_FALSE;
return false;
window->wl.visible = GLFW_TRUE;
window->wl.visible = true;
}
else
{
window->wl.xdg.surface = NULL;
window->wl.xdg.toplevel = NULL;
window->wl.visible = GLFW_FALSE;
window->wl.visible = false;
}
window->wl.currentCursor = NULL;
@@ -883,7 +898,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
window->wl.monitorsCount = 0;
window->wl.monitorsSize = 1;
return GLFW_TRUE;
return true;
}
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
@@ -891,12 +906,12 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
if (window == _glfw.wl.pointerFocus)
{
_glfw.wl.pointerFocus = NULL;
_glfwInputCursorEnter(window, GLFW_FALSE);
_glfwInputCursorEnter(window, false);
}
if (window == _glfw.wl.keyboardFocus)
{
_glfw.wl.keyboardFocus = NULL;
_glfwInputWindowFocus(window, GLFW_FALSE);
_glfwInputWindowFocus(window, false);
}
if (window->wl.idleInhibitor)
@@ -908,6 +923,7 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
destroyDecorations(window);
if (window->wl.xdg.decoration)
zxdg_toplevel_decoration_v1_destroy(window->wl.xdg.decoration);
if (window->wl.decorations.buffer)
wl_buffer_destroy(window->wl.decorations.buffer);
@@ -938,14 +954,14 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
xdg_toplevel_set_title(window->wl.xdg.toplevel, title);
}
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
int count, const GLFWimage* images)
void _glfwPlatformSetWindowIcon(_GLFWwindow* window UNUSED,
int count UNUSED, const GLFWimage* images UNUSED)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Setting window icon not supported");
}
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
void _glfwPlatformGetWindowPos(_GLFWwindow* window UNUSED, int* xpos UNUSED, int* ypos UNUSED)
{
// A Wayland client is not aware of its position, so just warn and leave it
// as (0, 0)
@@ -954,7 +970,7 @@ void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
"Wayland: Window position retrieval not supported");
}
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
void _glfwPlatformSetWindowPos(_GLFWwindow* window UNUSED, int xpos UNUSED, int ypos UNUSED)
{
// A Wayland client can not set its position, so just warn
@@ -995,13 +1011,15 @@ void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
}
}
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window UNUSED,
int numer UNUSED, int denom UNUSED)
{
// TODO: find out how to trigger a resize.
// The actual limits are checked in the xdg_toplevel::configure handler.
}
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window,
int* width, int* height)
{
_glfwPlatformGetWindowSize(window, width, height);
*width *= window->wl.scale;
@@ -1034,7 +1052,7 @@ void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
*yscale = (float) window->wl.scale;
}
double _glfwPlatformGetDoubleClickInterval(_GLFWwindow* window)
double _glfwPlatformGetDoubleClickInterval(_GLFWwindow* window UNUSED)
{
return 0.5;
}
@@ -1057,7 +1075,7 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
// minimized, so there is nothing to do in this case.
}
_glfwInputWindowMonitor(window, NULL);
window->wl.maximized = GLFW_FALSE;
window->wl.maximized = false;
}
void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
@@ -1066,7 +1084,7 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
{
xdg_toplevel_set_maximized(window->wl.xdg.toplevel);
}
window->wl.maximized = GLFW_TRUE;
window->wl.maximized = true;
}
void _glfwPlatformShowWindow(_GLFWwindow* window)
@@ -1074,7 +1092,7 @@ void _glfwPlatformShowWindow(_GLFWwindow* window)
if (!window->wl.visible)
{
createXdgSurface(window);
window->wl.visible = GLFW_TRUE;
window->wl.visible = true;
}
}
@@ -1087,34 +1105,34 @@ void _glfwPlatformHideWindow(_GLFWwindow* window)
window->wl.xdg.toplevel = NULL;
window->wl.xdg.surface = NULL;
}
window->wl.visible = GLFW_FALSE;
window->wl.visible = false;
}
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window UNUSED)
{
// TODO
static GLFWbool notified = GLFW_FALSE;
static bool notified = false;
if (!notified) {
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Window attention request not implemented yet");
notified = GLFW_TRUE;
notified = true;
}
}
int _glfwPlatformWindowBell(_GLFWwindow* window)
int _glfwPlatformWindowBell(_GLFWwindow* window UNUSED)
{
// TODO: Use an actual Wayland API to implement this when one becomes available
static char tty[L_ctermid + 1];
int fd = open(ctermid(tty), O_WRONLY | O_CLOEXEC);
if (fd > -1) {
int ret = write(fd, "\x07", 1) == 1 ? GLFW_TRUE : GLFW_FALSE;
int ret = write(fd, "\x07", 1) == 1 ? true : false;
close(fd);
return ret;
}
return GLFW_FALSE;
return false;
}
void _glfwPlatformFocusWindow(_GLFWwindow* window)
void _glfwPlatformFocusWindow(_GLFWwindow* window UNUSED)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Focusing a window requires user interaction");
@@ -1122,9 +1140,9 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window)
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
_GLFWmonitor* monitor,
int xpos, int ypos,
int width, int height,
int refreshRate)
int xpos UNUSED, int ypos UNUSED,
int width UNUSED, int height UNUSED,
int refreshRate UNUSED)
{
setFullscreen(window, monitor, monitor != NULL);
_glfwInputWindowMonitor(window, monitor);
@@ -1135,16 +1153,16 @@ int _glfwPlatformWindowFocused(_GLFWwindow* window)
return _glfw.wl.keyboardFocus == window;
}
int _glfwPlatformWindowOccluded(_GLFWwindow* window)
int _glfwPlatformWindowOccluded(_GLFWwindow* window UNUSED)
{
return GLFW_FALSE;
return false;
}
int _glfwPlatformWindowIconified(_GLFWwindow* window)
int _glfwPlatformWindowIconified(_GLFWwindow* window UNUSED)
{
// xdg-shell doesnt give any way to request whether a surface is
// iconified.
return GLFW_FALSE;
return false;
}
int _glfwPlatformWindowVisible(_GLFWwindow* window)
@@ -1167,14 +1185,14 @@ int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
return window->wl.transparent;
}
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
void _glfwPlatformSetWindowResizable(_GLFWwindow* window UNUSED, bool enabled UNUSED)
{
// TODO
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Window attribute setting not implemented yet");
}
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, bool enabled)
{
if (!window->monitor)
{
@@ -1185,19 +1203,19 @@ void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
}
}
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
void _glfwPlatformSetWindowFloating(_GLFWwindow* window UNUSED, bool enabled UNUSED)
{
// TODO
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Window attribute setting not implemented yet");
}
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window UNUSED)
{
return 1.f;
}
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window UNUSED, float opacity UNUSED)
{
}
@@ -1221,7 +1239,7 @@ void _glfwPlatformWaitEventsTimeout(double timeout)
void _glfwPlatformPostEmptyEvent(void)
{
while (write(_glfw.wl.eventLoopData.wakeupFds[1], "w", 1) < 0 && errno == EINTR);
wakeupEventLoop(&_glfw.wl.eventLoopData);
}
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
@@ -1232,7 +1250,7 @@ void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
*ypos = window->wl.cursorPosY;
}
static GLFWbool isPointerLocked(_GLFWwindow* window);
static bool isPointerLocked(_GLFWwindow* window);
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
{
@@ -1245,7 +1263,7 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
}
}
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode UNUSED)
{
_glfwPlatformSetCursor(window, window->wl.currentCursor);
}
@@ -1262,16 +1280,16 @@ int _glfwPlatformGetKeyScancode(int key)
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
const GLFWimage* image,
int xhot, int yhot, int count)
int xhot, int yhot, int count UNUSED)
{
cursor->wl.buffer = createShmBuffer(image);
if (!cursor->wl.buffer)
return GLFW_FALSE;
return false;
cursor->wl.width = image->width;
cursor->wl.height = image->height;
cursor->wl.xhot = xhot;
cursor->wl.yhot = yhot;
return GLFW_TRUE;
return true;
}
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, GLFWCursorShape shape)
@@ -1279,10 +1297,10 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, GLFWCursorShape shape
struct wl_cursor* standardCursor;
standardCursor = _glfwLoadCursor(shape);
if (!standardCursor) return GLFW_FALSE;
if (!standardCursor) return false;
cursor->wl.cursor = standardCursor;
cursor->wl.currentImage = 0;
return GLFW_TRUE;
return true;
}
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
@@ -1296,11 +1314,11 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
}
static void handleRelativeMotion(void* data,
struct zwp_relative_pointer_v1* pointer,
uint32_t timeHi,
uint32_t timeLo,
wl_fixed_t dx,
wl_fixed_t dy,
struct zwp_relative_pointer_v1* pointer UNUSED,
uint32_t timeHi UNUSED,
uint32_t timeLo UNUSED,
wl_fixed_t dx UNUSED,
wl_fixed_t dy UNUSED,
wl_fixed_t dxUnaccel,
wl_fixed_t dyUnaccel)
{
@@ -1318,8 +1336,8 @@ static const struct zwp_relative_pointer_v1_listener relativePointerListener = {
handleRelativeMotion
};
static void handleLocked(void* data,
struct zwp_locked_pointer_v1* lockedPointer)
static void handleLocked(void* data UNUSED,
struct zwp_locked_pointer_v1* lockedPointer UNUSED)
{
}
@@ -1337,10 +1355,10 @@ static void unlockPointer(_GLFWwindow* window)
window->wl.pointerLock.lockedPointer = NULL;
}
static void lockPointer(_GLFWwindow* window);
static void lockPointer(_GLFWwindow* window UNUSED);
static void handleUnlocked(void* data,
struct zwp_locked_pointer_v1* lockedPointer)
static void handleUnlocked(void* data UNUSED,
struct zwp_locked_pointer_v1* lockedPointer UNUSED)
{
}
@@ -1387,7 +1405,7 @@ static void lockPointer(_GLFWwindow* window)
NULL, 0, 0);
}
static GLFWbool isPointerLocked(_GLFWwindow* window)
static bool isPointerLocked(_GLFWwindow* window)
{
return window->wl.pointerLock.lockedPointer != NULL;
}
@@ -1462,12 +1480,12 @@ static void send_text(char *text, int fd)
close(fd);
}
static void _glfwSendClipboardText(void *data, struct wl_data_source *data_source, const char *mime_type, int fd) {
static void _glfwSendClipboardText(void *data UNUSED, struct wl_data_source *data_source UNUSED, const char *mime_type UNUSED, int fd) {
send_text(_glfw.wl.clipboardString, fd);
}
static void _glfwSendPrimarySelectionText(void *data, struct zwp_primary_selection_source_v1 *primary_selection_source,
const char *mime_type, int fd) {
static void _glfwSendPrimarySelectionText(void *data UNUSED, struct zwp_primary_selection_source_v1 *primary_selection_source UNUSED,
const char *mime_type UNUSED, int fd) {
send_text(_glfw.wl.primarySelectionString, fd);
}
@@ -1532,28 +1550,28 @@ static char* read_data_offer(struct wl_data_offer *data_offer, const char *mime)
return read_offer_string(pipefd[0]);
}
static void data_source_canceled(void *data, struct wl_data_source *wl_data_source) {
static void data_source_canceled(void *data UNUSED, struct wl_data_source *wl_data_source) {
if (_glfw.wl.dataSourceForClipboard == wl_data_source)
_glfw.wl.dataSourceForClipboard = NULL;
wl_data_source_destroy(wl_data_source);
}
static void primary_selection_source_canceled(void *data, struct zwp_primary_selection_source_v1 *primary_selection_source) {
static void primary_selection_source_canceled(void *data UNUSED, struct zwp_primary_selection_source_v1 *primary_selection_source) {
if (_glfw.wl.dataSourceForPrimarySelection == primary_selection_source)
_glfw.wl.dataSourceForPrimarySelection = NULL;
zwp_primary_selection_source_v1_destroy(primary_selection_source);
}
static void data_source_target(void *data, struct wl_data_source *wl_data_source, const char* mime) {
static void data_source_target(void *data UNUSED, struct wl_data_source *wl_data_source UNUSED, const char* mime UNUSED) {
}
const static struct wl_data_source_listener data_source_listener = {
static const struct wl_data_source_listener data_source_listener = {
.send = _glfwSendClipboardText,
.cancelled = data_source_canceled,
.target = data_source_target,
};
const static struct zwp_primary_selection_source_v1_listener primary_selection_source_listener = {
static const struct zwp_primary_selection_source_v1_listener primary_selection_source_listener = {
.send = _glfwSendPrimarySelectionText,
.cancelled = primary_selection_source_canceled,
};
@@ -1576,7 +1594,7 @@ static void prune_unclaimed_primary_selection_offers(void) {
}
}
static void mark_selection_offer(void *data, struct wl_data_device *data_device, struct wl_data_offer *data_offer)
static void mark_selection_offer(void *data UNUSED, struct wl_data_device *data_device UNUSED, struct wl_data_offer *data_offer)
{
for (size_t i = 0; i < arraysz(_glfw.wl.dataOffers); i++) {
if (_glfw.wl.dataOffers[i].id == data_offer) {
@@ -1588,7 +1606,7 @@ static void mark_selection_offer(void *data, struct wl_data_device *data_device,
prune_unclaimed_data_offers();
}
static void mark_primary_selection_offer(void *data, struct zwp_primary_selection_device_v1* primary_selection_device,
static void mark_primary_selection_offer(void *data UNUSED, struct zwp_primary_selection_device_v1* primary_selection_device UNUSED,
struct zwp_primary_selection_offer_v1 *primary_selection_offer) {
for (size_t i = 0; i < arraysz(_glfw.wl.primarySelectionOffers); i++) {
if (_glfw.wl.primarySelectionOffers[i].id == primary_selection_offer) {
@@ -1611,7 +1629,7 @@ static void set_offer_mimetype(struct _GLFWWaylandDataOffer* offer, const char*
offer->has_uri_list = 1;
}
static void handle_offer_mimetype(void *data, struct wl_data_offer* id, const char *mime) {
static void handle_offer_mimetype(void *data UNUSED, struct wl_data_offer* id, const char *mime) {
for (size_t i = 0; i < arraysz(_glfw.wl.dataOffers); i++) {
if (_glfw.wl.dataOffers[i].id == id) {
set_offer_mimetype(&_glfw.wl.dataOffers[i], mime);
@@ -1620,7 +1638,7 @@ static void handle_offer_mimetype(void *data, struct wl_data_offer* id, const ch
}
}
static void handle_primary_selection_offer_mimetype(void *data, struct zwp_primary_selection_offer_v1* id, const char *mime) {
static void handle_primary_selection_offer_mimetype(void *data UNUSED, struct zwp_primary_selection_offer_v1* id, const char *mime) {
for (size_t i = 0; i < arraysz(_glfw.wl.primarySelectionOffers); i++) {
if (_glfw.wl.primarySelectionOffers[i].id == id) {
set_offer_mimetype((struct _GLFWWaylandDataOffer*)&_glfw.wl.primarySelectionOffers[i], mime);
@@ -1629,7 +1647,7 @@ static void handle_primary_selection_offer_mimetype(void *data, struct zwp_prima
}
}
static void data_offer_source_actions(void *data, struct wl_data_offer* id, uint32_t actions) {
static void data_offer_source_actions(void *data UNUSED, struct wl_data_offer* id, uint32_t actions) {
for (size_t i = 0; i < arraysz(_glfw.wl.dataOffers); i++) {
if (_glfw.wl.dataOffers[i].id == id) {
_glfw.wl.dataOffers[i].source_actions = actions;
@@ -1638,7 +1656,7 @@ static void data_offer_source_actions(void *data, struct wl_data_offer* id, uint
}
}
static void data_offer_action(void *data, struct wl_data_offer* id, uint32_t action) {
static void data_offer_action(void *data UNUSED, struct wl_data_offer* id, uint32_t action) {
for (size_t i = 0; i < arraysz(_glfw.wl.dataOffers); i++) {
if (_glfw.wl.dataOffers[i].id == id) {
_glfw.wl.dataOffers[i].dnd_action = action;
@@ -1658,7 +1676,7 @@ static const struct zwp_primary_selection_offer_v1_listener primary_selection_of
.offer = handle_primary_selection_offer_mimetype,
};
static void handle_data_offer(void *data, struct wl_data_device *wl_data_device, struct wl_data_offer *id) {
static void handle_data_offer(void *data UNUSED, struct wl_data_device *wl_data_device UNUSED, struct wl_data_offer *id) {
size_t smallest_idx = SIZE_MAX, pos = 0;
for (size_t i = 0; i < arraysz(_glfw.wl.dataOffers); i++) {
if (_glfw.wl.dataOffers[i].idx && _glfw.wl.dataOffers[i].idx < smallest_idx) {
@@ -1679,7 +1697,7 @@ end:
wl_data_offer_add_listener(id, &data_offer_listener, NULL);
}
static void handle_primary_selection_offer(void *data, struct zwp_primary_selection_device_v1 *zwp_primary_selection_device_v1, struct zwp_primary_selection_offer_v1 *id) {
static void handle_primary_selection_offer(void *data UNUSED, struct zwp_primary_selection_device_v1 *zwp_primary_selection_device_v1 UNUSED, struct zwp_primary_selection_offer_v1 *id) {
size_t smallest_idx = SIZE_MAX, pos = 0;
for (size_t i = 0; i < arraysz(_glfw.wl.primarySelectionOffers); i++) {
if (_glfw.wl.primarySelectionOffers[i].idx && _glfw.wl.primarySelectionOffers[i].idx < smallest_idx) {
@@ -1700,7 +1718,7 @@ end:
zwp_primary_selection_offer_v1_add_listener(id, &primary_selection_offer_listener, NULL);
}
static void drag_enter(void *data, struct wl_data_device *wl_data_device, uint32_t serial, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *id) {
static void drag_enter(void *data UNUSED, struct wl_data_device *wl_data_device UNUSED, uint32_t serial, struct wl_surface *surface, wl_fixed_t x UNUSED, wl_fixed_t y UNUSED, struct wl_data_offer *id) {
for (size_t i = 0; i < arraysz(_glfw.wl.dataOffers); i++) {
if (_glfw.wl.dataOffers[i].id == id) {
_glfw.wl.dataOffers[i].offer_type = DRAG_AND_DROP;
@@ -1714,7 +1732,7 @@ static void drag_enter(void *data, struct wl_data_device *wl_data_device, uint32
prune_unclaimed_data_offers();
}
static void drag_leave(void *data, struct wl_data_device *wl_data_device) {
static void drag_leave(void *data UNUSED, struct wl_data_device *wl_data_device UNUSED) {
for (size_t i = 0; i < arraysz(_glfw.wl.dataOffers); i++) {
if (_glfw.wl.dataOffers[i].offer_type == DRAG_AND_DROP) {
wl_data_offer_destroy(_glfw.wl.dataOffers[i].id);
@@ -1723,7 +1741,7 @@ static void drag_leave(void *data, struct wl_data_device *wl_data_device) {
}
}
static void drop(void *data, struct wl_data_device *wl_data_device) {
static void drop(void *data, struct wl_data_device *wl_data_device UNUSED) {
for (size_t i = 0; i < arraysz(_glfw.wl.dataOffers); i++) {
if (_glfw.wl.dataOffers[i].offer_type == DRAG_AND_DROP) {
char *uri_list = read_data_offer(_glfw.wl.dataOffers[i].id, URI_LIST_MIME);
@@ -1755,10 +1773,10 @@ static void drop(void *data, struct wl_data_device *wl_data_device) {
}
}
static void motion(void *data, struct wl_data_device *wl_data_device, uint32_t time, wl_fixed_t x, wl_fixed_t y) {
static void motion(void *data UNUSED, struct wl_data_device *wl_data_device UNUSED, uint32_t time UNUSED, wl_fixed_t x UNUSED, wl_fixed_t y UNUSED) {
}
const static struct wl_data_device_listener data_device_listener = {
static const struct wl_data_device_listener data_device_listener = {
.data_offer = handle_data_offer,
.selection = mark_selection_offer,
.enter = drag_enter,
@@ -1767,7 +1785,7 @@ const static struct wl_data_device_listener data_device_listener = {
.leave = drag_leave,
};
const static struct zwp_primary_selection_device_v1_listener primary_selection_device_listener = {
static const struct zwp_primary_selection_device_v1_listener primary_selection_device_listener = {
.data_offer = handle_primary_selection_offer,
.selection = mark_primary_selection_offer,
};
@@ -1799,12 +1817,12 @@ void _glfwSetupWaylandPrimarySelectionDevice() {
if (_glfw.wl.primarySelectionDevice) zwp_primary_selection_device_v1_add_listener(_glfw.wl.primarySelectionDevice, &primary_selection_device_listener, NULL);
}
static inline GLFWbool _glfwEnsureDataDevice(void) {
static inline bool _glfwEnsureDataDevice(void) {
if (!_glfw.wl.dataDeviceManager)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Cannot use clipboard, data device manager is not ready");
return GLFW_FALSE;
return false;
}
if (!_glfw.wl.dataDevice)
@@ -1813,16 +1831,16 @@ static inline GLFWbool _glfwEnsureDataDevice(void) {
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Cannot use clipboard, seat is not ready");
return GLFW_FALSE;
return false;
}
if (!_glfw.wl.dataDevice)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Cannot use clipboard, failed to create data device");
return GLFW_FALSE;
"Wayland: Cannot use clipboard, failed to create data device");
return false;
}
}
return GLFW_TRUE;
return true;
}
void _glfwPlatformSetClipboardString(const char* string)
@@ -1847,7 +1865,7 @@ void _glfwPlatformSetClipboardString(const char* string)
wl_data_source_offer(_glfw.wl.dataSourceForClipboard, "STRING");
wl_data_source_offer(_glfw.wl.dataSourceForClipboard, "UTF8_STRING");
struct wl_callback *callback = wl_display_sync(_glfw.wl.display);
const static struct wl_callback_listener clipboard_copy_callback_listener = {.done = clipboard_copy_callback_done};
static const struct wl_callback_listener clipboard_copy_callback_listener = {.done = clipboard_copy_callback_done};
wl_callback_add_listener(callback, &clipboard_copy_callback_listener, _glfw.wl.dataSourceForClipboard);
}
@@ -1867,11 +1885,11 @@ const char* _glfwPlatformGetClipboardString(void)
void _glfwPlatformSetPrimarySelectionString(const char* string)
{
if (!_glfw.wl.primarySelectionDevice) {
static GLFWbool warned_about_primary_selection_device = GLFW_FALSE;
static bool warned_about_primary_selection_device = false;
if (!warned_about_primary_selection_device) {
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Cannot copy no primary selection device available");
warned_about_primary_selection_device = GLFW_TRUE;
warned_about_primary_selection_device = true;
}
return;
}
@@ -1896,7 +1914,7 @@ void _glfwPlatformSetPrimarySelectionString(const char* string)
zwp_primary_selection_source_v1_offer(_glfw.wl.dataSourceForPrimarySelection, "STRING");
zwp_primary_selection_source_v1_offer(_glfw.wl.dataSourceForPrimarySelection, "UTF8_STRING");
struct wl_callback *callback = wl_display_sync(_glfw.wl.display);
const static struct wl_callback_listener primary_selection_copy_callback_listener = {.done = primary_selection_copy_callback_done};
static const struct wl_callback_listener primary_selection_copy_callback_listener = {.done = primary_selection_copy_callback_done};
wl_callback_add_listener(callback, &primary_selection_copy_callback_listener, _glfw.wl.dataSourceForPrimarySelection);
}
@@ -1986,7 +2004,7 @@ _glfwPlatformUpdateIMEState(_GLFWwindow *w, int which, int a, int b, int c, int
}
static void
frame_handle_redraw(void *data, struct wl_callback *callback, uint32_t time) {
frame_handle_redraw(void *data, struct wl_callback *callback, uint32_t time UNUSED) {
_GLFWwindow* window = (_GLFWwindow*) data;
if (callback == window->wl.frameCallbackData.current_wl_callback) {
window->wl.frameCallbackData.callback(window->wl.frameCallbackData.id);
@@ -1995,6 +2013,7 @@ frame_handle_redraw(void *data, struct wl_callback *callback, uint32_t time) {
wl_callback_destroy(callback);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW native API //////
//////////////////////////////////////////////////////////////////////////
@@ -2012,7 +2031,7 @@ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* handle)
return window->wl.surface;
}
GLFWAPI int glfwGetXKBScancode(const char* keyName, GLFWbool caseSensitive) {
GLFWAPI int glfwGetXKBScancode(const char* keyName, bool caseSensitive) {
return glfw_xkb_keysym_from_name(keyName, caseSensitive);
}

214
glfw/x11_init.c vendored
View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 X11 - www.glfw.org
// GLFW 3.4 X11 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -24,6 +24,8 @@
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#define _GNU_SOURCE
#include "internal.h"
@@ -46,10 +48,9 @@ static Atom getSupportedAtom(Atom* supportedAtoms,
unsigned long atomCount,
const char* atomName)
{
unsigned long i;
const Atom atom = XInternAtom(_glfw.x11.display, atomName, False);
for (i = 0; i < atomCount; i++)
for (unsigned long i = 0; i < atomCount; i++)
{
if (supportedAtoms[i] == atom)
return atom;
@@ -62,18 +63,12 @@ static Atom getSupportedAtom(Atom* supportedAtoms,
//
static void detectEWMH(void)
{
// First we read the _NET_SUPPORTING_WM_CHECK property on the root window
Window* windowFromRoot = NULL;
Window* windowFromChild = NULL;
// First we need a couple of atoms
const Atom supportingWmCheck =
XInternAtom(_glfw.x11.display, "_NET_SUPPORTING_WM_CHECK", False);
const Atom wmSupported =
XInternAtom(_glfw.x11.display, "_NET_SUPPORTED", False);
// Then we look for the _NET_SUPPORTING_WM_CHECK property of the root window
if (!_glfwGetWindowPropertyX11(_glfw.x11.root,
supportingWmCheck,
_glfw.x11.NET_SUPPORTING_WM_CHECK,
XA_WINDOW,
(unsigned char**) &windowFromRoot))
{
@@ -82,10 +77,12 @@ static void detectEWMH(void)
_glfwGrabErrorHandlerX11();
// It should be the ID of a child window (of the root)
// Then we look for the same property on the child window
// If it exists, it should be the XID of a top-level window
// Then we look for the same property on that window
Window* windowFromChild = NULL;
if (!_glfwGetWindowPropertyX11(*windowFromRoot,
supportingWmCheck,
_glfw.x11.NET_SUPPORTING_WM_CHECK,
XA_WINDOW,
(unsigned char**) &windowFromChild))
{
@@ -95,7 +92,7 @@ static void detectEWMH(void)
_glfwReleaseErrorHandlerX11();
// It should be the ID of that same child window
// If the property exists, it should contain the XID of the window
if (*windowFromRoot != *windowFromChild)
{
XFree(windowFromRoot);
@@ -107,18 +104,20 @@ static void detectEWMH(void)
XFree(windowFromChild);
// We are now fairly sure that an EWMH-compliant window manager is running
// We can now start querying the WM about what features it supports by
// looking in the _NET_SUPPORTED property on the root window
// It should contain a list of supported EWMH protocol and state atoms
Atom* supportedAtoms;
unsigned long atomCount;
// Now we need to check the _NET_SUPPORTED property of the root window
// It should be a list of supported WM protocol and state atoms
atomCount = _glfwGetWindowPropertyX11(_glfw.x11.root,
wmSupported,
Atom* supportedAtoms = NULL;
const unsigned long atomCount = _glfwGetWindowPropertyX11(_glfw.x11.root,
_glfw.x11.NET_SUPPORTED,
XA_ATOM,
(unsigned char**) &supportedAtoms);
if (!supportedAtoms)
return;
// See which of the atoms we support that are supported by the WM
_glfw.x11.NET_WM_STATE =
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE");
_glfw.x11.NET_WM_STATE_ABOVE =
@@ -148,25 +147,20 @@ static void detectEWMH(void)
_glfw.x11.NET_REQUEST_FRAME_EXTENTS =
getSupportedAtom(supportedAtoms, atomCount, "_NET_REQUEST_FRAME_EXTENTS");
if (supportedAtoms)
XFree(supportedAtoms);
XFree(supportedAtoms);
}
// Look for and initialize supported X11 extensions
//
static GLFWbool initExtensions(void)
static bool initExtensions(void)
{
_glfw.x11.vidmode.handle = _glfw_dlopen("libXxf86vm.so.1");
if (_glfw.x11.vidmode.handle)
{
_glfw.x11.vidmode.QueryExtension = (PFN_XF86VidModeQueryExtension)
_glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeQueryExtension");
_glfw.x11.vidmode.GetGammaRamp = (PFN_XF86VidModeGetGammaRamp)
_glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRamp");
_glfw.x11.vidmode.SetGammaRamp = (PFN_XF86VidModeSetGammaRamp)
_glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeSetGammaRamp");
_glfw.x11.vidmode.GetGammaRampSize = (PFN_XF86VidModeGetGammaRampSize)
_glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRampSize");
glfw_dlsym(_glfw.x11.vidmode.QueryExtension, _glfw.x11.vidmode.handle, "XF86VidModeQueryExtension");
glfw_dlsym(_glfw.x11.vidmode.GetGammaRamp, _glfw.x11.vidmode.handle, "XF86VidModeGetGammaRamp");
glfw_dlsym(_glfw.x11.vidmode.SetGammaRamp, _glfw.x11.vidmode.handle, "XF86VidModeSetGammaRamp");
glfw_dlsym(_glfw.x11.vidmode.GetGammaRampSize, _glfw.x11.vidmode.handle, "XF86VidModeGetGammaRampSize");
_glfw.x11.vidmode.available =
XF86VidModeQueryExtension(_glfw.x11.display,
@@ -181,10 +175,8 @@ static GLFWbool initExtensions(void)
#endif
if (_glfw.x11.xi.handle)
{
_glfw.x11.xi.QueryVersion = (PFN_XIQueryVersion)
_glfw_dlsym(_glfw.x11.xi.handle, "XIQueryVersion");
_glfw.x11.xi.SelectEvents = (PFN_XISelectEvents)
_glfw_dlsym(_glfw.x11.xi.handle, "XISelectEvents");
glfw_dlsym(_glfw.x11.xi.QueryVersion, _glfw.x11.xi.handle, "XIQueryVersion");
glfw_dlsym(_glfw.x11.xi.SelectEvents, _glfw.x11.xi.handle, "XISelectEvents");
if (XQueryExtension(_glfw.x11.display,
"XInputExtension",
@@ -199,7 +191,7 @@ static GLFWbool initExtensions(void)
&_glfw.x11.xi.major,
&_glfw.x11.xi.minor) == Success)
{
_glfw.x11.xi.available = GLFW_TRUE;
_glfw.x11.xi.available = true;
}
}
}
@@ -211,42 +203,24 @@ static GLFWbool initExtensions(void)
#endif
if (_glfw.x11.randr.handle)
{
_glfw.x11.randr.AllocGamma = (PFN_XRRAllocGamma)
_glfw_dlsym(_glfw.x11.randr.handle, "XRRAllocGamma");
_glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma)
_glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeGamma");
_glfw.x11.randr.FreeCrtcInfo = (PFN_XRRFreeCrtcInfo)
_glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeCrtcInfo");
_glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma)
_glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeGamma");
_glfw.x11.randr.FreeOutputInfo = (PFN_XRRFreeOutputInfo)
_glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeOutputInfo");
_glfw.x11.randr.FreeScreenResources = (PFN_XRRFreeScreenResources)
_glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeScreenResources");
_glfw.x11.randr.GetCrtcGamma = (PFN_XRRGetCrtcGamma)
_glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGamma");
_glfw.x11.randr.GetCrtcGammaSize = (PFN_XRRGetCrtcGammaSize)
_glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGammaSize");
_glfw.x11.randr.GetCrtcInfo = (PFN_XRRGetCrtcInfo)
_glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcInfo");
_glfw.x11.randr.GetOutputInfo = (PFN_XRRGetOutputInfo)
_glfw_dlsym(_glfw.x11.randr.handle, "XRRGetOutputInfo");
_glfw.x11.randr.GetOutputPrimary = (PFN_XRRGetOutputPrimary)
_glfw_dlsym(_glfw.x11.randr.handle, "XRRGetOutputPrimary");
_glfw.x11.randr.GetScreenResourcesCurrent = (PFN_XRRGetScreenResourcesCurrent)
_glfw_dlsym(_glfw.x11.randr.handle, "XRRGetScreenResourcesCurrent");
_glfw.x11.randr.QueryExtension = (PFN_XRRQueryExtension)
_glfw_dlsym(_glfw.x11.randr.handle, "XRRQueryExtension");
_glfw.x11.randr.QueryVersion = (PFN_XRRQueryVersion)
_glfw_dlsym(_glfw.x11.randr.handle, "XRRQueryVersion");
_glfw.x11.randr.SelectInput = (PFN_XRRSelectInput)
_glfw_dlsym(_glfw.x11.randr.handle, "XRRSelectInput");
_glfw.x11.randr.SetCrtcConfig = (PFN_XRRSetCrtcConfig)
_glfw_dlsym(_glfw.x11.randr.handle, "XRRSetCrtcConfig");
_glfw.x11.randr.SetCrtcGamma = (PFN_XRRSetCrtcGamma)
_glfw_dlsym(_glfw.x11.randr.handle, "XRRSetCrtcGamma");
_glfw.x11.randr.UpdateConfiguration = (PFN_XRRUpdateConfiguration)
_glfw_dlsym(_glfw.x11.randr.handle, "XRRUpdateConfiguration");
glfw_dlsym(_glfw.x11.randr.AllocGamma, _glfw.x11.randr.handle, "XRRAllocGamma");
glfw_dlsym(_glfw.x11.randr.FreeGamma, _glfw.x11.randr.handle, "XRRFreeGamma");
glfw_dlsym(_glfw.x11.randr.FreeCrtcInfo, _glfw.x11.randr.handle, "XRRFreeCrtcInfo");
glfw_dlsym(_glfw.x11.randr.FreeGamma, _glfw.x11.randr.handle, "XRRFreeGamma");
glfw_dlsym(_glfw.x11.randr.FreeOutputInfo, _glfw.x11.randr.handle, "XRRFreeOutputInfo");
glfw_dlsym(_glfw.x11.randr.FreeScreenResources, _glfw.x11.randr.handle, "XRRFreeScreenResources");
glfw_dlsym(_glfw.x11.randr.GetCrtcGamma, _glfw.x11.randr.handle, "XRRGetCrtcGamma");
glfw_dlsym(_glfw.x11.randr.GetCrtcGammaSize, _glfw.x11.randr.handle, "XRRGetCrtcGammaSize");
glfw_dlsym(_glfw.x11.randr.GetCrtcInfo, _glfw.x11.randr.handle, "XRRGetCrtcInfo");
glfw_dlsym(_glfw.x11.randr.GetOutputInfo, _glfw.x11.randr.handle, "XRRGetOutputInfo");
glfw_dlsym(_glfw.x11.randr.GetOutputPrimary, _glfw.x11.randr.handle, "XRRGetOutputPrimary");
glfw_dlsym(_glfw.x11.randr.GetScreenResourcesCurrent, _glfw.x11.randr.handle, "XRRGetScreenResourcesCurrent");
glfw_dlsym(_glfw.x11.randr.QueryExtension, _glfw.x11.randr.handle, "XRRQueryExtension");
glfw_dlsym(_glfw.x11.randr.QueryVersion, _glfw.x11.randr.handle, "XRRQueryVersion");
glfw_dlsym(_glfw.x11.randr.SelectInput, _glfw.x11.randr.handle, "XRRSelectInput");
glfw_dlsym(_glfw.x11.randr.SetCrtcConfig, _glfw.x11.randr.handle, "XRRSetCrtcConfig");
glfw_dlsym(_glfw.x11.randr.SetCrtcGamma, _glfw.x11.randr.handle, "XRRSetCrtcGamma");
glfw_dlsym(_glfw.x11.randr.UpdateConfiguration, _glfw.x11.randr.handle, "XRRUpdateConfiguration");
if (XRRQueryExtension(_glfw.x11.display,
&_glfw.x11.randr.eventBase,
@@ -258,7 +232,7 @@ static GLFWbool initExtensions(void)
{
// The GLFW RandR path requires at least version 1.3
if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3)
_glfw.x11.randr.available = GLFW_TRUE;
_glfw.x11.randr.available = true;
}
else
{
@@ -277,14 +251,14 @@ static GLFWbool initExtensions(void)
{
// This is likely an older Nvidia driver with broken gamma support
// Flag it as useless and fall back to xf86vm gamma, if available
_glfw.x11.randr.gammaBroken = GLFW_TRUE;
_glfw.x11.randr.gammaBroken = true;
}
if (!sr->ncrtc)
{
// A system without CRTCs is likely a system with broken RandR
// Disable the RandR monitor path and fall back to core functions
_glfw.x11.randr.monitorBroken = GLFW_TRUE;
_glfw.x11.randr.monitorBroken = true;
}
XRRFreeScreenResources(sr);
@@ -303,12 +277,9 @@ static GLFWbool initExtensions(void)
#endif
if (_glfw.x11.xcursor.handle)
{
_glfw.x11.xcursor.ImageCreate = (PFN_XcursorImageCreate)
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageCreate");
_glfw.x11.xcursor.ImageDestroy = (PFN_XcursorImageDestroy)
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageDestroy");
_glfw.x11.xcursor.ImageLoadCursor = (PFN_XcursorImageLoadCursor)
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageLoadCursor");
glfw_dlsym(_glfw.x11.xcursor.ImageCreate, _glfw.x11.xcursor.handle, "XcursorImageCreate");
glfw_dlsym(_glfw.x11.xcursor.ImageDestroy, _glfw.x11.xcursor.handle, "XcursorImageDestroy");
glfw_dlsym(_glfw.x11.xcursor.ImageLoadCursor, _glfw.x11.xcursor.handle, "XcursorImageLoadCursor");
}
#if defined(__CYGWIN__)
@@ -318,19 +289,16 @@ static GLFWbool initExtensions(void)
#endif
if (_glfw.x11.xinerama.handle)
{
_glfw.x11.xinerama.IsActive = (PFN_XineramaIsActive)
_glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaIsActive");
_glfw.x11.xinerama.QueryExtension = (PFN_XineramaQueryExtension)
_glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaQueryExtension");
_glfw.x11.xinerama.QueryScreens = (PFN_XineramaQueryScreens)
_glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaQueryScreens");
glfw_dlsym(_glfw.x11.xinerama.IsActive, _glfw.x11.xinerama.handle, "XineramaIsActive");
glfw_dlsym(_glfw.x11.xinerama.QueryExtension, _glfw.x11.xinerama.handle, "XineramaQueryExtension");
glfw_dlsym(_glfw.x11.xinerama.QueryScreens, _glfw.x11.xinerama.handle, "XineramaQueryScreens");
if (XineramaQueryExtension(_glfw.x11.display,
&_glfw.x11.xinerama.major,
&_glfw.x11.xinerama.minor))
{
if (XineramaIsActive(_glfw.x11.display))
_glfw.x11.xinerama.available = GLFW_TRUE;
_glfw.x11.xinerama.available = true;
}
}
@@ -341,12 +309,9 @@ static GLFWbool initExtensions(void)
#endif
if (_glfw.x11.xrender.handle)
{
_glfw.x11.xrender.QueryExtension = (PFN_XRenderQueryExtension)
_glfw_dlsym(_glfw.x11.xrender.handle, "XRenderQueryExtension");
_glfw.x11.xrender.QueryVersion = (PFN_XRenderQueryVersion)
_glfw_dlsym(_glfw.x11.xrender.handle, "XRenderQueryVersion");
_glfw.x11.xrender.FindVisualFormat = (PFN_XRenderFindVisualFormat)
_glfw_dlsym(_glfw.x11.xrender.handle, "XRenderFindVisualFormat");
glfw_dlsym(_glfw.x11.xrender.QueryExtension, _glfw.x11.xrender.handle, "XRenderQueryExtension");
glfw_dlsym(_glfw.x11.xrender.QueryVersion, _glfw.x11.xrender.handle, "XRenderQueryVersion");
glfw_dlsym(_glfw.x11.xrender.FindVisualFormat, _glfw.x11.xrender.handle, "XRenderFindVisualFormat");
if (XRenderQueryExtension(_glfw.x11.display,
&_glfw.x11.xrender.errorBase,
@@ -356,7 +321,7 @@ static GLFWbool initExtensions(void)
&_glfw.x11.xrender.major,
&_glfw.x11.xrender.minor))
{
_glfw.x11.xrender.available = GLFW_TRUE;
_glfw.x11.xrender.available = true;
}
}
}
@@ -373,22 +338,19 @@ static GLFWbool initExtensions(void)
if (!_glfw.x11.xkb.available)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to load Xkb extension");
return GLFW_FALSE;
return false;
}
Bool supported;
if (XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported))
{
if (supported)
_glfw.x11.xkb.detectable = GLFW_TRUE;
_glfw.x11.xkb.detectable = true;
}
if (!glfw_xkb_set_x11_events_mask()) return GLFW_FALSE;
if (!glfw_xkb_create_context(&_glfw.x11.xkb)) return GLFW_FALSE;
if (!glfw_xkb_update_x11_keyboard_id(&_glfw.x11.xkb)) return GLFW_FALSE;
if (!glfw_xkb_compile_keymap(&_glfw.x11.xkb, NULL)) return GLFW_FALSE;
// Detect whether an EWMH-conformant window manager is running
detectEWMH();
if (!glfw_xkb_set_x11_events_mask()) return false;
if (!glfw_xkb_create_context(&_glfw.x11.xkb)) return false;
if (!glfw_xkb_update_x11_keyboard_id(&_glfw.x11.xkb)) return false;
if (!glfw_xkb_compile_keymap(&_glfw.x11.xkb, NULL)) return false;
// String format atoms
_glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False);
@@ -433,6 +395,10 @@ static GLFWbool initExtensions(void)
XInternAtom(_glfw.x11.display, "WM_STATE", False);
_glfw.x11.WM_DELETE_WINDOW =
XInternAtom(_glfw.x11.display, "WM_DELETE_WINDOW", False);
_glfw.x11.NET_SUPPORTED =
XInternAtom(_glfw.x11.display, "_NET_SUPPORTED", False);
_glfw.x11.NET_SUPPORTING_WM_CHECK =
XInternAtom(_glfw.x11.display, "_NET_SUPPORTING_WM_CHECK", False);
_glfw.x11.NET_WM_ICON =
XInternAtom(_glfw.x11.display, "_NET_WM_ICON", False);
_glfw.x11.NET_WM_PING =
@@ -457,12 +423,15 @@ static GLFWbool initExtensions(void)
_glfw.x11.NET_WM_CM_Sx = XInternAtom(_glfw.x11.display, name, False);
}
return GLFW_TRUE;
// Detect whether an EWMH-conformant window manager is running
detectEWMH();
return true;
}
// Retrieve system content scale via folklore heuristics
//
void _glfwGetSystemContentScaleX11(float* xscale, float* yscale, GLFWbool bypass_cache)
void _glfwGetSystemContentScaleX11(float* xscale, float* yscale, bool bypass_cache)
{
// NOTE: Default to the display-wide DPI as we don't currently have a policy
// for which monitor a window is considered to be on
@@ -536,7 +505,7 @@ static Window createHelperWindow(void)
// X error handler
//
static int errorHandler(Display *display, XErrorEvent* event)
static int errorHandler(Display *display UNUSED, XErrorEvent* event)
{
_glfw.x11.errorCode = event->error_code;
return 0;
@@ -611,6 +580,7 @@ Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot)
return cursor;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
@@ -620,13 +590,6 @@ int _glfwPlatformInit(void)
XInitThreads();
XrmInitialize();
if (pipe2(_glfw.x11.eventLoopData.wakeupFds, O_CLOEXEC | O_NONBLOCK) != 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: failed to create self pipe");
return GLFW_FALSE;
}
_glfw.x11.display = XOpenDisplay(NULL);
if (!_glfw.x11.display)
{
@@ -642,10 +605,13 @@ int _glfwPlatformInit(void)
"X11: The DISPLAY environment variable is missing");
}
return GLFW_FALSE;
return false;
}
initPollData(&_glfw.x11.eventLoopData, _glfw.x11.eventLoopData.wakeupFds[0], ConnectionNumber(_glfw.x11.display));
if (!initPollData(&_glfw.x11.eventLoopData, ConnectionNumber(_glfw.x11.display))) {
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to initialize event loop data");
}
glfw_dbus_init(&_glfw.x11.dbus, &_glfw.x11.eventLoopData);
_glfw.x11.screen = DefaultScreen(_glfw.x11.display);
@@ -654,10 +620,10 @@ int _glfwPlatformInit(void)
_glfw.x11.RESOURCE_MANAGER = XInternAtom(_glfw.x11.display, "RESOURCE_MANAGER", True);
XSelectInput(_glfw.x11.display, _glfw.x11.root, PropertyChangeMask);
_glfwGetSystemContentScaleX11(&_glfw.x11.contentScaleX, &_glfw.x11.contentScaleY, GLFW_FALSE);
_glfwGetSystemContentScaleX11(&_glfw.x11.contentScaleX, &_glfw.x11.contentScaleY, false);
if (!initExtensions())
return GLFW_FALSE;
return false;
_glfw.x11.helperWindowHandle = createHelperWindow();
_glfw.x11.hiddenCursorHandle = createHiddenCursor();
@@ -665,7 +631,7 @@ int _glfwPlatformInit(void)
#if defined(__linux__)
if (_glfw.hints.init.enableJoysticks) {
if (!_glfwInitJoysticksLinux())
return GLFW_FALSE;
return false;
if (_glfw.linjs.inotify > 0)
addWatch(&_glfw.x11.eventLoopData, "joystick", _glfw.linjs.inotify, POLLIN, 1, NULL, NULL);
}
@@ -674,7 +640,7 @@ int _glfwPlatformInit(void)
_glfwInitTimerPOSIX();
_glfwPollMonitorsX11();
return GLFW_TRUE;
return true;
}
void _glfwPlatformTerminate(void)
@@ -754,7 +720,7 @@ void _glfwPlatformTerminate(void)
#if defined(__linux__)
_glfwTerminateJoysticksLinux();
#endif
closeFds(_glfw.x11.eventLoopData.wakeupFds, sizeof(_glfw.x11.eventLoopData.wakeupFds)/sizeof(_glfw.x11.eventLoopData.wakeupFds[0]));
finalizePollData(&_glfw.x11.eventLoopData);
}
const char* _glfwPlatformGetVersionString(void)

106
glfw/x11_monitor.c vendored
View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 X11 - www.glfw.org
// GLFW 3.4 X11 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -24,6 +24,8 @@
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include "internal.h"
@@ -35,7 +37,7 @@
// Check whether the display mode should be included in enumeration
//
static GLFWbool modeIsGood(const XRRModeInfo* mi)
static bool modeIsGood(const XRRModeInfo* mi)
{
return (mi->modeFlags & RR_Interlace) == 0;
}
@@ -54,9 +56,7 @@ static int calculateRefreshRate(const XRRModeInfo* mi)
//
static const XRRModeInfo* getModeInfo(const XRRScreenResources* sr, RRMode id)
{
int i;
for (i = 0; i < sr->nmode; i++)
for (int i = 0; i < sr->nmode; i++)
{
if (sr->modes[i].id == id)
return sr->modes + i;
@@ -102,7 +102,7 @@ void _glfwPollMonitorsX11(void)
{
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
{
int i, j, disconnectedCount, screenCount = 0;
int disconnectedCount, screenCount = 0;
_GLFWmonitor** disconnected = NULL;
XineramaScreenInfo* screens = NULL;
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display,
@@ -122,14 +122,11 @@ void _glfwPollMonitorsX11(void)
_glfw.monitorCount * sizeof(_GLFWmonitor*));
}
for (i = 0; i < sr->noutput; i++)
for (int i = 0; i < sr->noutput; i++)
{
int type, widthMM, heightMM;
XRROutputInfo* oi;
XRRCrtcInfo* ci;
_GLFWmonitor* monitor;
int j, type, widthMM, heightMM;
oi = XRRGetOutputInfo(_glfw.x11.display, sr, sr->outputs[i]);
XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, sr->outputs[i]);
if (oi->connection != RR_Connected || oi->crtc == None)
{
XRRFreeOutputInfo(oi);
@@ -152,7 +149,7 @@ void _glfwPollMonitorsX11(void)
continue;
}
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, oi->crtc);
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, oi->crtc);
if (!ci)
{
XRRFreeOutputInfo(oi);
@@ -169,7 +166,7 @@ void _glfwPollMonitorsX11(void)
heightMM = oi->mm_height;
}
monitor = _glfwAllocMonitor(oi->name, widthMM, heightMM);
_GLFWmonitor* monitor = _glfwAllocMonitor(oi->name, widthMM, heightMM);
monitor->x11.output = sr->outputs[i];
monitor->x11.crtc = oi->crtc;
@@ -177,8 +174,8 @@ void _glfwPollMonitorsX11(void)
{
if (screens[j].x_org == ci->x &&
screens[j].y_org == ci->y &&
screens[j].width == ci->width &&
screens[j].height == ci->height)
screens[j].width == (short int)ci->width &&
screens[j].height == (short int)ci->height)
{
monitor->x11.index = j;
break;
@@ -201,7 +198,7 @@ void _glfwPollMonitorsX11(void)
if (screens)
XFree(screens);
for (i = 0; i < disconnectedCount; i++)
for (int i = 0; i < disconnectedCount; i++)
{
if (disconnected[i])
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
@@ -226,24 +223,19 @@ void _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired)
{
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
{
XRRScreenResources* sr;
XRRCrtcInfo* ci;
XRROutputInfo* oi;
GLFWvidmode current;
const GLFWvidmode* best;
RRMode native = None;
int i;
best = _glfwChooseVideoMode(monitor, desired);
const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired);
_glfwPlatformGetVideoMode(monitor, &current);
if (_glfwCompareVideoModes(&current, best) == 0)
return;
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
for (i = 0; i < oi->nmode; i++)
for (int i = 0; i < oi->nmode; i++)
{
const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]);
if (!modeIsGood(mi))
@@ -284,14 +276,11 @@ void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor)
{
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
{
XRRScreenResources* sr;
XRRCrtcInfo* ci;
if (monitor->x11.oldMode == None)
return;
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
XRRSetCrtcConfig(_glfw.x11.display,
sr, monitor->x11.crtc,
@@ -314,7 +303,7 @@ void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor)
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor UNUSED)
{
}
@@ -322,11 +311,9 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
{
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
{
XRRScreenResources* sr;
XRRCrtcInfo* ci;
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
if (ci)
{
if (xpos)
@@ -340,7 +327,7 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
}
}
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor UNUSED,
float* xscale, float* yscale)
{
if (xscale)
@@ -349,17 +336,15 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
*yscale = _glfw.x11.contentScaleY;
}
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height)
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height)
{
int areaX = 0, areaY = 0, areaWidth = 0, areaHeight = 0;
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
{
XRRScreenResources* sr;
XRRCrtcInfo* ci;
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
areaX = ci->x;
areaY = ci->y;
@@ -451,24 +436,20 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
{
int i, j;
XRRScreenResources* sr;
XRRCrtcInfo* ci;
XRROutputInfo* oi;
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
result = calloc(oi->nmode, sizeof(GLFWvidmode));
for (i = 0; i < oi->nmode; i++)
for (int i = 0; i < oi->nmode; i++)
{
const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]);
if (!modeIsGood(mi))
continue;
const GLFWvidmode mode = vidmodeFromModeInfo(mi, ci);
int j;
for (j = 0; j < *count; j++)
{
@@ -502,11 +483,9 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
{
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
{
XRRScreenResources* sr;
XRRCrtcInfo* ci;
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
if (ci) {
const XRRModeInfo* mi = getModeInfo(sr, ci->mode);
@@ -528,7 +507,7 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
}
}
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{
if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken)
{
@@ -544,7 +523,7 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
memcpy(ramp->blue, gamma->blue, size * sizeof(unsigned short));
XRRFreeGamma(gamma);
return GLFW_TRUE;
return true;
}
else if (_glfw.x11.vidmode.available)
{
@@ -556,13 +535,13 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
XF86VidModeGetGammaRamp(_glfw.x11.display,
_glfw.x11.screen,
ramp->size, ramp->red, ramp->green, ramp->blue);
return GLFW_TRUE;
return true;
}
else
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Gamma ramp access not supported by server");
return GLFW_FALSE;
return false;
}
}
@@ -570,7 +549,7 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{
if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken)
{
if (XRRGetCrtcGammaSize(_glfw.x11.display, monitor->x11.crtc) != ramp->size)
if (XRRGetCrtcGammaSize(_glfw.x11.display, monitor->x11.crtc) != (int)ramp->size)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Gamma ramp size must match current ramp size");
@@ -595,7 +574,8 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
(unsigned short*) ramp->green,
(unsigned short*) ramp->blue);
}
else {
else
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Gamma ramp access not supported by server");
}

31
glfw/x11_platform.h vendored
View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 X11 - www.glfw.org
// GLFW 3.4 X11 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -182,11 +182,11 @@ typedef struct _GLFWwindowX11
Colormap colormap;
Window handle;
GLFWbool iconified;
GLFWbool maximized;
bool iconified;
bool maximized;
// Whether the visual supports framebuffer transparency
GLFWbool transparent;
bool transparent;
// Cached position and size used to filter out duplicate events
int width, height;
@@ -227,6 +227,8 @@ typedef struct _GLFWlibraryX11
_GLFWwindow* disabledCursorWindow;
// Window manager atoms
Atom NET_SUPPORTED;
Atom NET_SUPPORTING_WM_CHECK;
Atom WM_PROTOCOLS;
Atom WM_STATE;
Atom WM_DELETE_WINDOW;
@@ -284,14 +286,14 @@ typedef struct _GLFWlibraryX11
Atom RESOURCE_MANAGER;
struct {
GLFWbool available;
bool available;
void* handle;
int eventBase;
int errorBase;
int major;
int minor;
GLFWbool gammaBroken;
GLFWbool monitorBroken;
bool gammaBroken;
bool monitorBroken;
PFN_XRRAllocGamma AllocGamma;
PFN_XRRFreeCrtcInfo FreeCrtcInfo;
PFN_XRRFreeGamma FreeGamma;
@@ -336,7 +338,7 @@ typedef struct _GLFWlibraryX11
} xcursor;
struct {
GLFWbool available;
bool available;
void* handle;
int major;
int minor;
@@ -346,7 +348,7 @@ typedef struct _GLFWlibraryX11
} xinerama;
struct {
GLFWbool available;
bool available;
void* handle;
int eventBase;
int errorBase;
@@ -357,7 +359,7 @@ typedef struct _GLFWlibraryX11
} vidmode;
struct {
GLFWbool available;
bool available;
void* handle;
int majorOpcode;
int eventBase;
@@ -369,7 +371,7 @@ typedef struct _GLFWlibraryX11
} xi;
struct {
GLFWbool available;
bool available;
void* handle;
int major;
int minor;
@@ -406,6 +408,7 @@ typedef struct _GLFWcursorX11
} _GLFWcursorX11;
void _glfwPollMonitorsX11(void);
void _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired);
void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor);
@@ -416,11 +419,11 @@ unsigned long _glfwGetWindowPropertyX11(Window window,
Atom property,
Atom type,
unsigned char** value);
GLFWbool _glfwIsVisualTransparentX11(Visual* visual);
bool _glfwIsVisualTransparentX11(Visual* visual);
void _glfwGrabErrorHandlerX11(void);
void _glfwReleaseErrorHandlerX11(void);
void _glfwInputErrorX11(int error, const char* message);
void _glfwGetSystemContentScaleX11(float* xscale, float* yscale, GLFWbool bypass_cache);
void _glfwGetSystemContentScaleX11(float* xscale, float* yscale, bool bypass_cache);
void _glfwPushSelectionToManagerX11(void);

244
glfw/x11_window.c vendored
View File

@@ -1,8 +1,8 @@
//========================================================================
// GLFW 3.3 X11 - www.glfw.org
// GLFW 3.4 X11 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -24,6 +24,8 @@
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#define _GNU_SOURCE
#include "internal.h"
@@ -51,6 +53,7 @@
#define _GLFW_XDND_VERSION 5
// Wait for data to arrive using poll
// This avoids blocking other threads via the per-display Xlib lock that also
// covers GLX functions
@@ -70,25 +73,26 @@ handleEvents(double timeout) {
glfw_ibus_dispatch(&_glfw.x11.xkb.ibus);
glfw_dbus_session_bus_dispatch();
EVDBG("other dispatch done");
if (_glfw.x11.eventLoopData.wakeup_fd_ready) check_for_wakeup_events(&_glfw.x11.eventLoopData);
}
static GLFWbool
static bool
waitForX11Event(double timeout) {
// returns true iff there is X11 data waiting to be read, does not run watches and timers
// returns true if there is X11 data waiting to be read, does not run watches and timers
double end_time = glfwGetTime() + timeout;
while(GLFW_TRUE) {
while(true) {
if (timeout >= 0) {
const int result = pollWithTimeout(_glfw.x11.eventLoopData.fds, 1, timeout);
if (result > 0) return GLFW_TRUE;
if (result > 0) return true;
timeout = end_time - glfwGetTime();
if (timeout <= 0) return GLFW_FALSE;
if (timeout <= 0) return false;
if (result < 0 && (errno == EINTR || errno == EAGAIN)) continue;
return GLFW_FALSE;
return false;
} else {
const int result = poll(_glfw.x11.eventLoopData.fds, 1, -1);
if (result > 0) return GLFW_TRUE;
if (result > 0) return true;
if (result < 0 && (errno == EINTR || errno == EAGAIN)) continue;
return GLFW_FALSE;
return false;
}
}
}
@@ -96,7 +100,7 @@ waitForX11Event(double timeout) {
// Waits until a VisibilityNotify event arrives for the specified window or the
// timeout period elapses (ICCCM section 4.2.2)
//
static GLFWbool waitForVisibilityNotify(_GLFWwindow* window)
static bool waitForVisibilityNotify(_GLFWwindow* window)
{
XEvent dummy;
@@ -106,10 +110,10 @@ static GLFWbool waitForVisibilityNotify(_GLFWwindow* window)
&dummy))
{
if (!waitForX11Event(0.1))
return GLFW_FALSE;
return false;
}
return GLFW_TRUE;
return true;
}
// Returns whether the window is iconified
@@ -138,7 +142,7 @@ static int getWindowState(_GLFWwindow* window)
// Returns whether the event is a selection event
//
static Bool isSelectionEvent(Display* display, XEvent* event, XPointer pointer)
static Bool isSelectionEvent(Display* display UNUSED, XEvent* event, XPointer pointer UNUSED)
{
if (event->xany.window != _glfw.x11.helperWindowHandle)
return False;
@@ -150,7 +154,7 @@ static Bool isSelectionEvent(Display* display, XEvent* event, XPointer pointer)
// Returns whether it is a _NET_FRAME_EXTENTS event for the specified window
//
static Bool isFrameExtentsEvent(Display* display, XEvent* event, XPointer pointer)
static Bool isFrameExtentsEvent(Display* display UNUSED, XEvent* event, XPointer pointer)
{
_GLFWwindow* window = (_GLFWwindow*) pointer;
return event->type == PropertyNotify &&
@@ -161,7 +165,7 @@ static Bool isFrameExtentsEvent(Display* display, XEvent* event, XPointer pointe
// Returns whether it is a property event for the specified selection transfer
//
static Bool isSelPropNewValueNotify(Display* display, XEvent* event, XPointer pointer)
static Bool isSelPropNewValueNotify(Display* display UNUSED, XEvent* event, XPointer pointer)
{
XEvent* notification = (XEvent*) pointer;
return event->type == PropertyNotify &&
@@ -197,10 +201,7 @@ static int translateState(int state)
static void sendEventToWM(_GLFWwindow* window, Atom type,
long a, long b, long c, long d, long e)
{
XEvent event;
memset(&event, 0, sizeof(event));
event.type = ClientMessage;
XEvent event = { ClientMessage };
event.xclient.window = window->x11.handle;
event.xclient.format = 32; // Data is 32-bit longs
event.xclient.message_type = type;
@@ -270,7 +271,7 @@ is_window_fullscreen(_GLFWwindow* window)
{
Atom* states;
unsigned long i;
GLFWbool ans = GLFW_FALSE;
bool ans = false;
if (!_glfw.x11.NET_WM_STATE || !_glfw.x11.NET_WM_STATE_FULLSCREEN)
return ans;
const unsigned long count =
@@ -283,7 +284,7 @@ is_window_fullscreen(_GLFWwindow* window)
{
if (states[i] == _glfw.x11.NET_WM_STATE_FULLSCREEN)
{
ans = GLFW_TRUE;
ans = true;
break;
}
}
@@ -328,8 +329,7 @@ set_fullscreen(_GLFWwindow *window, bool on) {
}
bool
_glfwPlatformToggleFullscreen(_GLFWwindow *window, unsigned int flags) {
(void) flags;
_glfwPlatformToggleFullscreen(_GLFWwindow *window, unsigned int flags UNUSED) {
bool already_fullscreen = is_window_fullscreen(window);
set_fullscreen(window, !already_fullscreen);
return !already_fullscreen;
@@ -499,7 +499,7 @@ static void enableCursor(_GLFWwindow* window)
// Create the X11 window (and its colormap)
//
static GLFWbool createNativeWindow(_GLFWwindow* window,
static bool createNativeWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
Visual* visual, int depth)
{
@@ -551,7 +551,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
{
_glfwInputErrorX11(GLFW_PLATFORM_ERROR,
"X11: Failed to create window");
return GLFW_FALSE;
return false;
}
XSaveContext(_glfw.x11.display,
@@ -561,7 +561,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
}
if (!wndconfig->decorated)
_glfwPlatformSetWindowDecorated(window, GLFW_FALSE);
_glfwPlatformSetWindowDecorated(window, false);
if (_glfw.x11.NET_WM_STATE && !window->monitor)
{
@@ -581,7 +581,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
{
states[count++] = _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT;
states[count++] = _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ;
window->x11.maximized = GLFW_TRUE;
window->x11.maximized = true;
}
}
@@ -630,7 +630,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
{
_glfwInputError(GLFW_OUT_OF_MEMORY,
"X11: Failed to allocate WM hints");
return GLFW_FALSE;
return false;
}
hints->flags = StateHint;
@@ -684,7 +684,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
_glfwPlatformGetWindowPos(window, &window->x11.xpos, &window->x11.ypos);
_glfwPlatformGetWindowSize(window, &window->x11.width, &window->x11.height);
return GLFW_TRUE;
return true;
}
// Set the specified property to the selection converted to the requested target
@@ -841,11 +841,8 @@ static void handleSelectionRequest(XEvent* event)
{
const XSelectionRequestEvent* request = &event->xselectionrequest;
XEvent reply;
memset(&reply, 0, sizeof(reply));
XEvent reply = { SelectionNotify };
reply.xselection.property = writeTargetToProperty(request);
reply.xselection.type = SelectionNotify;
reply.xselection.display = request->display;
reply.xselection.requestor = request->requestor;
reply.xselection.selection = request->selection;
@@ -857,7 +854,6 @@ static void handleSelectionRequest(XEvent* event)
static const char* getSelectionString(Atom selection)
{
size_t i;
char** selectionString = NULL;
const Atom targets[] = { _glfw.x11.UTF8_STRING, XA_STRING };
const size_t targetCount = sizeof(targets) / sizeof(targets[0]);
@@ -878,7 +874,7 @@ static const char* getSelectionString(Atom selection)
free(*selectionString);
*selectionString = NULL;
for (i = 0; i < targetCount; i++)
for (size_t i = 0; i < targetCount; i++)
{
char* data;
Atom actualType;
@@ -1056,7 +1052,7 @@ static void releaseMonitor(_GLFWwindow* window)
static void onConfigChange(void)
{
float xscale, yscale;
_glfwGetSystemContentScaleX11(&xscale, &yscale, GLFW_TRUE);
_glfwGetSystemContentScaleX11(&xscale, &yscale, true);
if (xscale != _glfw.x11.contentScaleX || yscale != _glfw.x11.contentScaleY)
{
@@ -1075,9 +1071,8 @@ static void onConfigChange(void)
//
static void processEvent(XEvent *event)
{
_GLFWwindow* window = NULL;
static GLFWbool keymap_dirty = GLFW_FALSE;
#define UPDATE_KEYMAP_IF_NEEDED if (keymap_dirty) { keymap_dirty = GLFW_FALSE; glfw_xkb_compile_keymap(&_glfw.x11.xkb, NULL); }
static bool keymap_dirty = false;
#define UPDATE_KEYMAP_IF_NEEDED if (keymap_dirty) { keymap_dirty = false; glfw_xkb_compile_keymap(&_glfw.x11.xkb, NULL); }
if (_glfw.x11.randr.available)
{
@@ -1153,7 +1148,7 @@ static void processEvent(XEvent *event)
/* fallthrough */
case XkbMapNotify:
{
keymap_dirty = GLFW_TRUE;
keymap_dirty = true;
return;
}
case XkbStateNotify:
@@ -1170,6 +1165,7 @@ static void processEvent(XEvent *event)
return;
}
_GLFWwindow* window = NULL;
if (XFindContext(_glfw.x11.display,
event->xany.window,
_glfw.x11.context,
@@ -1310,7 +1306,7 @@ static void processEvent(XEvent *event)
if (window->cursorMode == GLFW_CURSOR_HIDDEN)
updateCursorImage(window);
_glfwInputCursorEnter(window, GLFW_TRUE);
_glfwInputCursorEnter(window, true);
_glfwInputCursorPos(window, x, y);
window->x11.lastCursorPosX = x;
@@ -1320,7 +1316,7 @@ static void processEvent(XEvent *event)
case LeaveNotify:
{
_glfwInputCursorEnter(window, GLFW_FALSE);
_glfwInputCursorEnter(window, false);
return;
}
@@ -1430,7 +1426,7 @@ static void processEvent(XEvent *event)
// A drag operation has entered the window
unsigned long i, count;
Atom* formats = NULL;
const GLFWbool list = event->xclient.data.l[1] & 1;
const bool list = event->xclient.data.l[1] & 1;
_glfw.x11.xdnd.source = event->xclient.data.l[0];
_glfw.x11.xdnd.version = event->xclient.data.l[1] >> 24;
@@ -1487,10 +1483,7 @@ static void processEvent(XEvent *event)
}
else if (_glfw.x11.xdnd.version >= 2)
{
XEvent reply;
memset(&reply, 0, sizeof(reply));
reply.type = ClientMessage;
XEvent reply = { ClientMessage };
reply.xclient.window = _glfw.x11.xdnd.source;
reply.xclient.message_type = _glfw.x11.XdndFinished;
reply.xclient.format = 32;
@@ -1523,10 +1516,7 @@ static void processEvent(XEvent *event)
_glfwInputCursorPos(window, xpos, ypos);
XEvent reply;
memset(&reply, 0, sizeof(reply));
reply.type = ClientMessage;
XEvent reply = { ClientMessage };
reply.xclient.window = _glfw.x11.xdnd.source;
reply.xclient.message_type = _glfw.x11.XdndStatus;
reply.xclient.format = 32;
@@ -1579,10 +1569,7 @@ static void processEvent(XEvent *event)
if (_glfw.x11.xdnd.version >= 2)
{
XEvent reply;
memset(&reply, 0, sizeof(reply));
reply.type = ClientMessage;
XEvent reply = { ClientMessage };
reply.xclient.window = _glfw.x11.xdnd.source;
reply.xclient.message_type = _glfw.x11.XdndFinished;
reply.xclient.format = 32;
@@ -1601,9 +1588,6 @@ static void processEvent(XEvent *event)
case FocusIn:
{
if (window->cursorMode == GLFW_CURSOR_DISABLED)
disableCursor(window);
if (event->xfocus.mode == NotifyGrab ||
event->xfocus.mode == NotifyUngrab)
{
@@ -1612,15 +1596,15 @@ static void processEvent(XEvent *event)
return;
}
_glfwInputWindowFocus(window, GLFW_TRUE);
if (window->cursorMode == GLFW_CURSOR_DISABLED)
disableCursor(window);
_glfwInputWindowFocus(window, true);
return;
}
case FocusOut:
{
if (window->cursorMode == GLFW_CURSOR_DISABLED)
enableCursor(window);
if (event->xfocus.mode == NotifyGrab ||
event->xfocus.mode == NotifyUngrab)
{
@@ -1629,10 +1613,13 @@ static void processEvent(XEvent *event)
return;
}
if (window->cursorMode == GLFW_CURSOR_DISABLED)
enableCursor(window);
if (window->monitor && window->autoIconify)
_glfwPlatformIconifyWindow(window);
_glfwInputWindowFocus(window, GLFW_FALSE);
_glfwInputWindowFocus(window, false);
return;
}
@@ -1653,7 +1640,7 @@ static void processEvent(XEvent *event)
if (state != IconicState && state != NormalState)
return;
const GLFWbool iconified = (state == IconicState);
const bool iconified = (state == IconicState);
if (window->x11.iconified != iconified)
{
if (window->monitor)
@@ -1670,7 +1657,7 @@ static void processEvent(XEvent *event)
}
else if (event->xproperty.atom == _glfw.x11.NET_WM_STATE)
{
const GLFWbool maximized = _glfwPlatformWindowMaximized(window);
const bool maximized = _glfwPlatformWindowMaximized(window);
if (window->x11.maximized != maximized)
{
window->x11.maximized = maximized;
@@ -1720,10 +1707,10 @@ unsigned long _glfwGetWindowPropertyX11(Window window,
return itemCount;
}
GLFWbool _glfwIsVisualTransparentX11(Visual* visual)
bool _glfwIsVisualTransparentX11(Visual* visual)
{
if (!_glfw.x11.xrender.available)
return GLFW_FALSE;
return false;
XRenderPictFormat* pf = XRenderFindVisualFormat(_glfw.x11.display, visual);
return pf && pf->direct.alphaMask;
@@ -1795,21 +1782,21 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
{
if (!_glfwInitGLX())
return GLFW_FALSE;
return false;
if (!_glfwChooseVisualGLX(wndconfig, ctxconfig, fbconfig, &visual, &depth))
return GLFW_FALSE;
return false;
}
else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
{
if (!_glfwInitEGL())
return GLFW_FALSE;
return false;
if (!_glfwChooseVisualEGL(wndconfig, ctxconfig, fbconfig, &visual, &depth))
return GLFW_FALSE;
return false;
}
else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
{
if (!_glfwInitOSMesa())
return GLFW_FALSE;
return false;
}
}
@@ -1821,24 +1808,24 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
}
if (!createNativeWindow(window, wndconfig, visual, depth))
return GLFW_FALSE;
return false;
if (ctxconfig->client != GLFW_NO_API)
{
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
{
if (!_glfwCreateContextGLX(window, ctxconfig, fbconfig))
return GLFW_FALSE;
return false;
}
else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
{
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
return GLFW_FALSE;
return false;
}
else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
{
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
return GLFW_FALSE;
return false;
}
}
@@ -1850,7 +1837,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
}
XFlush(_glfw.x11.display);
return GLFW_TRUE;
return true;
}
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
@@ -2025,8 +2012,8 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
}
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
int minwidth, int minheight,
int maxwidth, int maxheight)
int minwidth UNUSED, int minheight UNUSED,
int maxwidth UNUSED, int maxheight UNUSED)
{
int width, height;
_glfwPlatformGetWindowSize(window, &width, &height);
@@ -2034,7 +2021,7 @@ void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
XFlush(_glfw.x11.display);
}
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer UNUSED, int denom UNUSED)
{
int width, height;
_glfwPlatformGetWindowSize(window, &width, &height);
@@ -2107,7 +2094,7 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
XFree(extents);
}
void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
void _glfwPlatformGetWindowContentScale(_GLFWwindow* window UNUSED,
float* xscale, float* yscale)
{
if (xscale)
@@ -2116,7 +2103,7 @@ void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
*yscale = _glfw.x11.contentScaleY;
}
double _glfwPlatformGetDoubleClickInterval(_GLFWwindow* window)
double _glfwPlatformGetDoubleClickInterval(_GLFWwindow* window UNUSED)
{
return 0.5;
}
@@ -2194,7 +2181,7 @@ void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
int _glfwPlatformWindowBell(_GLFWwindow* window)
{
return XkbBell(_glfw.x11.display, window->x11.handle, 100, (Atom)0) ? GLFW_TRUE : GLFW_FALSE;
return XkbBell(_glfw.x11.display, window->x11.handle, 100, (Atom)0) ? true : false;
}
void _glfwPlatformFocusWindow(_GLFWwindow* window)
@@ -2215,7 +2202,7 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
_GLFWmonitor* monitor,
int xpos, int ypos,
int width, int height,
int refreshRate)
int refreshRate UNUSED)
{
if (window->monitor == monitor)
{
@@ -2245,13 +2232,14 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
if (window->monitor)
{
if (!_glfwPlatformWindowVisible(window))
{
XMapRaised(_glfw.x11.display, window->x11.handle);
waitForVisibilityNotify(window);
}
updateWindowMode(window);
acquireMonitor(window);
if (!_glfwPlatformWindowVisible(window))
{
XMapRaised(_glfw.x11.display, window->x11.handle);
waitForVisibilityNotify(window);
}
updateWindowMode(window);
acquireMonitor(window);
}
else
{
@@ -2272,9 +2260,9 @@ int _glfwPlatformWindowFocused(_GLFWwindow* window)
return window->x11.handle == focused;
}
int _glfwPlatformWindowOccluded(_GLFWwindow* window)
int _glfwPlatformWindowOccluded(_GLFWwindow* window UNUSED)
{
return GLFW_FALSE;
return false;
}
int _glfwPlatformWindowIconified(_GLFWwindow* window)
@@ -2293,11 +2281,14 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
{
Atom* states;
unsigned long i;
GLFWbool maximized = GLFW_FALSE;
bool maximized = false;
if (!_glfw.x11.NET_WM_STATE ||
!_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT ||
!_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
!_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT ||
!_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
{
return maximized;
}
const unsigned long count =
_glfwGetWindowPropertyX11(window->x11.handle,
_glfw.x11.NET_WM_STATE,
@@ -2309,7 +2300,7 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
if (states[i] == _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT ||
states[i] == _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
{
maximized = GLFW_TRUE;
maximized = true;
break;
}
}
@@ -2332,32 +2323,32 @@ int _glfwPlatformWindowHovered(_GLFWwindow* window)
if (!XQueryPointer(_glfw.x11.display, w,
&root, &w, &rootX, &rootY, &childX, &childY, &mask))
{
return GLFW_FALSE;
return false;
}
if (w == window->x11.handle)
return GLFW_TRUE;
return true;
}
return GLFW_FALSE;
return false;
}
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
{
if (!window->x11.transparent)
return GLFW_FALSE;
return false;
return XGetSelectionOwner(_glfw.x11.display, _glfw.x11.NET_WM_CM_Sx) != None;
}
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, bool enabled UNUSED)
{
int width, height;
_glfwPlatformGetWindowSize(window, &width, &height);
updateNormalHints(window, width, height);
}
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, bool enabled)
{
if (enabled)
{
@@ -2388,7 +2379,7 @@ void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
}
}
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, bool enabled)
{
if (!_glfw.x11.NET_WM_STATE || !_glfw.x11.NET_WM_STATE_ABOVE)
return;
@@ -2485,14 +2476,12 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
}
static inline unsigned
dispatch_x11_queued_events(void) {
unsigned dispatched = 0;
while (XQLength(_glfw.x11.display) > 0)
{
dispatch_x11_queued_events(int num_events) {
unsigned dispatched = num_events > 0 ? num_events : 0;
while (num_events-- > 0) {
XEvent event;
XNextEvent(_glfw.x11.display, &event);
processEvent(&event);
dispatched += 1;
}
return dispatched;
}
@@ -2503,10 +2492,9 @@ _glfwDispatchX11Events(void) {
unsigned dispatched = 0;
#if defined(__linux__)
_glfwDetectJoystickConnectionLinux();
if (_glfw.hints.init.enableJoysticks) _glfwDetectJoystickConnectionLinux();
#endif
XPending(_glfw.x11.display);
dispatched += dispatch_x11_queued_events();
dispatched += dispatch_x11_queued_events(XEventsQueued(_glfw.x11.display, QueuedAfterFlush));
window = _glfw.x11.disabledCursorWindow;
if (window)
@@ -2524,8 +2512,10 @@ _glfwDispatchX11Events(void) {
}
XFlush(_glfw.x11.display);
// XFlush can cause events to be queued
dispatched += dispatch_x11_queued_events();
// XFlush can cause events to be queued, we don't use QueuedAfterFlush here
// as something might have inserted events into the queue, but we want to guarantee
// a flush.
dispatched += dispatch_x11_queued_events(XEventsQueued(_glfw.x11.display, QueuedAlready));
return dispatched;
}
@@ -2549,7 +2539,7 @@ void _glfwPlatformWaitEventsTimeout(double timeout)
void _glfwPlatformPostEmptyEvent(void)
{
while (write(_glfw.x11.eventLoopData.wakeupFds[1], "w", 1) < 0 && errno == EINTR);
wakeupEventLoop(&_glfw.x11.eventLoopData);
}
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
@@ -2608,13 +2598,13 @@ int _glfwPlatformGetKeyScancode(int key)
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
const GLFWimage* image,
int xhot, int yhot, int count)
int xhot, int yhot, int count UNUSED)
{
cursor->x11.handle = _glfwCreateCursorX11(image, xhot, yhot);
if (!cursor->x11.handle)
return GLFW_FALSE;
return false;
return GLFW_TRUE;
return true;
}
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, GLFWCursorShape shape)
@@ -2633,7 +2623,7 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, GLFWCursorShape shape
C(GLFW_SW_RESIZE_CURSOR, XC_bottom_left_corner);
C(GLFW_SE_RESIZE_CURSOR, XC_bottom_right_corner);
case GLFW_INVALID_CURSOR:
return GLFW_FALSE;
return false;
}
#undef C
@@ -2642,10 +2632,10 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, GLFWCursorShape shape
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to create standard cursor");
return GLFW_FALSE;
return false;
}
return GLFW_TRUE;
return true;
}
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
@@ -2654,7 +2644,7 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
XFreeCursor(_glfw.x11.display, cursor->x11.handle);
}
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor UNUSED)
{
if (window->cursorMode == GLFW_CURSOR_NORMAL)
{
@@ -2747,7 +2737,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"X11: Vulkan instance missing VK_KHR_xcb_surface extension");
return GLFW_FALSE;
return false;
}
xcb_connection_t* connection = XGetXCBConnection(_glfw.x11.display);
@@ -2755,7 +2745,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to retrieve XCB connection");
return GLFW_FALSE;
return false;
}
return vkGetPhysicalDeviceXcbPresentationSupportKHR(device,
@@ -2773,7 +2763,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"X11: Vulkan instance missing VK_KHR_xlib_surface extension");
return GLFW_FALSE;
return false;
}
return vkGetPhysicalDeviceXlibPresentationSupportKHR(device,
@@ -2880,7 +2870,7 @@ GLFWAPI Window glfwGetX11Window(GLFWwindow* handle)
return window->x11.handle;
}
GLFWAPI int glfwGetXKBScancode(const char* keyName, GLFWbool caseSensitive) {
GLFWAPI int glfwGetXKBScancode(const char* keyName, bool caseSensitive) {
return glfw_xkb_keysym_from_name(keyName, caseSensitive);
}

59
glfw/xkb_glfw.c vendored
View File

@@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.3 XKB - www.glfw.org
// GLFW 3.4 XKB - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2018 Kovid Goyal <kovid@kovidgoyal.net>
//
@@ -29,6 +29,7 @@
#include <stdlib.h>
#include "internal.h"
#include "xkb_glfw.h"
START_ALLOW_CASE_RANGE
#define debug(...) if (_glfw.hints.init.debugKeyboard) printf(__VA_ARGS__);
@@ -47,6 +48,7 @@
S(backslash, BACKSLASH); \
S(bracketright, RIGHT_BRACKET); \
S(plus, PLUS); \
S(underscore, UNDERSCORE); \
S(grave, GRAVE_ACCENT); \
S(Escape, ESCAPE); \
S(Return, ENTER); \
@@ -100,7 +102,7 @@ glfw_key_for_sym(xkb_keysym_t key) {
#define S(f, t) case XKB_KEY_##f: return GLFW_KEY_##t
#define F(f, t) S(f, t)
#define R(s, e, gs, ...) case XKB_KEY_##s ... XKB_KEY_##e: return GLFW_KEY_##gs + key - XKB_KEY_##s
#define D(s, e, gs, ...) R(s, e, gs)
#define D(s, e, gs, ...) R(s, e, gs, __VA_ARGS__)
map_key(key)
S(KP_Up, UP);
S(KP_Down, DOWN);
@@ -114,7 +116,7 @@ glfw_key_for_sym(xkb_keysym_t key) {
#undef D
#undef R
#undef S
};
}
xkb_keysym_t
glfw_xkb_sym_for_key(int key) {
@@ -132,33 +134,34 @@ glfw_xkb_sym_for_key(int key) {
#undef R
#undef S
}
END_ALLOW_CASE_RANGE
#ifdef _GLFW_X11
GLFWbool
bool
glfw_xkb_set_x11_events_mask(void) {
if (!XkbSelectEvents(_glfw.x11.display, XkbUseCoreKbd, XkbNewKeyboardNotifyMask | XkbMapNotifyMask | XkbStateNotifyMask, XkbNewKeyboardNotifyMask | XkbMapNotifyMask | XkbStateNotifyMask)) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to set XKB events mask");
return GLFW_FALSE;
return false;
}
return GLFW_TRUE;
return true;
}
GLFWbool
bool
glfw_xkb_update_x11_keyboard_id(_GLFWXKBData *xkb) {
xkb->keyboard_device_id = -1;
xcb_connection_t* conn = XGetXCBConnection(_glfw.x11.display);
if (!conn) {
_glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to retrieve XCB connection");
return GLFW_FALSE;
return false;
}
xkb->keyboard_device_id = xkb_x11_get_core_keyboard_device_id(conn);
if (xkb->keyboard_device_id == -1) {
_glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to retrieve core keyboard device id");
return GLFW_FALSE;
return false;
}
return GLFW_TRUE;
return true;
}
#define xkb_glfw_load_keymap(keymap, ...) {\
@@ -166,7 +169,7 @@ glfw_xkb_update_x11_keyboard_id(_GLFWXKBData *xkb) {
if (conn) keymap = xkb_x11_keymap_new_from_device(xkb->context, conn, xkb->keyboard_device_id, XKB_KEYMAP_COMPILE_NO_FLAGS); \
}
#define xkb_glfw_load_state(keymap, state, ...) {\
#define xkb_glfw_load_state(keymap, state) {\
xcb_connection_t* conn = XGetXCBConnection(_glfw.x11.display); \
if (conn) state = xkb_x11_state_new_from_device(keymap, conn, xkb->keyboard_device_id); \
}
@@ -174,7 +177,7 @@ glfw_xkb_update_x11_keyboard_id(_GLFWXKBData *xkb) {
#else
#define xkb_glfw_load_keymap(keymap, map_str) keymap = xkb_keymap_new_from_string(xkb->context, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, 0);
#define xkb_glfw_load_state(keymap, state, ...) state = xkb_state_new(keymap);
#define xkb_glfw_load_state(keymap, state) state = xkb_state_new(keymap);
#endif
@@ -203,17 +206,17 @@ glfw_xkb_release(_GLFWXKBData *xkb) {
glfw_ibus_terminate(&xkb->ibus);
}
GLFWbool
bool
glfw_xkb_create_context(_GLFWXKBData *xkb) {
xkb->context = xkb_context_new(0);
if (!xkb->context)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Failed to initialize XKB context");
return GLFW_FALSE;
return false;
}
glfw_connect_to_ibus(&xkb->ibus);
return GLFW_TRUE;
return true;
}
static const char*
@@ -259,7 +262,7 @@ load_compose_tables(_GLFWXKBData *xkb) {
xkb_compose_table_unref(compose_table);
}
GLFWbool
bool
glfw_xkb_compile_keymap(_GLFWXKBData *xkb, const char *map_str) {
const char *err;
release_keyboard_data(xkb);
@@ -267,13 +270,13 @@ glfw_xkb_compile_keymap(_GLFWXKBData *xkb, const char *map_str) {
if (err) {
_glfwInputError(GLFW_PLATFORM_ERROR, "%s", err);
release_keyboard_data(xkb);
return GLFW_FALSE;
return false;
}
err = load_states(xkb);
if (err) {
_glfwInputError(GLFW_PLATFORM_ERROR, "%s", err);
release_keyboard_data(xkb);
return GLFW_FALSE;
return false;
}
load_compose_tables(xkb);
#define S(a, n) xkb->a##Idx = xkb_keymap_mod_get_index(xkb->keymap, n); xkb->a##Mask = 1 << xkb->a##Idx;
@@ -291,7 +294,7 @@ glfw_xkb_compile_keymap(_GLFWXKBData *xkb, const char *map_str) {
}
xkb->states.modifiers = 0;
xkb->states.activeUnknownModifiers = 0;
return GLFW_TRUE;
return true;
}
static inline xkb_mod_mask_t
@@ -325,7 +328,7 @@ glfw_xkb_update_modifiers(_GLFWXKBData *xkb, xkb_mod_mask_t depressed, xkb_mod_m
update_modifiers(xkb, &xkb->states);
}
GLFWbool
bool
glfw_xkb_should_repeat(_GLFWXKBData *xkb, xkb_keycode_t scancode) {
#ifdef _GLFW_WAYLAND
scancode += 8;
@@ -334,7 +337,7 @@ glfw_xkb_should_repeat(_GLFWXKBData *xkb, xkb_keycode_t scancode) {
}
static KeyEvent key_event = {};
static KeyEvent key_event = {0};
static inline xkb_keysym_t
compose_symbol(struct xkb_compose_state *composeState, xkb_keysym_t sym, int *compose_completed) {
@@ -365,7 +368,7 @@ glfw_xkb_keysym_name(xkb_keysym_t sym) {
}
int
glfw_xkb_keysym_from_name(const char *name, GLFWbool case_sensitive) {
glfw_xkb_keysym_from_name(const char *name, bool case_sensitive) {
return (int)xkb_keysym_from_name(name, case_sensitive ? XKB_KEYSYM_NO_FLAGS : XKB_KEYSYM_CASE_INSENSITIVE);
}
@@ -412,7 +415,7 @@ glfw_xkb_update_ime_state(_GLFWwindow *w, _GLFWXKBData *xkb, int which, int a, i
int x = 0, y = 0;
switch(which) {
case 1:
glfw_ibus_set_focused(&xkb->ibus, a ? GLFW_TRUE : GLFW_FALSE);
glfw_ibus_set_focused(&xkb->ibus, a ? true : false);
break;
case 2:
_glfwPlatformGetWindowPos(w, &x, &y);
@@ -423,7 +426,7 @@ glfw_xkb_update_ime_state(_GLFWwindow *w, _GLFWXKBData *xkb, int which, int a, i
}
void
glfw_xkb_key_from_ime(KeyEvent *ev, GLFWbool handled_by_ime, GLFWbool failed) {
glfw_xkb_key_from_ime(KeyEvent *ev, bool handled_by_ime, bool failed) {
_GLFWwindow *window = _glfwWindowForId(ev->window_id);
if (failed && window && window->callbacks.keyboard) {
// notify application to remove any existing pre-edit text
@@ -431,12 +434,12 @@ glfw_xkb_key_from_ime(KeyEvent *ev, GLFWbool handled_by_ime, GLFWbool failed) {
}
static xkb_keycode_t last_handled_press_keycode = 0;
// We filter out release events that correspond to the last press event
// handled by the IME system. This wont fix the case of multiple key
// handled by the IME system. This won't fix the case of multiple key
// presses before a release, but is better than nothing. For that case
// you'd need to implement a ring buffer to store pending key presses.
xkb_keycode_t prev_handled_press = last_handled_press_keycode;
last_handled_press_keycode = 0;
GLFWbool is_release = ev->action == GLFW_RELEASE;
bool is_release = ev->action == GLFW_RELEASE;
debug("From IBUS: scancode: 0x%x name: %s is_release: %d\n", ev->keycode, glfw_xkb_keysym_name(ev->keysym), is_release);
if (window && !handled_by_ime && !(is_release && ev->keycode == prev_handled_press)) {
debug("↳ to application: glfw_keycode: 0x%x (%s) keysym: 0x%x (%s) action: %s %s text: %s\n",
@@ -499,13 +502,13 @@ glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t
if (key_event.text[0]) { debug("%s: %s ", text_type, key_event.text); }
}
int glfw_keycode = glfw_key_for_sym(glfw_sym);
GLFWbool is_fallback = GLFW_FALSE;
bool is_fallback = false;
if (glfw_keycode == GLFW_KEY_UNKNOWN && !key_event.text[0]) {
int num_default_syms = xkb_state_key_get_syms(sg->default_state, code_for_sym, &default_syms);
if (num_default_syms > 0) {
glfw_sym = default_syms[0];
glfw_keycode = glfw_key_for_sym(glfw_sym);
is_fallback = GLFW_TRUE;
is_fallback = true;
}
}
debug(

20
glfw/xkb_glfw.h vendored
View File

@@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.3 XKB - www.glfw.org
// GLFW 3.4 XKB - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2018 Kovid Goyal <kovid@kovidgoyal.net>
//
@@ -67,8 +67,8 @@ typedef struct {
#ifdef _GLFW_X11
int32_t keyboard_device_id;
GLFWbool available;
GLFWbool detectable;
bool available;
bool detectable;
int majorOpcode;
int eventBase;
int errorBase;
@@ -79,18 +79,18 @@ typedef struct {
} _GLFWXKBData;
#ifdef _GLFW_X11
GLFWbool glfw_xkb_set_x11_events_mask(void);
GLFWbool glfw_xkb_update_x11_keyboard_id(_GLFWXKBData *xkb);
bool glfw_xkb_set_x11_events_mask(void);
bool glfw_xkb_update_x11_keyboard_id(_GLFWXKBData *xkb);
#endif
void glfw_xkb_release(_GLFWXKBData *xkb);
GLFWbool glfw_xkb_create_context(_GLFWXKBData *xkb);
GLFWbool glfw_xkb_compile_keymap(_GLFWXKBData *xkb, const char *map_str);
bool glfw_xkb_create_context(_GLFWXKBData *xkb);
bool glfw_xkb_compile_keymap(_GLFWXKBData *xkb, const char *map_str);
void glfw_xkb_update_modifiers(_GLFWXKBData *xkb, xkb_mod_mask_t depressed, xkb_mod_mask_t latched, xkb_mod_mask_t locked, xkb_layout_index_t base_group, xkb_layout_index_t latched_group, xkb_layout_index_t locked_group);
GLFWbool glfw_xkb_should_repeat(_GLFWXKBData *xkb, xkb_keycode_t scancode);
bool glfw_xkb_should_repeat(_GLFWXKBData *xkb, xkb_keycode_t scancode);
const char* glfw_xkb_keysym_name(xkb_keysym_t sym);
xkb_keysym_t glfw_xkb_sym_for_key(int key);
void glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t scancode, int action);
int glfw_xkb_keysym_from_name(const char *name, GLFWbool case_sensitive);
int glfw_xkb_keysym_from_name(const char *name, bool case_sensitive);
void glfw_xkb_update_ime_state(_GLFWwindow *w, _GLFWXKBData *xkb, int which, int a, int b, int c, int d);
void glfw_xkb_key_from_ime(KeyEvent *ev, GLFWbool handled_by_ime, GLFWbool failed);
void glfw_xkb_key_from_ime(KeyEvent *ev, bool handled_by_ime, bool failed);

View File

@@ -3,6 +3,7 @@
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
import os
from contextlib import suppress
from kitty.cli import parse_args
from kitty.constants import cache_dir
@@ -27,10 +28,8 @@ class HistoryCompleter:
self.history_path = None
if name:
ddir = os.path.join(cache_dir(), 'ask')
try:
with suppress(FileExistsError):
os.makedirs(ddir)
except FileExistsError:
pass
self.history_path = os.path.join(ddir, name)
def complete(self, text, state):
@@ -50,10 +49,8 @@ class HistoryCompleter:
def __enter__(self):
if self.history_path:
try:
with suppress(Exception):
readline.read_history_file(self.history_path)
except Exception:
pass
readline.set_completer(self.complete)
return self
@@ -106,10 +103,8 @@ def main(args):
print(styled(args.message, bold=True))
prompt = '> '
try:
with suppress(KeyboardInterrupt, EOFError):
ans['response'] = input(prompt)
except (KeyboardInterrupt, EOFError):
pass
return ans

View File

@@ -25,9 +25,9 @@ static inline ssize_t ms_write(int fd, const void* buf, size_t count) { return _
static inline bool
ensure_space(GlobalData *global, size_t sz) {
if (global->output_sz < sz + global->output_pos) {
if (global->output_sz < sz + global->output_pos || !global->output) {
size_t before = global->output_sz;
global->output_sz += MAX(sz, (64 * 1024));
global->output_sz += MAX(sz, (64u * 1024u));
global->output = realloc(global->output, sizeof(text_t) * global->output_sz);
if (!global->output) {
global->output_sz = before;

View File

@@ -22,6 +22,12 @@ class Clipboard(Handler):
if self.data_to_send is not None:
self.cmd.write_to_clipboard(self.data_to_send, self.args.use_primary)
if not self.args.get_clipboard:
if self.args.wait_for_completion:
# ask kitty for the TN terminfo capability and
# only quit after a response is received
self.print('\x1bP+q544e\x1b\\', end='')
self.print('Waiting for completion...')
return
self.quit_loop(0)
return
self.cmd.request_from_clipboard(self.args.use_primary)
@@ -30,6 +36,15 @@ class Clipboard(Handler):
self.clipboard_contents = text
self.quit_loop(0)
def on_capability_response(self, name, val):
self.quit_loop(0)
def on_interrupt(self):
self.quit_loop(1)
def on_eot(self):
self.quit_loop(1)
OPTIONS = r'''
--get-clipboard
@@ -45,6 +60,13 @@ default=False
type=bool-set
Use the primary selection rather than the clipboard on systems that support it,
such as X11.
--wait-for-completion
default=False
type=bool-set
Wait till the copy to clipboard is complete before exiting. Useful if running
the kitten in a dedicated, ephemeral window.
'''.format
help_text = '''\
Read or write to the system clipboard.
@@ -54,6 +76,7 @@ To set the clipboard text, pipe in the new text on stdin. Use the
:file:`stdout`. Note that you must enable reading of clipboard in
:file:`kitty.conf` first.
'''
usage = ''

View File

@@ -7,6 +7,7 @@ import re
from functools import lru_cache
from hashlib import md5
from mimetypes import guess_type
from contextlib import suppress
path_name_map = {}
@@ -140,10 +141,8 @@ def is_image(path):
def data_for_path(path):
ans = raw_data_for_path(path)
if not is_image(path) and not os.path.samefile(path, os.devnull):
try:
with suppress(UnicodeDecodeError):
ans = ans.decode('utf-8')
except UnicodeDecodeError:
pass
return ans

View File

@@ -9,6 +9,7 @@ import warnings
from collections import defaultdict
from functools import partial
from gettext import gettext as _
from contextlib import suppress
from kitty.cli import CONFIG_HELP, parse_args
from kitty.constants import appname
@@ -511,10 +512,8 @@ usage = 'file_or_directory_left file_or_directory_right'
def terminate_processes(processes):
for pid in processes:
try:
with suppress(Exception):
os.kill(pid, signal.SIGKILL)
except Exception:
pass
def main(args):

View File

@@ -20,7 +20,7 @@ from ..tui.loop import Loop
from ..tui.operations import faint, styled
URL_PREFIXES = 'http https file ftp'.split()
HINT_ALPHABET = string.digits + string.ascii_lowercase
DEFAULT_HINT_ALPHABET = string.digits + string.ascii_lowercase
screen_size = screen_size_function()
@@ -34,21 +34,26 @@ class Mark:
@lru_cache(maxsize=2048)
def encode_hint(num):
def encode_hint(num, alphabet):
res = ''
d = len(HINT_ALPHABET)
d = len(alphabet)
while not res or num > 0:
num, i = divmod(num, d)
res = HINT_ALPHABET[i] + res
res = alphabet[i] + res
return res
def decode_hint(x):
return int(x, 36)
def decode_hint(x, alphabet=DEFAULT_HINT_ALPHABET):
base = len(alphabet)
index_map = {c: i for i, c in enumerate(alphabet)}
i = 0
for char in x:
i = i * base + index_map[char]
return i
def highlight_mark(m, text, current_input):
hint = encode_hint(m.index)
def highlight_mark(m, text, current_input, alphabet):
hint = encode_hint(m.index, alphabet)
if current_input and not hint.startswith(current_input):
return faint(text)
hint = hint[len(current_input):] or ' '
@@ -63,11 +68,11 @@ def highlight_mark(m, text, current_input):
)
def render(text, current_input, all_marks, ignore_mark_indices):
def render(text, current_input, all_marks, ignore_mark_indices, alphabet):
for mark in reversed(all_marks):
if mark.index in ignore_mark_indices:
continue
mtext = highlight_mark(mark, text[mark.start:mark.end], current_input)
mtext = highlight_mark(mark, text[mark.start:mark.end], current_input, alphabet)
text = text[:mark.start] + mtext + text[mark.end:]
text = text.replace('\0', '')
@@ -79,6 +84,7 @@ class Hints(Handler):
def __init__(self, text, all_marks, index_map, args):
self.text, self.index_map = text, index_map
self.alphabet = args.alphabet or DEFAULT_HINT_ALPHABET
self.all_marks = all_marks
self.ignore_mark_indices = set()
self.args = args
@@ -111,13 +117,13 @@ class Hints(Handler):
def on_text(self, text, in_bracketed_paste):
changed = False
for c in text:
if c in HINT_ALPHABET:
if c in self.alphabet:
self.current_input += c
changed = True
if changed:
matches = [
m for idx, m in self.index_map.items()
if encode_hint(idx).startswith(self.current_input)
if encode_hint(idx, self.alphabet).startswith(self.current_input)
]
if len(matches) == 1:
self.chosen.append(matches[0].text + self.match_suffix)
@@ -137,7 +143,7 @@ class Hints(Handler):
self.draw_screen()
elif key_event is enter_key and self.current_input:
try:
idx = decode_hint(self.current_input)
idx = decode_hint(self.current_input, self.alphabet)
self.chosen.append(self.index_map[idx].text + self.match_suffix)
self.ignore_mark_indices.add(idx)
except Exception:
@@ -164,7 +170,7 @@ class Hints(Handler):
def draw_screen(self):
if self.current_text is None:
self.current_text = render(self.text, self.current_input, self.all_marks, self.ignore_mark_indices)
self.current_text = render(self.text, self.current_input, self.all_marks, self.ignore_mark_indices, self.alphabet)
self.cmd.clear_screen()
self.write(self.current_text)
@@ -213,7 +219,7 @@ def url(text, s, e):
@postprocessor
def brackets(text, s, e):
# Remove matching brackets
if e > s and e <= len(text):
if s < e <= len(text):
before = text[s]
if before in '({[<' and text[e-1] == closing_bracket_map[before]:
s += 1
@@ -224,7 +230,7 @@ def brackets(text, s, e):
@postprocessor
def quotes(text, s, e):
# Remove matching quotes
if e > s and e <= len(text):
if s < e <= len(text):
before = text[s]
if before in '\'"' and text[e-1] == before:
s += 1
@@ -246,7 +252,9 @@ def run_loop(args, text, all_marks, index_map):
handler = Hints(text, all_marks, index_map, args)
loop.loop(handler)
if handler.chosen and loop.return_code == 0:
return {'match': handler.chosen, 'program': args.program}
return {'match': handler.chosen, 'programs': args.program,
'multiple_joiner': args.multiple_joiner,
'type': args.type}
raise SystemExit(loop.return_code)
@@ -331,10 +339,12 @@ def run(args, text):
# CLI {{{
OPTIONS = r'''
--program
default=default
type=list
What program to use to open matched text. Defaults to the default open program
for the operating system. Use a value of :file:`-` to paste the match into the
for the operating system. Use a value of :file:`-` to paste the match into the
terminal window instead. A value of :file:`@` will copy the match to the clipboard.
A value of :file:`default` will run the default open program. Can be specified
multiple times to run multiple programs.
--type
@@ -346,9 +356,11 @@ The type of text to search for.
--regex
default=(?m)^\s*(.+)\s*$
The regular expression to use when :option:`kitty +kitten hints --type`=regex.
If you specify a group in the regular expression only the group
will be matched. This allow you to match text ignoring a prefix/suffix, as
needed. The default expression matches lines.
The regular expression is in python syntax. If you specify a group in
the regular expression only the group will be matched. This allow you to match
text ignoring a prefix/suffix, as needed. The default expression matches lines.
To match text over multiple lines you should prefix the regular expression with
:code:`(?ms)`, which turns on MULTILINE and DOTALL modes for the regex engine.
--url-prefixes
@@ -358,7 +370,7 @@ Comma separated list of recognized URL prefixes.
--word-characters
Characters to consider as part of a word. In addition, all characters marked as
alpha-numeric in the unicode database will be considered as word characters.
alphanumeric in the unicode database will be considered as word characters.
Defaults to the select_by_word_characters setting from kitty.conf.
@@ -374,6 +386,17 @@ Select multiple matches and perform the action on all of them together at the en
In this mode, press :kbd:`Esc` to finish selecting.
--multiple-joiner
default=auto
String to use to join multiple selections when copying to the clipboard or
inserting into the terminal. The special strings: "space", "newline", "empty",
"json" and "auto" are interpreted as a space character, a newline an empty
joiner, a JSON serialized list and an automatic choice, based on the type of
text being selected. In addition, integers are interpreted as zero-based
indices into the list of selections. You can use 0 for the first selection and
-1 for the last.
--add-trailing-space
default=auto
choices=auto,always,never
@@ -386,6 +409,15 @@ default=1
type=int
The offset (from zero) at which to start hint numbering. Note that only numbers
greater than or equal to zero are respected.
--alphabet
The list of characters to use for hints. The default is to use numbers and lowercase
English alphabets. Specify your preference as a string of characters. Note that
unless you specify the hints offset as zero the first match will be highlighted with
the second character you specify.
'''.format(','.join(sorted(URL_PREFIXES))).format
help_text = 'Select text from the screen using the keyboard. Defaults to searching for URLs.'
usage = ''
@@ -415,28 +447,50 @@ def main(args):
if items:
print('Extra command line arguments present: {}'.format(' '.join(items)), file=sys.stderr)
input(_('Press Enter to quit'))
return
return run(args, text)
def handle_result(args, data, target_window_id, boss):
program = data['program']
programs = data['programs'] or ('default',)
matches = tuple(filter(None, data['match']))
if program == '-':
w = boss.window_id_map.get(target_window_id)
if w is not None:
joiner = data['multiple_joiner']
try:
is_int = int(joiner)
except Exception:
is_int = None
text_type = data['type']
@lru_cache()
def joined_text():
if is_int is not None:
try:
return matches[is_int]
except IndexError:
return matches[-1]
if joiner == 'json':
import json
return json.dumps(matches, ensure_ascii=False, indent='\t')
if joiner == 'auto':
q = '\n\r' if text_type in ('line', 'url') else ' '
else:
q = {'newline': '\n\r', 'space': ' '}.get(joiner, '')
return q.join(matches)
for program in programs:
if program == '-':
w = boss.window_id_map.get(target_window_id)
if w is not None:
w.paste(joined_text())
elif program == '@':
set_clipboard_string(joined_text())
else:
cwd = None
w = boss.window_id_map.get(target_window_id)
if w is not None:
cwd = w.cwd_of_child
program = None if program == 'default' else program
for m in matches:
w.paste(m)
elif program == '@':
set_clipboard_string(matches[-1])
else:
cwd = None
w = boss.window_id_map.get(target_window_id)
if w is not None:
cwd = w.cwd_of_child
program = None if program == 'default' else program
for m in matches:
boss.open_url(m, program, cwd=cwd)
boss.open_url(m, program, cwd=cwd)
handle_result.type_of_input = 'screen'

View File

@@ -194,11 +194,13 @@ def process(path, args, is_tempfile):
available_height = args.place.height * (ss.height / ss.rows) if args.place else 10 * m.height
needs_scaling = m.width > available_width or m.height > available_height
needs_scaling = needs_scaling or args.scale_up
file_removed = False
if m.fmt == 'png' and not needs_scaling:
outfile = path
transmit_mode = 't' if is_tempfile else 'f'
fmt = 100
width, height = m.width, m.height
file_removed = transmit_mode == 't'
else:
fmt = 24 if m.mode == 'rgb' else 32
transmit_mode = 't'
@@ -206,6 +208,7 @@ def process(path, args, is_tempfile):
show(outfile, width, height, fmt, transmit_mode, align=args.align, place=args.place)
if not args.place:
print() # ensure cursor is on a new line
return file_removed
def scan(d):
@@ -270,15 +273,16 @@ help_text = (
usage = 'image-file-or-url-or-directory ...'
def process_single_item(item, args, url_pat, maybe_dir=True):
def process_single_item(item, args, url_pat=None, maybe_dir=True):
is_tempfile = False
file_removed = False
try:
if isinstance(item, bytes):
tf = NamedTemporaryFile(prefix='stdin-image-data-', delete=False)
tf.write(item), tf.close()
item = tf.name
is_tempfile = True
if url_pat.match(item) is not None:
if url_pat is not None and url_pat.match(item) is not None:
from urllib.request import urlretrieve
with NamedTemporaryFile(prefix='url-image-data-', delete=False) as tf:
try:
@@ -287,7 +291,7 @@ def process_single_item(item, args, url_pat, maybe_dir=True):
raise SystemExit('Failed to download image at URL: {} with error: {}'.format(item, e))
item = tf.name
is_tempfile = True
process(item, args, is_tempfile)
file_removed = process(item, args, is_tempfile)
elif item.lower().startswith('file://'):
from urllib.parse import urlparse
from urllib.request import url2pathname
@@ -297,15 +301,15 @@ def process_single_item(item, args, url_pat, maybe_dir=True):
else:
item = item.path
item = url2pathname(item)
process(item, args, is_tempfile)
file_removed = process(item, args, is_tempfile)
else:
if maybe_dir and os.path.isdir(item):
for x in scan(item):
process_single_item(item, args, url_pat, maybe_dir=False)
for (x, mt) in scan(item):
process_single_item(x, args, url_pat=None, maybe_dir=False)
else:
process(item, args, is_tempfile)
file_removed = process(item, args, is_tempfile)
finally:
if is_tempfile:
if is_tempfile and not file_removed:
os.remove(item)

View File

@@ -2,12 +2,13 @@
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
import os
import shutil
import subprocess
import sys
from kitty.cli import parse_args
from kitty.constants import is_macos, is_wayland
from kitty.constants import is_macos
OPTIONS = r'''
--lines
@@ -121,7 +122,7 @@ def initial_window_size_func(opts, *a):
def main(sys_args):
global args
if is_macos or is_wayland:
if is_macos or not os.environ.get('DISPLAY'):
raise SystemExit('Currently the panel kitten is supported only on X11 desktops')
if not shutil.which('xprop'):
raise SystemExit('The xprop program is required for the panel kitten')

View File

@@ -6,6 +6,7 @@
import importlib
import os
import sys
from contextlib import suppress
from functools import partial
aliases = {'url_hints': 'hints'}
@@ -15,13 +16,18 @@ def resolved_kitten(k):
return aliases.get(k, k).replace('-', '_')
def path_to_custom_kitten(config_dir, kitten):
path = os.path.expanduser(kitten)
if not os.path.isabs(path):
path = os.path.join(config_dir, path)
path = os.path.abspath(path)
return path
def import_kitten_main_module(config_dir, kitten):
if kitten.endswith('.py'):
path_modified = False
path = os.path.expanduser(kitten)
if not os.path.isabs(path):
path = os.path.join(config_dir, path)
path = os.path.abspath(path)
path = path_to_custom_kitten(config_dir, kitten)
if os.path.dirname(path):
sys.path.insert(0, os.path.dirname(path))
path_modified = True
@@ -90,12 +96,24 @@ def deserialize(output):
def run_kitten(kitten, run_name='__main__'):
import runpy
original_kitten_name = kitten
kitten = resolved_kitten(kitten)
set_debug(kitten)
try:
with suppress(ImportError):
runpy.run_module('kittens.{}.main'.format(kitten), run_name=run_name)
except ImportError:
raise SystemExit('No kitten named {}'.format(kitten))
return
# Look for a custom kitten
if not kitten.endswith('.py'):
kitten += '.py'
from kitty.constants import config_dir
path = path_to_custom_kitten(config_dir, kitten)
if not os.path.exists(path):
print('Available builtin kittens:', file=sys.stderr)
for kitten in all_kitten_names():
print(kitten, file=sys.stderr)
raise SystemExit('No kitten named {}'.format(original_kitten_name))
m = runpy.run_path(path, init_globals={'sys': sys, 'os': os}, run_name='__run_kitten__')
m['main'](sys.argv)
def all_kitten_names():

View File

@@ -4,6 +4,7 @@
import os
import re
import shlex
import subprocess
import sys
@@ -93,6 +94,18 @@ def parse_ssh_args(args):
return ssh_args, server_args, passthrough
def quote(x):
# we have to escape unbalanced quotes and other unparsable
# args as they will break the shell script
# But we do not want to quote things like * or 'echo hello'
# See https://github.com/kovidgoyal/kitty/issues/1787
try:
shlex.split(x)
except ValueError:
x = shlex.quote(x)
return x
def main(args):
ssh_args, server_args, passthrough = parse_ssh_args(args[1:])
if passthrough:
@@ -101,7 +114,7 @@ def main(args):
terminfo = subprocess.check_output(['infocmp']).decode('utf-8')
sh_script = SHELL_SCRIPT.replace('TERMINFO', terminfo, 1)
if len(server_args) > 1:
command_to_execute = ["'{}'".format(c.replace("'", """'"'"'""")) for c in server_args[1:]]
command_to_execute = [quote(c) for c in server_args[1:]]
command_to_execute = 'exec ' + ' '.join(command_to_execute)
else:
command_to_execute = ''

View File

@@ -84,6 +84,9 @@ class Handler:
def on_clipboard_response(self, text, from_primary=False):
pass
def on_capability_response(self, name, val):
pass
def write(self, data):
if isinstance(data, str):
data = data.encode('utf-8')

View File

@@ -8,6 +8,7 @@ import sys
from base64 import standard_b64encode
from collections import defaultdict, deque
from itertools import count
from contextlib import suppress
from kitty.utils import fit_image
@@ -172,10 +173,8 @@ class ImageManager:
if in_flight:
pl = in_flight.popleft()
if payload.startswith('ENOENT:'):
try:
with suppress(Exception):
self.resend_image(image_id, pl)
except Exception:
pass
if not in_flight:
self.placements_in_flight.pop(image_id, None)
@@ -250,7 +249,8 @@ class ImageManager:
cmd, standard_b64encode(rgba_path.encode(fsenc)))
else:
import zlib
data = open(rgba_path, 'rb').read()
with open(rgba_path, 'rb') as f:
data = f.read()
cmd['S'] = len(data)
data = zlib.compress(data)
cmd['o'] = 'z'

View File

@@ -214,9 +214,20 @@ class Loop:
self.handler.on_text(chunk, self.in_bracketed_paste)
def _on_dcs(self, dcs):
debug(dcs)
if dcs.startswith('@kitty-cmd'):
import json
self.handler.on_kitty_cmd_response(json.loads(dcs[len('@kitty-cmd'):]))
elif dcs.startswith('1+r'):
from binascii import unhexlify
vals = dcs[3:].split(';')
for q in vals:
parts = q.split('=', 1)
try:
name, val = parts[0], unhexlify(parts[1]).decode('utf-8', 'replace')
except Exception:
continue
self.handler.on_capability_response(name, val)
def _on_csi(self, csi):
q = csi[-1]

View File

@@ -7,6 +7,7 @@ import string
import subprocess
from functools import lru_cache
from gettext import gettext as _
from contextlib import suppress
from kitty.config import cached_values_for
from kitty.constants import config_dir
@@ -239,11 +240,10 @@ class Table:
def is_index(w):
try:
with suppress(Exception):
int(w.lstrip(INDEX_CHAR), 16)
return True
except Exception:
return False
return False
class UnicodeInput(Handler):
@@ -293,24 +293,21 @@ class UnicodeInput(Handler):
self.update_codepoints()
self.current_char = None
if self.mode is HEX:
try:
if self.line_edit.current_input.startswith(INDEX_CHAR) and len(self.line_edit.current_input) > 1:
self.current_char = chr(self.table.codepoint_at_hint(self.line_edit.current_input[1:]))
else:
with suppress(Exception):
if self.line_edit.current_input.startswith(INDEX_CHAR):
if len(self.line_edit.current_input) > 1:
self.current_char = chr(self.table.codepoint_at_hint(self.line_edit.current_input[1:]))
elif self.line_edit.current_input:
code = int(self.line_edit.current_input, 16)
self.current_char = chr(code)
except Exception:
pass
elif self.mode is NAME:
cc = self.table.current_codepoint
if cc:
self.current_char = chr(cc)
else:
try:
with suppress(Exception):
if self.line_edit.current_input:
self.current_char = chr(self.table.codepoint_at_hint(self.line_edit.current_input.lstrip(INDEX_CHAR)))
except Exception:
pass
if self.current_char is not None:
code = ord(self.current_char)
if not codepoint_ok(code):
@@ -395,19 +392,20 @@ class UnicodeInput(Handler):
try:
val = int(self.line_edit.current_input, 16)
except Exception:
return
if key_event.key is TAB:
self.line_edit.current_input = hex(val + 0x10)[2:]
self.refresh()
return
if key_event.key is UP:
self.line_edit.current_input = hex(val + 1)[2:]
self.refresh()
return
if key_event.key is DOWN:
self.line_edit.current_input = hex(val - 1)[2:]
self.refresh()
return
pass
else:
if key_event.key is TAB:
self.line_edit.current_input = hex(val + 0x10)[2:]
self.refresh()
return
if key_event.key is UP:
self.line_edit.current_input = hex(val + 1)[2:]
self.refresh()
return
if key_event.key is DOWN:
self.line_edit.current_input = hex(val - 1)[2:]
self.refresh()
return
if self.mode is NAME and key_event.type is not RELEASE and not key_event.mods:
if key_event.key is TAB:
if key_event.mods == SHIFT:
@@ -483,10 +481,8 @@ def main(args):
handler = UnicodeInput(cached_values)
loop.loop(handler)
if handler.current_char and loop.return_code == 0:
try:
with suppress(Exception):
handler.recent.remove(ord(handler.current_char))
except Exception:
pass
recent = [ord(handler.current_char)] + handler.recent
cached_values['recent'] = recent[:len(DEFAULT_SET)]
return handler.current_char

File diff suppressed because one or more lines are too long

View File

@@ -7,5 +7,5 @@ out vec4 color;
void main() {
color = texture(image, texcoord);
color = vec4(color.rgb / color.a, color.a);
color = vec4(color.rgb, color.a);
}

View File

@@ -11,7 +11,7 @@ from .utils import load_shaders
try:
from enum import IntFlag
except Exception:
except ImportError:
from enum import IntEnum as IntFlag
@@ -68,7 +68,7 @@ class Borders:
bw, pw = self.border_width, self.padding_width
if bw + pw <= 0:
return
draw_borders = bw > 0 and draw_window_borders and len(windows) > 1
draw_borders = bw > 0 and draw_window_borders
if draw_borders:
border_data = current_layout.resolve_borders(windows, active_window)

View File

@@ -6,11 +6,12 @@ import atexit
import json
import os
import re
from contextlib import suppress
from functools import partial
from gettext import gettext as _
from weakref import WeakValueDictionary
from .child import cached_process_data
from .child import cached_process_data, cwd_of_process
from .cli import create_opts, parse_args
from .conf.utils import to_cmdline
from .config import initial_window_size_func, prepare_config_file_for_editing
@@ -24,10 +25,11 @@ from .fast_data_types import (
change_os_window_state, create_os_window, current_os_window,
destroy_global_data, get_clipboard_string, global_font_size,
mark_os_window_for_close, os_window_font_size, patch_global_colors,
set_clipboard_string, set_in_sequence_mode, toggle_fullscreen
safe_pipe, set_clipboard_string, set_in_sequence_mode, thread_write,
toggle_fullscreen, toggle_maximized
)
from .keys import get_shortcut, shortcut_matches
from .layout import set_draw_borders_options
from .layout import set_layout_options
from .remote_control import handle_cmd
from .rgb import Color, color_from_int
from .session import create_sessions
@@ -104,7 +106,7 @@ class DumpCommands: # {{{
class Boss:
def __init__(self, os_window_id, opts, args, cached_values, new_os_window_trigger):
set_draw_borders_options(opts)
set_layout_options(opts)
self.clipboard_buffers = {}
self.update_check_process = None
self.window_id_map = WeakValueDictionary()
@@ -133,13 +135,13 @@ class Boss:
if new_os_window_trigger is not None:
self.keymap.pop(new_os_window_trigger, None)
for startup_session in startup_sessions:
os_window_id = self.add_os_window(startup_session, os_window_id=os_window_id)
self.add_os_window(startup_session, os_window_id=os_window_id)
os_window_id = None
if args.start_as != 'normal':
if args.start_as == 'fullscreen':
self.toggle_fullscreen()
else:
change_os_window_state(args.start_as)
os_window_id = None
if is_macos:
from .fast_data_types import cocoa_set_notification_activated_callback
cocoa_set_notification_activated_callback(self.notification_activated)
@@ -361,6 +363,9 @@ class Boss:
def toggle_fullscreen(self):
toggle_fullscreen()
def toggle_maximized(self):
toggle_maximized()
def start(self):
if not getattr(self, 'io_thread_started', False):
self.child_monitor.start()
@@ -614,12 +619,12 @@ class Boss:
if tm is not None:
tm.update_tab_bar_data()
def on_drop(self, os_window_id, paths):
def on_drop(self, os_window_id, strings):
tm = self.os_window_map.get(os_window_id)
if tm is not None:
w = tm.active_window
if w is not None:
w.paste('\n'.join(paths))
w.paste('\n'.join(strings))
def on_os_window_closed(self, os_window_id, viewport_width, viewport_height):
self.cached_values['window-size'] = viewport_width, viewport_height
@@ -635,16 +640,12 @@ class Boss:
def notify_on_os_window_death(self, address):
import socket
s = socket.socket(family=socket.AF_UNIX)
try:
with suppress(Exception):
s.connect(address)
s.sendall(b'c')
try:
with suppress(EnvironmentError):
s.shutdown(socket.SHUT_RDWR)
except EnvironmentError:
pass
s.close()
except Exception:
pass
def display_scrollback(self, window, data, cmd):
tab = self.active_tab
@@ -715,7 +716,9 @@ class Boss:
},
cwd=w.cwd_of_child,
overlay_for=w.id
))
),
copy_colors_from=w
)
overlay_window.action_on_close = partial(self.on_kitten_finish, w.id, end_kitten)
return overlay_window
@@ -756,10 +759,10 @@ class Boss:
def kitty_shell(self, window_type):
cmd = ['@', kitty_exe(), '@']
if window_type == 'tab':
self._new_tab(cmd).active_window
self._new_tab(cmd)
elif window_type == 'os_window':
os_window_id = self._new_os_window(cmd)
self.os_window_map[os_window_id].active_window
self.os_window_map[os_window_id]
elif window_type == 'overlay':
w = self.active_window
tab = self.active_tab
@@ -845,7 +848,8 @@ class Boss:
def set_active_tab(self, tab):
tm = self.active_tab_manager
if tm is not None:
tm.set_active_tab(tab)
return tm.set_active_tab(tab)
return False
def next_tab(self):
tm = self.active_tab_manager
@@ -909,14 +913,30 @@ class Boss:
tm.new_tab(special_window=create_window(), cwd_from=cwd_from)
elif dest == 'os_window':
self._new_os_window(create_window(), cwd_from=cwd_from)
elif dest in ('clipboard', 'primary'):
env, stdin = self.process_stdin_source(stdin=source, window=window)
if stdin:
func = set_clipboard_string if dest == 'clipboard' else set_primary_selection
func(stdin)
else:
import subprocess
env, stdin = self.process_stdin_source(stdin=source, window=window)
cwd = None
if cwd_from:
with suppress(Exception):
cwd = cwd_of_process(cwd_from)
if stdin:
p = subprocess.Popen(cmd, env=env, stdin=subprocess.PIPE)
p.communicate(stdin)
r, w = safe_pipe(False)
try:
subprocess.Popen(cmd, env=env, stdin=r, cwd=cwd)
except Exception:
os.close(w)
else:
thread_write(w, stdin)
finally:
os.close(r)
else:
subprocess.Popen(cmd)
subprocess.Popen(cmd, env=env, cwd=cwd)
def args_to_special_window(self, args, cwd_from=None):
args = list(args)
@@ -971,10 +991,14 @@ class Boss:
def _new_window(self, args, cwd_from=None):
tab = self.active_tab
if tab is not None:
location = None
if args and args[0].startswith('!'):
location = args[0][1:].lower()
args = args[1:]
if args:
return tab.new_special_window(self.args_to_special_window(args, cwd_from=cwd_from))
return tab.new_special_window(self.args_to_special_window(args, cwd_from=cwd_from), location=location)
else:
return tab.new_window(cwd_from=cwd_from)
return tab.new_window(cwd_from=cwd_from, location=location)
def new_window(self, *args):
self._new_window(args)
@@ -1028,18 +1052,14 @@ class Boss:
def safe_delete_temp_file(self, path):
if is_path_in_temp_dir(path):
try:
with suppress(FileNotFoundError):
os.remove(path)
except FileNotFoundError:
pass
def set_update_check_process(self, process=None):
if self.update_check_process is not None:
try:
with suppress(Exception):
if self.update_check_process.poll() is None:
self.update_check_process.kill()
except Exception:
pass
self.update_check_process = process
def on_monitored_pid_death(self, pid, exit_status):

View File

@@ -51,10 +51,48 @@ vec4 alpha_blend_premul(vec3 over, float over_alpha, vec3 under, float under_alp
float alpha = mix(under_alpha, 1.0f, over_alpha);
return vec4(premul_blend(over, over_alpha, under), alpha);
}
vec4 blend_onto_opaque_premul(vec3 over, float over_alpha, vec3 under) {
// same as alpha_blend_premul with under_alpha = 1 outputs a blended color
// with alpha 1 which is effectively pre-multiplied since alpha is 1
return vec4(premul_blend(over, over_alpha, under), 1.0);
}
// }}}
/*
* Explanation of rendering:
* There are a couple of cases, in order of increasing complexity:
* 1) Simple -- this path is used when there are either no images, or all images are
* drawn on top of text and the background is opaque. In this case, there is a single pass,
* of this shader with cell foreground and background colors blended directly.
* Expected output is a color premultiplied by alpha, with an alpha specified as well.
*
* 2) Interleaved -- this path is used if background is not opaque and there are images or
* if the background is opaque but there are images under text. Rendering happens in
* multiple passes drawing the background and foreground separately and blending.
*
* 2a) Opaque bg with images under text
* There are multiple passes, each pass is blended onto the previous using the opaque blend func (alpha, 1- alpha):
* 1) Draw only the background -- expected output is color with alpha 1
* 2) Draw the images that are supposed to be below text. This happens in the graphics shader
* 3) Draw the special cells (selection/cursor). Output is same as from step 1, with bg_alpha 1 for special cells and 0 otherwise
* 4) Draw the foreground -- expected output is color with alpha which is blended using the opaque blend func
* 5) Draw the images that are supposed to be above text again in the graphics shader
*
* 2b) Transparent bg with images
* First everything is rendered into a framebuffer, and then the framebauffer is blended onto
* the screen. The framebuffer is needed because it allows access to the background color pixels
* to blend with the image pixels. The steps are basically the same as for 2a.
*
* In this shader exactly *one* of SIMPLE, SPECIAL, FOREGROUND or BACKGROUND will be defined, corresponding
* to the appropriate rendering pass from above.
*/
#ifdef NEEDS_FOREGROUND
vec4 calculate_foreground() {
// returns the effective foreground color in pre-multiplied form
vec4 text_fg = texture(sprites, sprite_pos);
vec3 fg = mix(foreground, text_fg.rgb, colored_sprite);
float text_alpha = text_fg.a;
@@ -70,15 +108,12 @@ vec4 calculate_foreground() {
#endif
void main() {
#ifdef BACKGROUND
#ifdef SIMPLE
vec4 fg = calculate_foreground();
#ifdef TRANSPARENT
// bg_alpha is doubled to match rendering in the SIMPLE case
// and also rendering of the margin/padding, see https://github.com/kovidgoyal/kitty/pull/1291
// to test use background_opacity, window_margin_width and icat to display
// an image.
final_color = vec4(background.rgb * bg_alpha * bg_alpha, bg_alpha);
final_color = alpha_blend_premul(fg.rgb, fg.a, background.rgb * bg_alpha, bg_alpha);
#else
final_color = vec4(background.rgb, 1.0f);
final_color = blend_onto_opaque_premul(fg.rgb, fg.a, background.rgb);
#endif
#endif
@@ -90,29 +125,22 @@ void main() {
#endif
#endif
#if defined(FOREGROUND) || defined(SIMPLE)
// FOREGROUND or SIMPLE
vec4 fg = calculate_foreground(); // pre-multiplied foreground
#ifdef BACKGROUND
#ifdef TRANSPARENT
final_color = vec4(background.rgb * bg_alpha, bg_alpha);
#else
final_color = vec4(background.rgb, 1.0f);
#endif
#endif
#ifdef FOREGROUND
// FOREGROUND
vec4 fg = calculate_foreground(); // pre-multiplied foreground
#ifdef TRANSPARENT
final_color = fg;
#else
final_color = vec4(fg.rgb / fg.a, fg.a);
#endif
#else
// SIMPLE
#ifdef TRANSPARENT
final_color = alpha_blend_premul(fg.rgb, fg.a, background * bg_alpha, bg_alpha);
final_color = vec4(final_color.rgb, final_color.a);
#else
// since background alpha is 1.0, it is effectively pre-multiplied
final_color = vec4(premul_blend(fg.rgb, fg.a, background), 1.0f);
final_color = vec4(final_color.rgb, final_color.a);
#endif
#endif
#endif
}

View File

@@ -114,7 +114,7 @@ vec3 choose_color(float q, vec3 a, vec3 b) {
return mix(b, a, q);
}
float are_integers_equal(float a, float b) { // return 1 iff equal otherwise 0
float are_integers_equal(float a, float b) { // return 1 if equal otherwise 0
float delta = abs(a - b); // delta can be 0, 1 or larger
return step(delta, 0.5); // 0 if 0.5 < delta else 1
}

View File

@@ -5,6 +5,7 @@
* Distributed under terms of the GPL3 license.
*/
#include "loop-utils.h"
#include "state.h"
#include "threading.h"
#include "screen.h"
@@ -16,10 +17,16 @@
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <signal.h>
extern PyTypeObject Screen_Type;
#ifdef DEBUG_EVENT_LOOP
#define EVDBG(...) log_event(__VA_ARGS__)
#else
#define EVDBG(...)
#endif
#define EXTRA_FDS 2
#ifndef MSG_NOSIGNAL
// Apple does not implement MSG_NOSIGNAL
@@ -46,6 +53,7 @@ typedef struct {
int talk_fd, listen_fd;
Message *messages;
size_t messages_capacity, messages_count;
LoopData io_loop_data;
} ChildMonitor;
@@ -77,7 +85,6 @@ static pthread_mutex_t children_lock;
static bool kill_signal_received = false;
static ChildMonitor *the_monitor = NULL;
static uint8_t drain_buf[1024];
static int signal_fds[2], wakeup_fds[2];
typedef struct {
@@ -110,39 +117,6 @@ set_maximum_wait(double val) {
if (val >= 0 && (val < maximum_wait || maximum_wait < 0)) maximum_wait = val;
}
static void
handle_signal(int sig_num) {
int save_err = errno;
unsigned char byte = (unsigned char)sig_num;
while(true) {
ssize_t ret = write(signal_fds[1], &byte, 1);
if (ret < 0 && errno == EINTR) continue;
break;
}
errno = save_err;
}
static inline bool
self_pipe(int fds[2]) {
#ifdef __APPLE__
int flags;
flags = pipe(fds);
if (flags != 0) return false;
for (int i = 0; i < 2; i++) {
flags = fcntl(fds[i], F_GETFD);
if (flags == -1) { return false; }
if (fcntl(fds[i], F_SETFD, flags | FD_CLOEXEC) == -1) { return false; }
flags = fcntl(fds[i], F_GETFL);
if (flags == -1) { return false; }
if (fcntl(fds[i], F_SETFL, flags | O_NONBLOCK) == -1) { return false; }
}
return true;
#else
return pipe2(fds, O_CLOEXEC | O_NONBLOCK) == 0;
#endif
}
static PyObject *
new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
ChildMonitor *self;
@@ -156,13 +130,9 @@ new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
PyErr_Format(PyExc_RuntimeError, "Failed to create children_lock mutex: %s", strerror(ret));
return NULL;
}
if (!self_pipe(wakeup_fds)) return PyErr_SetFromErrno(PyExc_OSError);
if (!self_pipe(signal_fds)) return PyErr_SetFromErrno(PyExc_OSError);
struct sigaction act = {.sa_handler=handle_signal};
#define SA(which) { if (sigaction(which, &act, NULL) != 0) return PyErr_SetFromErrno(PyExc_OSError); if (siginterrupt(which, false) != 0) return PyErr_SetFromErrno(PyExc_OSError);}
SA(SIGINT); SA(SIGTERM); SA(SIGCHLD);
#undef SA
self = (ChildMonitor *)type->tp_alloc(type, 0);
if (!init_loop_data(&self->io_loop_data)) return PyErr_SetFromErrno(PyExc_OSError);
if (!install_signal_handlers(&self->io_loop_data)) return PyErr_SetFromErrno(PyExc_OSError);
self->talk_fd = talk_fd;
self->listen_fd = listen_fd;
if (self == NULL) return PyErr_NoMemory();
@@ -172,7 +142,7 @@ new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
parse_func = parse_worker_dump;
} else parse_func = parse_worker;
self->count = 0;
fds[0].fd = wakeup_fds[0]; fds[1].fd = signal_fds[0];
fds[0].fd = self->io_loop_data.wakeup_read_fd; fds[1].fd = self->io_loop_data.signal_read_fd;
fds[0].events = POLLIN; fds[1].events = POLLIN;
the_monitor = self;
@@ -193,22 +163,12 @@ dealloc(ChildMonitor* self) {
add_queue_count--;
FREE_CHILD(add_queue[add_queue_count]);
}
close(wakeup_fds[0]);
close(wakeup_fds[1]);
close(signal_fds[0]);
close(signal_fds[1]);
free_loop_data(&self->io_loop_data);
}
void
wakeup_io_loop(bool in_signal_handler) {
while(true) {
ssize_t ret = write(wakeup_fds[1], "w", 1);
if (ret < 0) {
if (errno == EINTR) continue;
if (!in_signal_handler) perror("Failed to write to wakeup fd with error");
}
break;
}
static void
wakeup_io_loop(ChildMonitor *self, bool in_signal_handler) {
wakeup_loop(&self->io_loop_data, in_signal_handler);
}
static void* io_loop(void *data);
@@ -231,11 +191,10 @@ start(PyObject *s, PyObject *a UNUSED) {
Py_RETURN_NONE;
}
static PyObject *
wakeup(PYNOARG) {
wakeup(ChildMonitor *self, PyObject *args UNUSED) {
#define wakeup_doc "wakeup() -> wakeup the ChildMonitor I/O thread, forcing it to exit from poll() if it is waiting there."
wakeup_io_loop(false);
wakeup_io_loop(self, false);
Py_RETURN_NONE;
}
@@ -254,7 +213,7 @@ add_child(ChildMonitor *self, PyObject *args) {
INCREF_CHILD(add_queue[add_queue_count]);
add_queue_count++;
children_mutex(unlock);
wakeup_io_loop(false);
wakeup_io_loop(self, false);
Py_RETURN_NONE;
}
@@ -301,7 +260,7 @@ schedule_write_to_child(unsigned long id, unsigned int num, ...) {
screen->write_buf = PyMem_RawRealloc(screen->write_buf, screen->write_buf_sz);
if (screen->write_buf == NULL) { fatal("Out of memory."); }
}
if (screen->write_buf_used) wakeup_io_loop(false);
if (screen->write_buf_used) wakeup_io_loop(self, false);
screen_mutex(unlock, write);
break;
}
@@ -323,12 +282,9 @@ needs_write(ChildMonitor UNUSED *self, PyObject *args) {
static PyObject *
shutdown_monitor(ChildMonitor *self, PyObject *a UNUSED) {
#define shutdown_monitor_doc "shutdown_monitor() -> Shutdown the monitor loop."
signal(SIGINT, SIG_DFL);
signal(SIGTERM, SIG_DFL);
signal(SIGCHLD, SIG_DFL);
self->shutting_down = true;
wakeup_talk_loop(false);
wakeup_io_loop(false);
wakeup_io_loop(self, false);
int ret = pthread_join(self->io_thread, NULL);
if (ret != 0) return PyErr_Format(PyExc_OSError, "Failed to join() I/O thread with error: %s", strerror(ret));
if (talk_thread_started) {
@@ -339,15 +295,17 @@ shutdown_monitor(ChildMonitor *self, PyObject *a UNUSED) {
Py_RETURN_NONE;
}
static inline void
static inline bool
do_parse(ChildMonitor *self, Screen *screen, double now) {
bool input_read = false;
screen_mutex(lock, read);
if (screen->read_buf_sz || screen->pending_mode.used) {
double time_since_new_input = now - screen->new_input_at;
if (time_since_new_input >= OPT(input_delay)) {
bool read_buf_full = screen->read_buf_sz >= READ_BUF_SZ;
input_read = true;
parse_func(screen, self->dump_callback, now);
if (read_buf_full) wakeup_io_loop(false); // Ensure the read fd has POLLIN set
if (read_buf_full) wakeup_io_loop(self, false); // Ensure the read fd has POLLIN set
screen->new_input_at = 0;
if (screen->pending_mode.activated_at) {
double time_since_pending = MAX(0, now - screen->pending_mode.activated_at);
@@ -356,12 +314,14 @@ do_parse(ChildMonitor *self, Screen *screen, double now) {
} else set_maximum_wait(OPT(input_delay) - time_since_new_input);
}
screen_mutex(unlock, read);
return input_read;
}
static void
static bool
parse_input(ChildMonitor *self) {
// Parse all available input that was read in the I/O thread.
size_t count = 0, remove_count = 0;
bool input_read = false;
double now = monotonic();
PyObject *msg = NULL;
children_mutex(lock);
@@ -416,10 +376,11 @@ parse_input(ChildMonitor *self) {
for (size_t i = 0; i < count; i++) {
if (!scratch[i].needs_removal) {
do_parse(self, scratch[i].screen, now);
if (do_parse(self, scratch[i].screen, now)) input_read = true;
}
DECREF_CHILD(scratch[i]);
}
return input_read;
}
static inline void
@@ -432,7 +393,7 @@ mark_child_for_close(ChildMonitor *self, id_type window_id) {
}
}
children_mutex(unlock);
wakeup_io_loop(false);
wakeup_io_loop(self, false);
}
@@ -521,9 +482,7 @@ pyset_iutf8(ChildMonitor *self, PyObject *args) {
#undef INCREF_CHILD
#undef DECREF_CHILD
static double last_render_at = -DBL_MAX;
extern void cocoa_update_title(PyObject*);
extern void cocoa_update_menu_bar_title(PyObject*);
static inline void
collect_cursor_info(CursorRenderInfo *ans, Window *w, double now, OSWindow *os_window) {
@@ -559,7 +518,7 @@ update_window_title(Window *w, OSWindow *os_window) {
Py_INCREF(os_window->window_title);
set_os_window_title(os_window, PyUnicode_AsUTF8(w->title));
#ifdef __APPLE__
if (os_window->is_focused && OPT(macos_show_window_title_in_menubar)) cocoa_update_title(w->title);
if (os_window->is_focused && (OPT(macos_show_window_title_in) & MENUBAR)) cocoa_update_menu_bar_title(w->title);
#endif
return true;
}
@@ -672,10 +631,19 @@ draw_resizing_text(OSWindow *w) {
}
}
static inline bool
no_render_frame_received_recently(OSWindow *w, double now, double max_wait) {
bool ans = now - w->last_render_frame_received_at > max_wait;
if (ans) log_error("No render frame received in %f seconds, re-requesting at: %f", max_wait, now);
return ans;
}
static inline void
render(double now) {
render(double now, bool input_read) {
EVDBG("input_read: %d", input_read);
static double last_render_at = -DBL_MAX;
double time_since_last_render = now - last_render_at;
if (time_since_last_render < OPT(repaint_delay)) {
if (!input_read && time_since_last_render < OPT(repaint_delay)) {
set_maximum_wait(OPT(repaint_delay) - time_since_last_render);
return;
}
@@ -688,7 +656,7 @@ render(double now) {
continue;
}
if (USE_RENDER_FRAMES && w->render_state != RENDER_FRAME_READY) {
if (w->render_state == RENDER_FRAME_NOT_REQUESTED) request_frame_render(w);
if (w->render_state == RENDER_FRAME_NOT_REQUESTED || no_render_frame_received_recently(w, now, 0.25)) request_frame_render(w);
continue;
}
make_os_window_context_current(w);
@@ -723,7 +691,7 @@ typedef struct { int fd; uint8_t *buf; size_t sz; } ThreadWriteData;
static inline ThreadWriteData*
alloc_twd(size_t sz) {
ThreadWriteData *data = malloc(sizeof(ThreadWriteData));
ThreadWriteData *data = calloc(1, sizeof(ThreadWriteData));
if (data != NULL) {
data->sz = sz;
data->buf = malloc(sz);
@@ -771,11 +739,25 @@ static void*
thread_write(void *x) {
ThreadWriteData *data = (ThreadWriteData*)x;
set_thread_name("KittyWriteStdin");
FILE *f = fdopen(data->fd, "w");
if (fwrite(data->buf, 1, data->sz, f) != data->sz) {
log_error("Failed to write all data");
int flags = fcntl(data->fd, F_GETFL, 0);
if (flags == -1) { free_twd(data); return 0; }
flags &= ~O_NONBLOCK;
fcntl(data->fd, F_SETFL, flags);
size_t pos = 0;
while (pos < data->sz) {
errno = 0;
ssize_t nbytes = write(data->fd, data->buf + pos, data->sz - pos);
if (nbytes < 0) {
if (errno == EAGAIN || errno == EINTR) continue;
break;
}
if (nbytes == 0) break;
pos += nbytes;
}
fclose(f);
if (pos < data->sz) {
log_error("Failed to write all data to STDIN of child process with error: %s", strerror(errno));
}
safe_close(data->fd);
free_twd(data);
return 0;
}
@@ -792,7 +774,8 @@ cm_thread_write(PyObject UNUSED *self, PyObject *args) {
data->fd = fd;
memcpy(data->buf, buf, data->sz);
int ret = pthread_create(&thread, NULL, thread_write, data);
if (ret != 0) { free_twd(data); return PyErr_SetFromErrno(PyExc_OSError); }
if (ret != 0) { safe_close(fd); free_twd(data); return PyErr_SetFromErrno(PyExc_OSError); }
pthread_detach(thread);
Py_RETURN_NONE;
}
@@ -913,21 +896,23 @@ static void process_global_state(void *data);
static void
do_state_check(id_type timer_id UNUSED, void *data) {
ChildMonitor *self = data;
process_global_state(self);
EVDBG("State check timer fired");
process_global_state(data);
}
static id_type state_check_timer = 0;
static void
process_global_state(void *data) {
EVDBG("Processing global state");
ChildMonitor *self = data;
maximum_wait = -1;
bool state_check_timer_enabled = false;
double now = monotonic();
if (global_state.has_pending_resizes) process_pending_resizes(now);
render(now);
bool input_read = parse_input(self);
render(now, input_read);
#ifdef __APPLE__
if (cocoa_pending_actions) {
if (cocoa_pending_actions & PREFERENCES_WINDOW) { call_boss(edit_config_file, NULL); }
@@ -941,7 +926,6 @@ process_global_state(void *data) {
cocoa_pending_actions = 0;
}
#endif
parse_input(self);
if (global_state.terminate) {
global_state.terminate = false;
close_all_windows();
@@ -954,7 +938,8 @@ process_global_state(void *data) {
if (global_state.has_pending_closes) has_open_windows = process_pending_closes(self);
if (has_open_windows) {
if (maximum_wait >= 0) {
state_check_timer_enabled = true;
if (maximum_wait == 0) request_tick_callback();
else state_check_timer_enabled = true;
}
} else {
stop_main_loop();
@@ -1005,7 +990,7 @@ hangup(pid_t pid) {
static inline void
cleanup_child(ssize_t i) {
close(children[i].fd);
safe_close(children[i].fd);
hangup(children[i].pid);
}
@@ -1074,35 +1059,28 @@ drain_fd(int fd) {
ssize_t len = read(fd, drain_buf, sizeof(drain_buf));
if (len < 0) {
if (errno == EINTR) continue;
if (errno != EIO) perror("Call to read() from drain fd failed");
break;
}
if (len > 0) continue;
break;
}
}
static inline void
read_signals(int fd, bool *kill_signal, bool *child_died) {
static char buf[256];
while(true) {
ssize_t len = read(fd, buf, sizeof(buf));
if (len < 0) {
if (errno == EINTR) continue;
if (errno != EIO) perror("Call to read() from read_signals() failed");
typedef struct { bool kill_signal, child_died; } SignalSet;
static void
handle_signal(int signum, void *data) {
SignalSet *ss = data;
switch(signum) {
case SIGINT:
case SIGTERM:
ss->kill_signal = true;
break;
case SIGCHLD:
ss->child_died = true;
break;
default:
break;
}
for (ssize_t i = 0; i < len; i++) {
switch(buf[i]) {
case SIGCHLD:
*child_died = true; break;
case SIGINT:
case SIGTERM:
*kill_signal = true; break;
default:
break;
}
}
break;
}
}
@@ -1212,11 +1190,11 @@ io_loop(void *data) {
if (ret > 0) {
if (fds[0].revents && POLLIN) drain_fd(fds[0].fd); // wakeup
if (fds[1].revents && POLLIN) {
SignalSet ss = {0};
data_received = true;
bool kill_signal = false, child_died = false;
read_signals(fds[1].fd, &kill_signal, &child_died);
if (kill_signal) { children_mutex(lock); kill_signal_received = true; children_mutex(unlock); }
if (child_died) reap_children(self, OPT(close_on_child_death));
read_signals(fds[1].fd, handle_signal, &ss);
if (ss.kill_signal) { children_mutex(lock); kill_signal_received = true; children_mutex(unlock); }
if (ss.child_died) reap_children(self, OPT(close_on_child_death));
}
for (i = 0; i < self->count; i++) {
if (fds[EXTRA_FDS + i].revents & (POLLIN | POLLHUP)) {
@@ -1296,14 +1274,14 @@ typedef struct {
PeerReadData *reads;
PeerWriteData *writes;
PeerWriteData *queued_writes;
int wakeup_fds[2];
LoopData loop_data;
pthread_mutex_t peer_lock;
} TalkData;
static TalkData talk_data = {0};
typedef struct pollfd PollFD;
#define PEER_LIMIT 256
#define nuke_socket(s) { shutdown(s, SHUT_RDWR); close(s); }
#define nuke_socket(s) { shutdown(s, SHUT_RDWR); safe_close(s); }
static inline bool
accept_peer(int listen_fd, bool shutting_down) {
@@ -1336,7 +1314,7 @@ read_from_peer(ChildMonitor *self, int s) {
if (rd->fd == s) {
if (rd->used >= rd->capacity) {
if (rd->capacity >= 1024 * 1024) failed("Ignoring too large message from peer");
rd->capacity = MAX(8192, rd->capacity * 2);
rd->capacity = MAX(8192u, rd->capacity * 2);
rd->data = realloc(rd->data, rd->capacity);
if (!rd->data) failed("Out of memory");
}
@@ -1424,7 +1402,7 @@ prune_finished_writes(void) {
PeerWriteData *wd = talk_data.writes + i;
if (wd->finished) {
remove_poll_fd(wd->fd);
shutdown(wd->fd, SHUT_WR); close(wd->fd);
shutdown(wd->fd, SHUT_WR); safe_close(wd->fd);
free(wd->data);
ssize_t num_to_right = talk_data.num_writes - 1 - i;
if (num_to_right > 0) memmove(talk_data.writes + i, talk_data.writes + i + 1, num_to_right * sizeof(PeerWriteData));
@@ -1436,15 +1414,7 @@ prune_finished_writes(void) {
static void
wakeup_talk_loop(bool in_signal_handler) {
if (talk_data.wakeup_fds[1] <= 0) return;
while(true) {
ssize_t ret = write(talk_data.wakeup_fds[1], "w", 1);
if (ret < 0) {
if (errno == EINTR) continue;
if (!in_signal_handler) perror("Failed to write to talk wakeup fd with error");
}
break;
}
wakeup_loop(&talk_data.loop_data, in_signal_handler);
}
static inline void
@@ -1473,7 +1443,7 @@ talk_loop(void *data) {
ChildMonitor *self = (ChildMonitor*)data;
set_thread_name("KittyPeerMon");
if ((pthread_mutex_init(&talk_data.peer_lock, NULL)) != 0) { perror("Failed to create peer mutex"); return 0; }
if (!self_pipe(talk_data.wakeup_fds)) { perror("Failed to create wakeup fds for talk thread"); return 0; }
if (!init_loop_data(&talk_data.loop_data)) { log_error("Failed to create wakeup fd for talk thread with error: %s", strerror(errno)); }
ensure_space_for(&talk_data, fds, PollFD, 8, fds_capacity, 8, false);
#define add_listener(which) \
if (self->which > -1) { \
@@ -1481,7 +1451,7 @@ talk_loop(void *data) {
}
add_listener(talk_fd); add_listener(listen_fd);
#undef add_listener
talk_data.fds[talk_data.num_listen_fds].fd = talk_data.wakeup_fds[0]; talk_data.fds[talk_data.num_listen_fds++].events = POLLIN;
talk_data.fds[talk_data.num_listen_fds].fd = talk_data.loop_data.wakeup_read_fd; talk_data.fds[talk_data.num_listen_fds++].events = POLLIN;
while (LIKELY(!self->shutting_down)) {
for (size_t i = 0; i < talk_data.num_listen_fds + talk_data.num_talk_fds; i++) { talk_data.fds[i].revents = 0; }
@@ -1504,7 +1474,7 @@ talk_loop(void *data) {
} else if (ret < 0) { if (errno != EAGAIN && errno != EINTR) perror("poll() on talk fds failed"); }
}
end:
close(talk_data.wakeup_fds[0]); close(talk_data.wakeup_fds[1]);
free_loop_data(&talk_data.loop_data);
free(talk_data.fds); free(talk_data.reads); free(talk_data.writes); free(talk_data.queued_writes);
return 0;
}
@@ -1530,8 +1500,8 @@ add_peer_writer(int fd, const char* msg, size_t msg_sz) {
static void
send_response(int fd, const char *msg, size_t msg_sz) {
if (msg == NULL) { shutdown(fd, SHUT_WR); close(fd); return; }
if (!add_peer_writer(fd, msg, msg_sz)) { shutdown(fd, SHUT_WR); close(fd); }
if (msg == NULL) { shutdown(fd, SHUT_WR); safe_close(fd); return; }
if (!add_peer_writer(fd, msg, msg_sz)) { shutdown(fd, SHUT_WR); safe_close(fd); }
else wakeup_talk_loop(false);
}
@@ -1565,18 +1535,20 @@ PyTypeObject ChildMonitor_Type = {
static PyObject*
safe_pipe(PYNOARG) {
safe_pipe(PyObject *self UNUSED, PyObject *args) {
int nonblock = 1;
if (!PyArg_ParseTuple(args, "|p", &nonblock)) return NULL;
int fds[2] = {0};
if (!self_pipe(fds)) return PyErr_SetFromErrno(PyExc_OSError);
if (!self_pipe(fds, nonblock)) return PyErr_SetFromErrno(PyExc_OSError);
return Py_BuildValue("ii", fds[0], fds[1]);
}
static PyMethodDef module_methods[] = {
METHODB(safe_pipe, METH_NOARGS),
METHODB(safe_pipe, METH_VARARGS),
{"add_timer", (PyCFunction)add_python_timer, METH_VARARGS, ""},
{"remove_timer", (PyCFunction)remove_python_timer, METH_VARARGS, ""},
METHODB(monitor_pid, METH_VARARGS),
{"set_iutf8", (PyCFunction)pyset_iutf8, METH_VARARGS, ""},
{"set_iutf8_winid", (PyCFunction)pyset_iutf8, METH_VARARGS, ""},
{NULL} /* Sentinel */
};

Some files were not shown because too many files have changed in this diff Show More