Compare commits

...

1060 Commits

Author SHA1 Message Date
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
Kovid Goyal
f61dfb0828 Fix warning on older compilers 2019-05-24 12:07:24 +05:30
Kovid Goyal
00fe963e7c version 0.14.0 2019-05-24 11:52:46 +05:30
Kovid Goyal
009ea1c8cd Merge branch 'change_package_manager_installation_docs' of https://github.com/Luflosi/kitty 2019-05-22 21:19:22 +05:30
Luflosi
72069015b9 Add Homebrew and Nix (not only on NixOS) as package manager to the installation instructions 2019-05-22 14:08:02 +02:00
Kovid Goyal
6c0c67dd7b Merge branch 'docs_use_better_word' of https://github.com/Luflosi/kitty 2019-05-22 06:36:42 +05:30
Luflosi
3c090519a0 docs: "relatively little effort" instead of "relatively less effort" 2019-05-22 02:55:23 +02:00
Kovid Goyal
5da70929f6 Merge branch 'docs_mouse_hide_wait_attention' of https://github.com/Luflosi/kitty 2019-05-22 06:19:25 +05:30
Luflosi
5b66d6209f Move documentation for mouse_hide_wait config option to the top of the Mouse group
Fixes #1626.
This makes it harder to miss this option in case a user is confused why the mouse cursor keeps disappearing.
2019-05-22 02:42:37 +02:00
Kovid Goyal
9f7f353485 Merge branch 'macos_mouse_cursor_off_by_one' of https://github.com/Luflosi/kitty 2019-05-22 06:06:33 +05:30
Luflosi
05f01525c3 Revert "macOS: Fix cocoa mouse y-coord off by one"
This reverts commit 8969206450.
Fixes #1621.
When committing b3f1acd400, applying the glfw upstream patch 3c3981a4f0 for https://github.com/glfw/glfw/issues/1461, this commit should have been reverted as it was just a quick fix for https://github.com/glfw/glfw/issues/1461.
2019-05-21 19:31:57 +02:00
Kovid Goyal
3aa016940c Merge branch 'python3_shebang' of https://github.com/Luflosi/kitty 2019-05-21 21:30:59 +05:30
Luflosi
a792c94ccf Use python3 shebang for all python scripts
Fixes #1624.
Use python3 shebang for all python scripts as python still defaults to python2 on many systems.
2019-05-20 14:44:24 +02:00
Kovid Goyal
249e59b310 Only reset dirty flag on borders if actually updated 2019-05-20 11:18:54 +05:30
Kovid Goyal
3b43b76222 Merge branch 'fix_copy_and_paste_error' of https://github.com/Luflosi/kitty 2019-05-19 19:44:29 +05:30
Luflosi
398f5cfbdc Fix copy and paste error 2019-05-19 16:08:11 +02:00
Kovid Goyal
bc47be64b0 Merge branch 'missing_file_header' of https://github.com/Luflosi/kitty 2019-05-19 19:31:50 +05:30
Luflosi
59c6fb9ce7 Add file header to build-terminfo 2019-05-19 15:41:46 +02:00
Kovid Goyal
8b99d0a432 Make the default live resize strategy drawing the current window contents unchanged 2019-05-19 09:45:59 +05:30
Kovid Goyal
639b18c7e8 Better fix for python include dirs
Ensure their order is stable
2019-05-19 09:17:52 +05:30
Kovid Goyal
701942f6ef Fix #1619 2019-05-19 07:21:52 +05:30
Kovid Goyal
9d8e6a2b30 Merge branch 'rename_linux_launcher' of https://github.com/Luflosi/kitty 2019-05-19 07:17:41 +05:30
Luflosi
581deb6073 Rename linux-launcher -> launcher
Since the launcher is also used on macOS, rename it to something more generic.
2019-05-18 19:13:56 +02:00
Kovid Goyal
9849a69afd Allow extending word selections to non-word chars 2019-05-16 20:20:03 +05:30
Kovid Goyal
5f33d907aa Mouse selection: When extending by word, fix selection encompassing one or two non-word characters after a word when the mouse is over that character
Fixes #1616
2019-05-16 18:32:15 +05:30
Kovid Goyal
0919eda640 Merge branch 'typo' of https://github.com/Luflosi/kitty 2019-05-15 16:58:37 +05:30
Luflosi
5952a140e0 Fix typo 2019-05-15 13:16:42 +02:00
Kovid Goyal
6d92996661 make comment more helpful 2019-05-13 21:13:45 +05:30
Kovid Goyal
04e4b0c469 Fix rendering of text containing the VS15 variation selector
Fixes #1611
2019-05-13 20:52:14 +05:30
Kovid Goyal
20f4a9a942 ... 2019-05-13 20:42:30 +05:30
Kovid Goyal
5552679c11 Left in a print statement 2019-05-13 20:37:44 +05:30
Kovid Goyal
1369a36178 Exclude variation selectors when finding fallback font 2019-05-13 20:36:29 +05:30
Kovid Goyal
529337e00a Ensure cursor is correctly positioned after emoji presentation char + VS15
cursor should be on the cell immediately after the the char since the
variation selector makes the char one cell wide.
2019-05-13 20:18:41 +05:30
Kovid Goyal
fe882dad15 Add support for Vs-15 to wcswidth 2019-05-13 19:50:49 +05:30
Kovid Goyal
4fff84b4b9 Add void to all function declarations for functions that take no arguments
Micro-optimization for some architectures. Enforced via
-Wstrict-prototypes
2019-05-13 11:04:21 +05:30
Kovid Goyal
3e964163c0 Pass zero for fullscreen flags on non Cocoa platforms 2019-05-12 16:07:54 +05:30
Kovid Goyal
10a987b908 Simplify code 2019-05-12 16:01:09 +05:30
Kovid Goyal
03e417e1be ... 2019-05-12 16:00:02 +05:30
Kovid Goyal
c95d3b19b3 X11 backend: Get rid of override redirect
Was used for hackish fullscreen, which we no longer support
2019-05-12 15:59:16 +05:30
Kovid Goyal
1fa9b8f102 X11: use the window manager's native full-screen implementation when making windows full-screen
This matches the behavior on Cocoa and Wayland.
Fixes #1605
2019-05-12 15:53:06 +05:30
Kovid Goyal
c27cf31a7c Only wait 0.2 secs after live resize if the resize strategy is "size" 2019-05-12 15:39:03 +05:30
Kovid Goyal
ad672fc9d6 Wayland: Remove wl_shell support
From upstream: 599fb3de34
2019-05-11 17:50:02 +05:30
Kovid Goyal
a0f298ddb0 ... 2019-05-11 16:35:48 +05:30
Kovid Goyal
9b740849ed Allow the user to control the draw strategy during OS window resizes
Changed the default to scaled which matches current macOS behavior.
Fixes #1591
2019-05-11 15:49:11 +05:30
Kovid Goyal
a3f9835b7b X11 backend: Improve performance when handling consecutive XkbKeyMap events
Only recompile the keymap when actually needed, greatly improving
performance when the X server sends multiple consecutive key map events.
Fixes #1606
2019-05-11 13:39:05 +05:30
Kovid Goyal
f4294b83fb Add a rationale for PWD 2019-05-11 12:59:01 +05:30
Kovid Goyal
4fa4a20b22 When launching child process set the PWD environment variable
This allows shells to display the symlink path to a directory instead
of the resolved path, when the specified directory is a symlink. Fixes #1595
2019-05-11 12:57:25 +05:30
Kovid Goyal
af2c9a49b1 ... 2019-05-11 12:04:07 +05:30
Kovid Goyal
bdeec61266 macOS: Add an entry point to use that works even if run via a symlink
Fixes #1539
2019-05-11 10:25:06 +05:30
Kovid Goyal
268e5cef3b Remove useless else 2019-05-03 13:37:57 +05:30
Kovid Goyal
b37f4333e2 Merge branch 'master' of github.com:kovidgoyal/kitty 2019-05-03 13:31:10 +05:30
Kovid Goyal
f0c663d42d macOS: Improve handling of IME extended input
Compose characters are now highlighted and the IME panel moves along with the text

Fixes #1586
Fixes #1461
2019-05-03 13:30:56 +05:30
BlahGeek
e36e44ab3a macOS: do not pass input events while having marked text
fix chinese input method backspacing issue

macOS: Set pre-edit text for IME

macOS: implement glfwPlatformUpdateIMEState

set firstRectForCharacterRange correctly

macOS: update IME position on each input

macOS: use float instead of int for updateIMEState

minor fix

macOS: ignore marked text on deadkey

fixes german keyboard input

macOS: convert markedRect to screen coord
2019-05-03 13:27:06 +05:30
Kovid Goyal
2dceec444f Merge branch 'fix-windows-for-payload' of https://github.com/blahgeek/kitty 2019-05-02 15:20:02 +05:30
BlahGeek
eaba3cff0b Fix windows_for_payload 2019-05-02 17:39:00 +08:00
Kovid Goyal
ec31a348cf oops 2019-05-01 13:11:49 +05:30
Kovid Goyal
d6a6e26500 Remote control: Make the :ref:at_set-font-size command more capable.
Fixes #1581
2019-05-01 12:37:39 +05:30
Kovid Goyal
cab1ba4e50 Use sys._xoptions to pass bundle_exe_dir
This allows it to be used with the make app kitty bundle as well.
This makes it robust against launching in environments where
python3 is not on PATH. See #1280
2019-05-01 08:45:01 +05:30
Kovid Goyal
a2f589be00 Make use of realpath() safer 2019-05-01 07:55:03 +05:30
Kovid Goyal
7622cbaed5 Avoid rapid transitions between the cells banner and the normal terminal view when live resizing on systems without live resizing notifications 2019-04-29 18:19:03 +05:30
Kovid Goyal
53df123c0d Allow the user to control the resize debounce time via resize_debounce_time 2019-04-28 21:16:13 +05:30
Kovid Goyal
c660840c19 When encountering errors in kitty.conf report them to the user instead of failing to start. 2019-04-28 20:53:59 +05:30
Kovid Goyal
c6d3ede57e Fix show_error kitten --title not working 2019-04-28 20:48:57 +05:30
Kovid Goyal
6037167336 Allow controlling the ligature strategy dynamically, per window
Fixes #1574
2019-04-27 22:05:33 +05:30
Kovid Goyal
0804447881 Merge branch 'patch-1' of https://github.com/g4s8/kitty 2019-04-27 18:52:57 +05:30
Kirill
83482873dc CR: grammar fixes 2019-04-27 14:11:12 +03:00
Kirill
5e351e4d65 Mentioned kitty list-fonts command 2019-04-27 13:02:52 +03:00
Kovid Goyal
408cd9cf9b Wayland: Only print out window attention error once 2019-04-27 14:53:31 +05:30
Kovid Goyal
8b47e63136 Wayland backend: Dont roundtrip to the server just to wakeup the main loop 2019-04-27 14:52:15 +05:30
Kovid Goyal
379ec88776 Only use the tick callback mechanism on macOS
On Linux, just call the tick callback on every loop tick. This is much
simpler, and should fix the issue with screen updates sometimes getting
stuck waiting for an X11 event.

Note that this was what used to happen (global state being checked on
every loop tick) before the refactoring to use a GLFW event loop,
therefore there should be no performance regressions, though we
of course end up checking global state on every group of events on
Linux, instead of only when something of interest happens. I suspect, to
achieve the latter is going to require implementing a mutex/lock in the
main loop to avoid races, which doesn't seem worth it.
2019-04-27 14:40:09 +05:30
Kovid Goyal
a320e8bc25 When debuggin event loop display number of dispatched X11 events 2019-04-27 13:52:44 +05:30
Kovid Goyal
1c4f5b471d Fix #1575 2019-04-27 07:58:07 +05:30
Kovid Goyal
d5846282a9 Avoid bikeshedding about the best way to suppress flake8 messages 2019-04-24 23:46:24 +05:30
Kovid Goyal
8b56f1ced6 Forgot to specify the default for --extra-logging 2019-04-24 16:19:30 +05:30
Kovid Goyal
0987a536b1 Add extra logging to debug the event loop
This should make tracking down the root cause of the
event loop pauses on X11 easier. And the infrastructure
should come in handy in the future as well.
2019-04-24 16:16:40 +05:30
Kovid Goyal
099510f4d1 Fix docs build failure
dynamic_background_opacity needs to be its own option in the conf docs.
2019-04-24 15:39:16 +05:30
Kovid Goyal
35c6014025 Merge branch 'update_changelog' of https://github.com/Luflosi/kitty 2019-04-24 15:27:18 +05:30
Luflosi
895ac26d43 Update changelog.rst to reflect change to disable_ligatures config option
In 934336e642, the config option
`disable_ligatures_under_cursor` was renamed to `disable_ligatures` and the
behaviour of that option was altered so that it is now possible to
disable ligatures completely. This commit reflects that change in changelog.rst
2019-04-24 11:48:39 +02:00
Kovid Goyal
da999f730b Dont assume sphinx-build is a python script
Fixes #1561
2019-04-24 15:12:36 +05:30
Kovid Goyal
47969e9f18 Use multiple CPU cores for sphinx-build 2019-04-24 15:08:51 +05:30
Kovid Goyal
b6267d4a8c X11 backend: Get rid of server roundtrip just to wake up the event loop 2019-04-24 13:42:26 +05:30
Kovid Goyal
2df97e309b X11 backend: Dispatch X11 events after XFlush 2019-04-24 06:25:00 +05:30
Kovid Goyal
078b23e6aa Merge branch 'https' of https://github.com/Luflosi/kitty 2019-04-24 05:15:54 +05:30
Luflosi
d8eeed2296 Convert HTTP URLs to HTTPS URLs where possible 2019-04-24 01:27:24 +02:00
Kovid Goyal
e5afc5297a Dont use multiprocessing to get CPU counts 2019-04-22 08:49:22 +05:30
Kovid Goyal
465ed48e73 When generating python bytecode, do it for all optimization levels 2019-04-22 08:46:33 +05:30
Kovid Goyal
f8b311b289 Cache calls to fc_match since FcFontMatch is very slow
Fixes #1547
2019-04-21 11:07:37 +05:30
Kovid Goyal
934336e642 Allow disabling ligatures always 2019-04-20 08:25:44 +05:30
Kovid Goyal
6f5ff05c56 Merge branch 'master' of https://github.com/fdev31/kitty 2019-04-19 14:09:48 +05:30
fdev31
2376b7c255 implement fast browsing of the unicode input
useful for zones with icons
2019-04-18 22:52:06 +02:00
Kovid Goyal
ef86f8a20c NSGL: Disable swap interval
Swap interval now uses CVDisplayLink.
From upstream: 28f118f4de
2019-04-18 10:14:29 +05:30
Kovid Goyal
b3f1acd400 Cocoa: Fix coordinate transformations
From upstream: 3c3981a4f0
2019-04-18 10:12:41 +05:30
Kovid Goyal
5c4462281e Cocoa: Upstream fix for mouse hover detection
0e74265426
2019-04-18 09:58:09 +05:30
Kovid Goyal
91d94f262c Merge branch 'patch-1' of https://github.com/serebit/kitty 2019-04-17 07:48:40 +05:30
Campbell Jones
2651acce91 Add link for the Solus package 2019-04-16 20:43:38 -04:00
Kovid Goyal
25cfcdba76 Dont hide mouse on modifier key presses 2019-04-16 15:16:14 +05:30
Kovid Goyal
6f5004fc13 Merge branch 'hide_mouse_on_key' of https://github.com/Luflosi/kitty 2019-04-15 19:55:00 +05:30
Luflosi
df9c1aea64 Add note to changelog.rst 2019-04-15 10:11:54 +02:00
Luflosi
a309069b6b Describe new feature in config_data.py 2019-04-15 09:51:57 +02:00
Luflosi
beb90f2c55 Implement feedback 2019-04-15 09:17:31 +02:00
Luflosi
0e0aba7a5e Option for hide mouse on keypress event 2019-04-14 18:07:26 +02:00
Kovid Goyal
6e9b41314e Add a link to the FAQ to a repo of kitty themes 2019-04-14 08:26:37 +05:30
Kovid Goyal
dbeac923ed oops 2019-04-13 18:37:06 +05:30
Kovid Goyal
5953c2097d Expand env vars throughout command lines
When converting strings to command lines interpret env vars in all the
parts of the command line not just the first item. Fixes #1535
2019-04-13 13:53:32 +05:30
Kovid Goyal
8969206450 macOS: Fix cocoa mouse y-coord off by one
See https://github.com/glfw/glfw/issues/1461
2019-04-09 22:02:36 +05:30
Kovid Goyal
41318d763b Fix missing context APIs in version strings 2019-04-09 10:06:10 +05:30
Kovid Goyal
8251b906b6 Add a listener for GPU changed events on macOS
Currently does nothing, but could potentially be used to fix:
https://github.com/kovidgoyal/kitty/issues/794

Will need someone with the hardware though to test
exactly what needs to be done to restore the custom cursor image.
2019-04-06 10:05:21 +05:30
Kovid Goyal
790d630d17 typo 2019-04-06 09:10:16 +05:30
Kovid Goyal
c9644039b1 Merge branch 'add_option_to_not_switch_to_previous_when_closing_current_tab' of https://github.com/ddddavidmartin/kitty 2019-04-03 14:23:14 +05:30
David Martin
34de072a10 Add option to disable switching to the previous tab when closing the current one.
When setting tab_bar_switch_to_previous_when_closing_current_tab kitty
will now switch to the left tab instead of the previously active one
when the currently active tab is closed. This makes the closing of tabs
a bit more predictable.

Note that we are not touching the handling of the active_tab_history at
all. I was considering it, but we want to keep track of it in any case
to keep the 'switch to previous tab' shortcut working.
2019-04-03 19:27:04 +11:00
Kovid Goyal
f6d7b3aa04 Merge branch 'update-docs-mouse' of https://github.com/eepp/kitty 2019-04-03 12:03:15 +05:30
Philippe Proulx
5c31c2b98e Docs: update mouse features
In the "Mouse features" section:

* Make it clear that you can double-click or triple-click and then drag
  to extend the initial selection.

* Add the fact that selecting copies the selected text to the primary
  clipboard on platforms supporting this.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
2019-04-03 01:59:55 -04:00
Kovid Goyal
2cc779b667 Merge branch 'fix-mouse-release-other-window' of https://github.com/eepp/kitty 2019-04-03 10:59:54 +05:30
Kovid Goyal
7f4294f68c Merge branch 'dbl-click-drag-extend-sel' of https://github.com/eepp/kitty 2019-04-03 10:59:28 +05:30
Philippe Proulx
fd2515da5c Do not focus window when mouse button is released
It is useless to focus a window on mouse button release. This behaviour
makes this scenario possible:

1. Have at least two visible windows in the current tab.
2. Select text in a window with the left mouse button, dragging, and
   release the mouse button within the other window.

The focus is changed to the other window. I believe this is unexpected.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
2019-04-02 19:36:26 -04:00
Philippe Proulx
db1f53fc29 Double-click + drag to select multiple words
This patch reverts part of cb095be0cc to
allow again to double-click and then drag to select multiple words.

With this patch, the primary selection is still not updated until you
release the mouse's left button, but the selection does not "block" on
the first word while trying to double-click and drag.

I believe this behaviour has come to be expected by users, since GNOME
Terminal, Terminator, xterm, rxvt, major browsers, LibreOffice, and many
more significant applications have it.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
2019-04-02 18:31:32 -04:00
Kovid Goyal
96f5c66755 Allow setting OS window size in session files 2019-04-02 20:20:39 +05:30
Kovid Goyal
4baf7b5bba Allow creating new OS windows in session files
Fixes #1514
2019-04-02 19:57:09 +05:30
Kovid Goyal
58bb5a7d1f ... 2019-04-01 23:29:27 +05:30
Kovid Goyal
c63dd76814 Note what the default for --cwd for @ new-window is 2019-03-28 18:43:17 +05:30
Kovid Goyal
8d3e6b4796 Fix disabling of ligatures under cursor
Now uses glyph groups to detect a possible ligature and turn off
ligatures only in that group. Requires a re-render of parts of the line,
but I dont see a good way to avoid that.
2019-03-28 18:33:28 +05:30
Kovid Goyal
b10312e249 Upstream fixes for vulkan surface creation and the retina hint
e108c0de0d
980fc9b52f
2019-03-28 13:09:22 +05:30
Kovid Goyal
6f3a9d6d29 macOS: Remove check for pre-10.8 SDK 2019-03-28 12:42:14 +05:30
Kovid Goyal
c4e89d9d0c macOS: Consolidate compatibility macros for old SDKs in one place 2019-03-28 12:37:05 +05:30
Kovid Goyal
00a2126152 Document the comments syntax for config files
Fixes #1503
2019-03-28 08:08:21 +05:30
Kovid Goyal
e7099cc771 Forgot to escape the backslash in the docs for reset_terminal 2019-03-25 12:05:56 +05:30
Kovid Goyal
b6724ed177 ... 2019-03-24 10:06:18 +05:30
Kovid Goyal
fcedc9f5c3 Allow setting :opt:active_border_color to `none` to not draw a border around the active window
Fixes #805
Fixes #1491
2019-03-24 10:04:32 +05:30
Kovid Goyal
cb095be0cc Only update the selected text to clipboard when the selection is finished, not continuously as it is updated.
Fixes #1460
Fixes #1492
2019-03-24 08:44:12 +05:30
Kovid Goyal
ecf2c86787 Wayland: Abort on fatal display errors instead of looping forever 2019-03-22 08:53:10 +05:30
Kovid Goyal
971c28ce97 Fix tab title not always being updated when active window is closed 2019-03-21 20:44:55 +05:30
Kovid Goyal
482129ff35 Increase resize debounce time 2019-03-21 20:44:24 +05:30
Kovid Goyal
65c75859bc Move rendering of resize banner into the tick callback
Unifies all rendering in one place. And possibly fixes issues with
rendering in a resize callback on sway.
2019-03-21 16:54:15 +05:30
Kovid Goyal
fcb26e5dc7 Cocoa: User performSelectorOnMainLoop for render frames as well which means render frames work during modal loops 2019-03-21 16:51:01 +05:30
Kovid Goyal
0dc6ac26c3 Cocoa: user performSelectorOnMainThread instead of postEvent for the tick callback
performSelectorOnMainThread runs in more loop run modes which means that
the tick callback will behave more like it does on other platforms,
during window resizes and other modal event loops.
2019-03-21 15:55:43 +05:30
Kovid Goyal
48303bac75 Use "arrow" as the arrow cursor on Linux
Different themes preferentiallyuse left_prt or right_ptr, so use arrow
instead
2019-03-21 13:22:13 +05:30
Kovid Goyal
5ab8a665be GLFW: Add more standard cursor shapes
Also use an enum for the cursor shapes
2019-03-21 13:06:13 +05:30
Kovid Goyal
733158a2de Better error reporting when failing to load cursor 2019-03-21 10:38:26 +05:30
Kovid Goyal
a2e47d2d0e EGL: Warn if non-blocking swap buffers is not available 2019-03-21 09:46:46 +05:30
Kovid Goyal
bfb97a6e6f Wayland: use correct name for hand cursor 2019-03-21 09:24:51 +05:30
Kovid Goyal
fc1a8351b0 Dont use a wide cursor in beam an unfocused modes
Fixes #1486
2019-03-20 19:57:59 +05:30
Kovid Goyal
be7a4a5868 Add an option :opt:disable_ligatures_under_cursor to disable multi-character ligatures under the cursor to make editing easier
Fixes #461
2019-03-20 16:28:27 +05:30
Kovid Goyal
493892a4df Merge branch 'no_ligatures_under_cursor' of https://github.com/Luflosi/kitty 2019-03-20 15:59:46 +05:30
Kovid Goyal
106dc2b03b Wayland: Load cursor theme at init even if no mouse pointer is currently present 2019-03-20 15:56:34 +05:30
Kovid Goyal
d5490475f1 Nicer error message when contacting GitHub to check for latest release fails 2019-03-20 08:38:35 +05:30
Luflosi
999a6a288c Do not render ligatures under cursor 2019-03-20 01:35:03 +01:00
Kovid Goyal
7d9d096fbf Rationalize change reporting after configure event on Wayland
Fixes #1482 (I hope)
2019-03-19 15:02:11 +05:30
Kovid Goyal
c129dd9331 Wayland: Ignore invalid scale values from compositor 2019-03-19 14:30:43 +05:30
Kovid Goyal
5c75ac0a96 GLFW Wayland backend: Dont fire resize events for Wayland configure events that dont change the window size. Fixes #1473 2019-03-17 15:07:32 +05:30
Kovid Goyal
bafedf8376 Make the scale sanitization more comprehensive 2019-03-17 12:41:03 +05:30
Kovid Goyal
136f15e647 Fix move to GLFW event loop breaking using macOS native quit action with no windows open.
Fixes #1476
2019-03-17 12:27:41 +05:30
Kovid Goyal
e9e4ac13ee Fix #1472 2019-03-16 07:37:36 +05:30
Kovid Goyal
e24c758341 Merge branch 'potential_undefined_behaviour' of https://github.com/Luflosi/kitty 2019-03-15 19:57:02 +05:30
Luflosi
4b65b4ac2b Fix potential undefined behaviour
When `gray_color_space` is `NULL`, it is passed into `CGBitmapContextCreate()`. Since there are no guarantees in https://developer.apple.com/documentation/coregraphics/1455939-cgbitmapcontextcreate?language=objc to what happens in that case, depending on the implementation there may be undefined behaviour.
2019-03-15 14:31:19 +01:00
Kovid Goyal
d8d7765a82 DRYer 2019-03-15 18:52:24 +05:30
Kovid Goyal
b98bc1c787 Add --help to kitty command line completion
Fixes #1469
2019-03-15 18:50:59 +05:30
Kovid Goyal
4b08ce2a09 Merge branch 'warn_invalid_config' of https://github.com/Luflosi/kitty 2019-03-15 11:05:49 +05:30
Luflosi
ed62e72a98 Warn when a line in the config file is invalid 2019-03-14 18:46:36 +01:00
Luflosi
a28710c1fc Minor refactor 2019-03-14 18:46:36 +01:00
Kovid Goyal
764a058cf6 Allow using tabs as delimiters in the config file
Fixes #1466
2019-03-14 22:51:52 +05:30
Kovid Goyal
a538663679 Merge branch 'fix_typo' of https://github.com/Luflosi/kitty 2019-03-13 05:59:28 +05:30
Luflosi
8920d64f7d Fix typo 2019-03-12 19:38:06 +01:00
Kovid Goyal
a051cb9ee3 Fix a regression in version 0.13.0 that caused background colors of space characters after private use unicode characters to not be respected
Fixes #1455
2019-03-11 20:03:58 +05:30
Kovid Goyal
56864cdfb7 When a window is closed, switch focus to the previously active window (if any) instead of picking the previous window in the layout
Fixes #1450
2019-03-09 10:42:55 +05:30
Kovid Goyal
428c600788 When parsing CSI codes allow - as a primary modifier
Fixes #1438
2019-03-08 09:58:18 +05:30
Kovid Goyal
748f1a90b9 Move swap interval setting to just before swap buffers 2019-03-07 18:15:27 +05:30
Kovid Goyal
d3cee832ce Wayland: Dont try to focus window on create/show since it is not allowed anyway 2019-03-07 18:14:12 +05:30
Kovid Goyal
8129246a10 Set swap interval before first call to swap buffers 2019-03-07 18:06:51 +05:30
Kovid Goyal
a2789650e5 Insert google analytics at publish time 2019-03-07 12:07:49 +05:30
Kovid Goyal
af376cf27e Tested scaling needed for initial window size on Wayland 2019-03-07 09:23:44 +05:30
Kovid Goyal
6c8ccbd73a ... 2019-03-07 06:40:33 +05:30
Kovid Goyal
626ac0d5b8 Restrict initial cell based size scaling to macOS only
No way to check if it is the right thing to do on other platforms
2019-03-06 21:40:05 +05:30
Kovid Goyal
2550bc910d Fix specifying initial window size in cells not working correctly on HiDPI screens
Fixes #1444
2019-03-06 21:23:54 +05:30
Kovid Goyal
0a153e2524 Wayland: Use the kitty Wayland backend by default 2019-03-06 21:04:34 +05:30
Kovid Goyal
facd353228 Update to using the Unicode 12 standard 2019-03-06 13:58:16 +05:30
Kovid Goyal
5b7eac280c DRYer
Store expected value of VS15 in only one place
2019-03-06 13:53:09 +05:30
Kovid Goyal
7ab63525c7 Dont use a global autorelease variable
Use function local @autorelease blocks instead
2019-03-06 09:34:55 +05:30
Kovid Goyal
a1c49a0f7f Cocoa: Disable shadow for transparent framebuffer
From upstream: 9883cb64f0
2019-03-06 09:12:16 +05:30
Kovid Goyal
4c4c6ab0e6 Various fixes for monitor work area retrieval from upstream 2019-03-06 09:08:08 +05:30
Kovid Goyal
2e0d39b512 Remove windows glfw backend as it is unused 2019-03-06 08:47:45 +05:30
Kovid Goyal
0899019518 Add glfwGetMonitorWorkarea
From upstream: be295ccbea
2019-03-06 08:47:01 +05:30
Kovid Goyal
db16996181 Fix Coverity Scan false positive
From upstream: c20754c4a6
2019-03-06 08:40:02 +05:30
Kovid Goyal
aa2b21456f Round refresh rate instead of truncating
From upstream: 621ece63c8
2019-03-06 08:36:59 +05:30
Kovid Goyal
7e8e1e9e89 Merge branch 'wrong_terminfo_location' of https://github.com/Luflosi/kitty 2019-03-05 06:27:39 +05:30
Luflosi
01e9702958 Fix wrong terminfo location 2019-03-05 01:24:22 +01:00
Kovid Goyal
6d970c1175 Add a changelog entry for live resizing 2019-03-04 19:55:53 +05:30
Kovid Goyal
16c0871e22 Implement resizing cells rendering on CoreText 2019-03-04 19:54:11 +05:30
Kovid Goyal
fd7ddc2905 Handle OS not reporting live resizing end 2019-03-04 19:54:10 +05:30
Kovid Goyal
c181919a57 Fix rendering of simple strings with FreeType 2019-03-04 19:54:10 +05:30
Kovid Goyal
5955b44c74 Remove unused code 2019-03-04 19:54:10 +05:30
Kovid Goyal
8b5f02bb0b Fix shader invocation for cells output during resize 2019-03-04 19:54:10 +05:30
Kovid Goyal
f2a1ff2584 ... 2019-03-04 19:54:10 +05:30
Kovid Goyal
11522ccc92 Initial code to show window size in cells while resizing 2019-03-04 19:54:10 +05:30
Kovid Goyal
bb97c589c1 FreeType code to render a simple string 2019-03-04 19:54:09 +05:30
Kovid Goyal
4a5a9b2888 Render windows as bank during a resize 2019-03-04 19:54:09 +05:30
Kovid Goyal
b1bd581065 Make live resize code a little cleaner 2019-03-04 19:54:05 +05:30
Kovid Goyal
3bd1ca0ac3 Avoid using timing related hacks to detect the end of a live resize on macOS
Since cocoa provides start/end notifications for live resizing, rely on
those instead.
2019-03-04 19:52:46 +05:30
Kovid Goyal
bbeb08ba08 Change docs for resize kludge on Cocoa 2019-03-04 19:52:46 +05:30
Kovid Goyal
66dbdf4b40 Do notcheck for closed windows on every loop tick 2019-03-04 19:52:46 +05:30
Kovid Goyal
f0a2c34eca Port cocoa backed to use glfw mainloop 2019-03-04 19:52:46 +05:30
Kovid Goyal
9f35b9281b Avoid needing to continuously add/remove timers 2019-03-04 19:52:46 +05:30
Kovid Goyal
7624578c21 Fix X11/Wayland addTimer returning incorrect timer ids 2019-03-04 19:52:45 +05:30
Kovid Goyal
d4b477ad78 Share main loop implementation between wayland and X11 2019-03-04 19:52:45 +05:30
Kovid Goyal
e6d5eea7eb Get rid of glfw_post_empty_event as it is not needed 2019-03-04 19:52:45 +05:30
Kovid Goyal
bef9490fa8 Switch to using the GLFW main loop 2019-03-04 19:52:45 +05:30
Kovid Goyal
d593ccba2f Add a loop tick callback 2019-03-04 19:52:45 +05:30
Kovid Goyal
1902d8bb19 Explicitly handle the empty events on X11 2019-03-04 19:52:45 +05:30
Kovid Goyal
f10c65f1bf Use the new glfw timers to get rid of the kitty specific timers 2019-03-04 19:52:45 +05:30
Kovid Goyal
da507dfd19 Infrastructure for moving the run loop into GLFW
This is needed on Cocoa, where Apple expects to be in control of the run
loop.
2019-03-04 19:52:44 +05:30
Kovid Goyal
13254ac4d5 Fix #1435 2019-03-03 07:24:05 +05:30
Kovid Goyal
fc9ffb3115 Add changes to clipboard-control to changelog 2019-03-02 11:57:19 +05:30
Kovid Goyal
f64ffcac48 Merge branch 'clipboard_control-no-append' of https://github.com/agriffis/kitty 2019-03-02 11:55:42 +05:30
Kovid Goyal
f2a6cb3dbb Merge branch 'replace_terminfo_dir_with_symlink' of https://github.com/Luflosi/kitty 2019-03-02 11:34:53 +05:30
Luflosi
4767d2b8d6 Replace the "78" terminfo directory with a symlink 2019-03-02 03:04:20 +01:00
Aron Griffis
1ceb8b1b0b Allow no-append in clipboard_control
If no-append is present in clipboard_control, this will disable kitty's
OSC 52 extension of concatenating to the clipboard.

See #995
2019-03-01 09:10:07 -05:00
Kovid Goyal
719a9a5b64 Fix #1428 2019-02-28 18:05:52 +05:30
Kovid Goyal
5adf7c2a3a icat kitten: Add a --silent flag to avoid printing anything to stdout
Useful for integration with other tools. See #1308
2019-02-27 09:02:15 +05:30
Kovid Goyal
1c9d6bf9e6 Merge branch 'more_verbose_error_messages' of https://github.com/Luflosi/kitty 2019-02-26 08:04:13 +05:30
Luflosi
f85dfe91a9 Log the exact value of the cell height/width when it's invalid 2019-02-26 03:26:53 +01:00
Kovid Goyal
749fb84053 Cleanup cell dim sanity checks 2019-02-26 07:02:45 +05:30
Kovid Goyal
e33af8b2f8 Fix #1423 2019-02-26 06:56:25 +05:30
Kovid Goyal
61a9f7baae Merge branch 'cell_height_width_off_by_one' of https://github.com/Luflosi/kitty 2019-02-25 21:19:22 +05:30
Luflosi
4d4b690a99 Change cell_height and cell_width checks to be consistent with later check 2019-02-25 16:13:56 +01:00
Kovid Goyal
d4c2293d56 Merge branch 'color_code_case' of https://github.com/Luflosi/kitty 2019-02-25 20:03:16 +05:30
Luflosi
3b34cec64c Consistent case for color codes 2019-02-25 14:47:14 +01:00
Kovid Goyal
a1e9b854e3 Move cocoa custom even dispatching into the application object
This allows it to work even with the cocoa run loop
2019-02-25 15:51:39 +05:30
Kovid Goyal
01ed1e1604 Move initial window blanking to before showing the window 2019-02-25 15:07:03 +05:30
Kovid Goyal
b7b1a1f1c6 Blank the window at creation so that there is no initial flash of color changing, in case the background color is not black
Fixes #1404
2019-02-25 14:32:56 +05:30
Kovid Goyal
c9446727d3 Only set swap interval once 2019-02-25 14:28:47 +05:30
Kovid Goyal
cff79bc9d4 Forgot that cocoa blink interval time is in ms 2019-02-25 11:17:29 +05:30
Kovid Goyal
72ccf87d19 macOS: Use the system cursor blink interval by default
Can be changed with:

defaults write -g NSTextInsertionPointBlinkPeriodOff -float 500
defaults write -g NSTextInsertionPointBlinkPeriodOn -float 500
2019-02-25 09:37:48 +05:30
Kovid Goyal
2387c71b3c Merge branch 'macos_switch_tab_shortcut' of https://github.com/Luflosi/kitty 2019-02-25 06:58:55 +05:30
Luflosi
47a2120023 Add two more macOS keyboard shortcuts for switching tabs 2019-02-24 17:37:02 +01:00
Kovid Goyal
b777353766 Missed one call to migrate 2019-02-24 20:14:31 +05:30
Kovid Goyal
5d4491667b Use a single function for cocoa pending actions
Also fix a couple of memory leaks when using coca pending actions with a
wd
2019-02-24 20:07:37 +05:30
Kovid Goyal
9fbd14f815 Merge branch 'check_for_null' of https://github.com/Luflosi/kitty 2019-02-24 19:45:15 +05:30
Luflosi
f38b27e923 Add check for NULL after malloc() 2019-02-24 14:48:54 +01:00
Kovid Goyal
cb8116e2af Fix leak of a few bytes of memory after every update notification
Fixes #1411
2019-02-24 10:19:19 +05:30
Kovid Goyal
2066dd0077 Merge branch 'memory_leak_no_2' of https://github.com/Luflosi/kitty 2019-02-23 20:24:00 +05:30
Luflosi
37afd7aaa7 Fix memory leak 2019-02-23 15:46:16 +01:00
Kovid Goyal
8df9ccc72c Merge branch 'memory_leak__nr_1' of https://github.com/Luflosi/kitty 2019-02-23 18:00:18 +05:30
Luflosi
862075bd65 Fix memory leak 2019-02-23 12:32:40 +01:00
Kovid Goyal
27ffed5a1a Merge branch 'exe-ordered' of https://github.com/blueyed/kitty
Fixes #1406
2019-02-23 15:31:57 +05:30
Kovid Goyal
bf2c50b58b Merge branch 'check_for_null' of https://github.com/Luflosi/kitty 2019-02-23 15:19:32 +05:30
Daniel Hahler
34c35ff4ca kitty_exe: use ordered list
Fixes https://github.com/kovidgoyal/kitty/issues/1406.
2019-02-23 10:40:00 +01:00
Luflosi
174a45b4bd Add check for NULL after malloc() 2019-02-23 09:13:12 +01:00
Kovid Goyal
e44b331cc3 Fix exception when getting function name for debug_keyboard action dispatch
Fixes #1401
2019-02-23 08:00:21 +05:30
Kovid Goyal
aed504efdc Remove unnecessary NULL check 2019-02-23 07:42:08 +05:30
Kovid Goyal
ca38568187 Merge branch 'wrong_return_type' of https://github.com/Luflosi/kitty 2019-02-22 22:42:32 +05:30
Luflosi
a653c17e8a Fix function returning the wrong type 2019-02-22 15:13:13 +01:00
Kovid Goyal
6bbd33eca4 ... 2019-02-21 08:41:56 +05:30
Kovid Goyal
494235750e Cleanup note on visudo 2019-02-21 08:38:39 +05:30
Lucius Hu
076c81c4ee Add notes on getting sudo to preserve TERMINFO to the FAQ 2019-02-21 08:36:59 +05:30
Kovid Goyal
abd4de7311 macOS: Fix :opt:sync_to_monitor not working on Mojave. 2019-02-20 20:09:15 +05:30
Kovid Goyal
4629ef627f GLFW: Add support for render frames on Cocoa (CVDisplayLink)
Allows vsync to work again since Apple broke OpenGL swap intervals on
Mojave
2019-02-20 15:08:07 +05:30
Kovid Goyal
b1c2e90a05 oops 2019-02-20 06:21:13 +05:30
Kovid Goyal
c19cbaad24 Handle wrap around when using negative values for adjust cell sizes 2019-02-20 06:19:54 +05:30
Kovid Goyal
1a3fdac4e4 Merge branch 'macos_focus_change' of https://github.com/koekeishiya/kitty 2019-02-20 06:11:27 +05:30
koekeishiya
d343981faa #1379 highest_focus_counter and loop index should be initialized to 0 2019-02-19 21:23:56 +01:00
Kovid Goyal
51c0c51884 Allow using the new private internal clipboard buffers with the copy_on_select option
Fixes #1390
2019-02-19 21:12:37 +05:30
Kovid Goyal
cb2d162bec Support for an arbitrary number of internal clipboard buffers to copy/paste from 2019-02-19 20:41:23 +05:30
Kovid Goyal
6507fd1ac2 Refactor code to focus previous window on cocoa into a separate function 2019-02-19 20:09:24 +05:30
Kovid Goyal
442f2adf23 Use non-deprecated API to get workspaces for window on Cocoa
Thanks to @koekeishiya
2019-02-19 19:54:59 +05:30
Kovid Goyal
702613915b Revert "macOS: Fix v-sync to monitor refresh rate no longer working under Mojave."
This reverts commit 104e213934.

Fixes #1393
2019-02-19 14:43:36 +05:30
Kovid Goyal
8ebc9553c3 Report negative percentage adjustments of cell sizes
Fixes #1394
2019-02-19 07:17:10 +05:30
Kovid Goyal
ae8076e411 Add a note about runnning commands from within kitty to the timeout error message 2019-02-18 10:29:04 +05:30
Kovid Goyal
f3974671f6 macOS: Reduce energy consumption by not rendering occluded windows 2019-02-18 10:10:04 +05:30
Kovid Goyal
dcb2d95f9a GLFW: Add support for window occluded notifications on macOS
Based on: https://github.com/glfw/glfw/pull/1123
2019-02-18 10:03:21 +05:30
Kovid Goyal
c8bb7aae40 Merge branch 'upper_case_fatal_messages' of https://github.com/Luflosi/kitty 2019-02-18 08:24:34 +05:30
Luflosi
4711e10df2 Let all fatal messages begin with an upper case character 2019-02-17 22:43:10 +01:00
Kovid Goyal
28f1b8a7a0 Nicer report when failing to process update check data
Fixes #1389
2019-02-17 16:00:36 +05:30
Kovid Goyal
104e213934 macOS: Fix v-sync to monitor refresh rate no longer working under Mojave.
Mojave broke the technique GLFW used to use for v-sync. Changed to use
CVDisplayLink, fix comes from: https://github.com/glfw/glfw/pull/1417
2019-02-17 11:39:49 +05:30
Kovid Goyal
fe3a432845 Documentation for window frames on Wayland 2019-02-17 10:38:48 +05:30
Kovid Goyal
423f8e59cc Wayland: Fix auto-iconify on kwin_wayland
Upstream: 45bd991ea9
2019-02-17 10:35:39 +05:30
Kovid Goyal
1c468b2931 Wayland: Only auto-iconify fullscreen windows
Upstream: edf0a07174
2019-02-17 10:31:17 +05:30
Kovid Goyal
85faad5ec7 Wayland: use SHM_ANON on FreeBSD
Upstream: 36ce73bbfd
2019-02-17 10:30:02 +05:30
Kovid Goyal
869152750c X11: Fix system cursor used for GLFW_HAND_CURSOR
From upstream: 2a27eb95e4
2019-02-17 10:21:15 +05:30
Kovid Goyal
7fd4ec50c9 macOS: When closing a top-level window only switch focus to the previous kitty window if it is on the same workspace
Fixes #1379
Fixes #1383
2019-02-16 13:21:52 +05:30
Kovid Goyal
8de4dd334b Use Apple private APIs to get workspace id 2019-02-16 12:58:15 +05:30
Kovid Goyal
c5cc208397 Dont use a stack to focus other window on window close 2019-02-16 12:26:49 +05:30
Kovid Goyal
718e6fa93d Fix scrollback pager history not being cleared when clearing the main scrollback buffer
Fixes #1387
2019-02-16 12:15:39 +05:30
Kovid Goyal
0833697c49 Merge branch 'more_macos_keyboard_shortcuts' of https://github.com/Luflosi/kitty 2019-02-15 10:18:57 +05:30
Kovid Goyal
112ae0edab Next release will be 0.14.0 not 0.13.x 2019-02-15 10:12:25 +05:30
Kovid Goyal
502c31b408 icat: Ensure temp files are cleaned up 2019-02-15 10:08:25 +05:30
Kovid Goyal
062563a562 icat: Add support for file:// URLs as well 2019-02-15 09:59:54 +05:30
Kovid Goyal
c385532b10 A new option :opt:tab_bar_min_tabs to control how many tabs must be present before the tab-bar is shown
Fixes #1382
2019-02-15 09:47:22 +05:30
Kovid Goyal
81f4b4cece ... 2019-02-15 06:52:33 +05:30
Kovid Goyal
23482e3cf4 macOS: Allow assigning only the left or right :kbd:Option key to work as the :kbd:Alt key. See :opt:macos_option_as_alt for details
Fixes #1022
2019-02-14 20:39:32 +05:30
Kovid Goyal
b49b34c4c1 Micro-optimization 2019-02-14 15:41:29 +05:30
Kovid Goyal
b40ca5800d macOS: Fix using multi-key sequences to input text ignoring the first few key presses if the sequence is aborted
Fixes #1311
2019-02-14 15:10:13 +05:30
Kovid Goyal
3b25081353 Print out current text when ignoring dead keys 2019-02-14 14:56:06 +05:30
Kovid Goyal
5726466db3 Ensure cells are at least 2 pixels wide
User could specify adjust_column_width to make cells too naroow
otherwise
2019-02-14 10:22:45 +05:30
Kovid Goyal
27acd4c7d4 Don't crash when rendering special cells with absurd cell sizes
Fixes #1378
2019-02-14 09:49:51 +05:30
Kovid Goyal
f98d780f3e macOS: Allow opening new kitty tabs/top-level windows from Finder
Merge branch 'macos_service' of https://github.com/Luflosi/kitty
2019-02-11 14:53:12 +05:30
Luflosi
8177cfac2a macOS Finder Service to open a directory in a new kitty tab or window 2019-02-10 15:38:45 +01:00
Kovid Goyal
fb4123a6f2 Guard calls to glfwGetMonitorContentScale 2019-02-08 08:03:16 +05:30
Kovid Goyal
191913b7eb Add a paragraph about unrecognized key handling 2019-02-05 14:14:36 +05:30
Kovid Goyal
3a3f745d31 ... 2019-02-05 10:41:05 +05:30
Kovid Goyal
eebe12a972 Allow specifying a value of `none for the :opt:selection_foreground`` which will cause kitty to not change text color in selections
Fixes #1358
2019-02-05 10:34:56 +05:30
Kovid Goyal
274dd2f3fe Cleanup
From upstream: 90e22947c6
2019-02-03 20:17:28 +05:30
Kovid Goyal
fb5dbc811b Cocoa: Fix handling of analog joystick buttons
From upstream: 463ef7eb71
2019-02-03 20:16:47 +05:30
Kovid Goyal
c31c32f921 Cocoa: Add missing IOHID page and usages
From upstream: 51ca41dd9f
2019-02-03 20:15:33 +05:30
Kovid Goyal
22b756753a X11: Fix EWMH state update for hidden windows
From upstream: 78e6a0063d
2019-02-03 20:09:18 +05:30
Kovid Goyal
cb7eb48768 Cleanup
From upstream: d5ab3e919a
2019-02-03 20:04:54 +05:30
Kovid Goyal
22ed014123 Fix tabs being used for spaces in some source code files 2019-02-03 19:59:02 +05:30
Kovid Goyal
419b078104 Remove duplicate centerCursor function
From upstream: a46104ee69
2019-02-03 19:56:16 +05:30
Kovid Goyal
b51584525a Forgot to remove function on apple 2019-02-03 19:47:37 +05:30
Kovid Goyal
728dbbfff0 ... 2019-02-03 19:41:19 +05:30
Kovid Goyal
7485269c37 Forgot to set timers/watches on session bus connection 2019-02-03 19:36:39 +05:30
Kovid Goyal
cffaa54a78 Forgot to dispatch events on the dbus session bus 2019-02-03 18:24:47 +05:30
Kovid Goyal
1f597fd2b3 Speed up build for ubuntu and include debug symbols 2019-02-03 16:00:55 +05:30
Kovid Goyal
48d792bc19 ... 2019-02-03 15:58:29 +05:30
Kovid Goyal
5da123c632 Respond to clicks on user notifications via DBus 2019-02-03 15:54:32 +05:30
Kovid Goyal
27887ada45 Script to easily test kitty in my Ubuntu VM 2019-02-03 15:44:18 +05:30
Kovid Goyal
4c9a6ed56c Set a default action name on the dbus notification 2019-02-03 13:53:26 +05:30
Kovid Goyal
1bf2864638 API to handle DBus user notification activation 2019-02-03 13:20:07 +05:30
Kovid Goyal
c8bd61b345 ... 2019-02-03 11:32:35 +05:30
Kovid Goyal
7ee04b37ac Drop the dependency on libnotify for notifications on Linux 2019-02-03 11:27:05 +05:30
Kovid Goyal
5957befaad Build linux_notify.c 2019-02-03 10:28:03 +05:30
Kovid Goyal
17a16ccd21 Remove unused code 2019-02-03 10:25:38 +05:30
Kovid Goyal
1de940d7b4 Forgot to commit this in the previous commit 2019-02-03 10:24:26 +05:30
Kovid Goyal
9a2ff9e419 Use stdbool for glfw boolean types 2019-02-03 10:13:02 +05:30
Kovid Goyal
84caf787aa macOS: Workaround for cocoa bug that could cause the mouse cursor to become hidden in other applications in rare circumstances
Use window focus gained/lost events instead of mouse enter/exit events
to hide/show the mouse cursor.

Fixes #1218
2019-02-03 08:58:16 +05:30
Kovid Goyal
e9d0d40809 Merge branch 'whitespace' of https://github.com/Luflosi/kitty 2019-02-03 08:17:08 +05:30
Luflosi
0e2a5c63c6 Convert some tabs to spaces 2019-02-02 22:08:32 +01:00
Kovid Goyal
9916802a69 Only kill process if not already dead 2019-02-02 15:56:51 +05:30
Kovid Goyal
bfac482940 Ensure the update check process is killed on exit 2019-02-02 15:48:15 +05:30
Kovid Goyal
8778cf63c4 Correct fix for ignoring BrokenPipeError 2019-02-02 15:47:13 +05:30
Kovid Goyal
d5d1e6c11e Ignore broken pipe errors when readon data from update check worker 2019-02-02 15:41:55 +05:30
Kovid Goyal
8e6780e761 ... 2019-02-02 15:37:48 +05:30
Kovid Goyal
ddb961f9af Dont fail to run if the update check fails 2019-02-02 15:36:32 +05:30
Kovid Goyal
670de085a3 Add API to GLFW for user notifications using DBus 2019-02-02 13:48:26 +05:30
Kovid Goyal
4c49573465 Randomize the sleep before version fetch 2019-02-01 23:33:41 +05:30
Kovid Goyal
13d478ffca Use kitty_exe() for the update_check worker 2019-02-01 23:25:19 +05:30
Kovid Goyal
1cc95a605c Add a link to update instructions at the top of the changelog 2019-02-01 14:46:31 +05:30
Kovid Goyal
e19f180c71 Fix notifications on macOS 2019-02-01 14:43:03 +05:30
Kovid Goyal
d3ad15dc51 Automatically check for new releases and notify when an update is available, via the system notification facilities. Can be controlled by :opt:update_check_interval
Fixes #1342
2019-02-01 12:08:35 +05:30
Kovid Goyal
3aaa69b36c ... 2019-01-31 20:57:21 +05:30
Kovid Goyal
41906cf7db Infrastructure to monitor child processes for death 2019-01-31 20:43:50 +05:30
Kovid Goyal
f3696da0ff Put the functions in the wrong place 2019-01-31 19:55:05 +05:30
Kovid Goyal
fab723b9bc Manage timer callback reference counts 2019-01-31 19:30:40 +05:30
Kovid Goyal
d3a3a89098 Add a function to change timer intervals 2019-01-31 18:43:12 +05:30
Kovid Goyal
68313e99a7 Add a function to remove timers 2019-01-31 18:41:20 +05:30
Kovid Goyal
9b73d25151 Add infrastructure for timers to the event loop 2019-01-31 18:37:29 +05:30
Luflosi
440db8f4bd Revert "Add default keyboard shortcuts to jump words on macOS"
This reverts commit e114c8d6b854e1cfd839ee4a2abf1b450f963f4f.
2019-01-30 12:26:11 +01:00
Luflosi
6690c4f916 Add default keyboard shortcuts to jump words on macOS 2019-01-30 12:26:11 +01:00
Luflosi
6d3ad7d903 Implement suggestions for macOS keyboard shortcuts 2019-01-30 12:26:11 +01:00
Luflosi
0d60b88f1d Add more common macOS keyboard shortcuts 2019-01-30 12:26:10 +01:00
Luflosi
aa82d8fddd Change default of "macos_option_as_alt" option from True to False 2019-01-30 12:26:10 +01:00
Kovid Goyal
10f5461cd8 Nicer signal handling in cocoa for the notification run loop 2019-01-30 14:50:04 +05:30
Kovid Goyal
c7a0626c69 version check infrastructure 2019-01-30 13:49:30 +05:30
Kovid Goyal
6a9a7dee55 macOS: Add an option macos_show_window_title_in_menubar to not show the current window title in the menu-bar
Fixes #1066
2019-01-30 13:29:55 +05:30
Kovid Goyal
8952afd6cc Fix compilation of new choose kitten under FreeBSD
I hope. Fixes #1347
2019-01-30 09:11:25 +05:30
Kovid Goyal
526c526bf3 Make compiler detection more robust 2019-01-30 09:05:42 +05:30
Kovid Goyal
12e269e791 Make the currently released version available on the website 2019-01-29 21:48:11 +05:30
Kovid Goyal
c2f6450af3 Framework for displaying simple OS notifications 2019-01-29 18:11:48 +05:30
Kovid Goyal
c8dfe955d7 ... 2019-01-29 11:08:34 +05:30
Kovid Goyal
71091e73a4 Merge branch 'osx_to_macos' of https://github.com/Luflosi/kitty 2019-01-29 09:01:24 +05:30
Luflosi
25d1b2328f Missed one instance of "OS X" 2019-01-28 23:57:28 +01:00
Kovid Goyal
4085fe2e8e Merge branch 'osx_to_macos' of https://github.com/Luflosi/kitty 2019-01-28 08:44:37 +05:30
Kovid Goyal
74445674f2 Specify the behavior of underline color w.r.t. reverse video 2019-01-28 08:41:02 +05:30
Luflosi
c343bdd120 Rename OS X -> macOS 2019-01-28 01:25:02 +01:00
Kovid Goyal
5ff4a6f4d8 Add a note to the icat help about viewing URLs 2019-01-27 21:33:03 +05:30
Kovid Goyal
5172597d96 Also process ftp URLs in icat 2019-01-27 21:30:53 +05:30
Kovid Goyal
a09fb7b20d icat kitten: Add support for displaying images at http(s) URLs
Fixes #1340
2019-01-27 21:28:46 +05:30
Kovid Goyal
af9e633d56 Remove Travis 2019-01-27 09:45:36 +05:30
Kovid Goyal
df62478418 Install pkg-config in the Brewfile
Not available on CircleCI by default
2019-01-27 09:30:10 +05:30
Kovid Goyal
c623cd5d01 Add a brew build to CircleCI 2019-01-27 09:21:02 +05:30
Kovid Goyal
3126f31cbf CircleCI has enabled mac builds 2019-01-27 08:16:46 +05:30
Kovid Goyal
c33c88b2c6 Ignore background_opacity if could not make window semi-transparent
Should prevent bug reports like #1334
2019-01-27 08:16:07 +05:30
Kovid Goyal
36d5afef9f Disable mac build on CircleCI until they grant access 2019-01-26 14:51:57 +05:30
Kovid Goyal
c8ed52f600 ... 2019-01-26 14:31:33 +05:30
Kovid Goyal
8d7e083e64 Try building on macOS on CircleCI 2019-01-26 14:30:10 +05:30
Kovid Goyal
2144f43142 Add a note about how to build the docker image used for testing 2019-01-26 13:35:22 +05:30
Kovid Goyal
66d2930b7e Add CircleCI badge 2019-01-26 13:06:11 +05:30
Kovid Goyal
4dcaec0997 Env var fixed for bundle build 2019-01-26 12:51:17 +05:30
Kovid Goyal
33da5ca869 --with-system-ffi is ignored as of py3.7 2019-01-26 12:50:10 +05:30
Kovid Goyal
4c1a69a98c SW does not seem to survive despite the ENV key 2019-01-26 12:30:50 +05:30
Kovid Goyal
d613962f5b Check LD_LIBRARY_PATH 2019-01-26 11:57:32 +05:30
Kovid Goyal
8f7cef1232 Fix indentation 2019-01-26 11:53:15 +05:30
Kovid Goyal
7a91ba3699 Add a bundle build to CircleCI 2019-01-26 11:51:23 +05:30
Kovid Goyal
14018a5e54 Fix installation of bundle in container 2019-01-26 11:27:14 +05:30
Kovid Goyal
81a03fcea8 Fix environment key 2019-01-26 10:15:36 +05:30
Kovid Goyal
48962a58ae Set LD_LIBRARY_PATH 2019-01-26 09:38:30 +05:30
Kovid Goyal
8c9c777ad3 More work on CircleCI testing
Make the container more like CircleCI official images. Install
the kitty bundle in it. Run sanitizer and multi-python tests.
2019-01-26 09:04:29 +05:30
Kovid Goyal
dc6e276e39 Install multiple pythons on CircleCI 2019-01-25 15:50:04 +05:30
Kovid Goyal
8182fcecd2 ... 2019-01-25 15:02:42 +05:30
Kovid Goyal
4d082dbf80 Split up deps installation for easier maintenance 2019-01-25 15:02:05 +05:30
Kovid Goyal
5b5c49d317 More dependencies 2019-01-25 14:45:35 +05:30
Kovid Goyal
51b5510669 More needed dependencies 2019-01-25 14:11:45 +05:30
Kovid Goyal
7a4b438dc6 Get basic build going 2019-01-25 14:08:19 +05:30
Kovid Goyal
1a29de5ac9 Forgot workflows key 2019-01-25 12:11:28 +05:30
Kovid Goyal
ed8edf3e4c Install sphinx on CircleCI 2019-01-25 12:08:07 +05:30
Kovid Goyal
9fcde9d81d Use latest ubuntu rather than pinning to bionic 2019-01-25 11:56:51 +05:30
Kovid Goyal
81ffa7e948 Install flake8 and pip and also fix entrypoint 2019-01-25 11:17:48 +05:30
Kovid Goyal
93d2d30867 Do whitespace check on CircleCI 2019-01-25 11:08:17 +05:30
Kovid Goyal
42e05c5ad2 Start config.yml for CircleCI 2019-01-25 11:02:43 +05:30
Kovid Goyal
d37e815f13 Start work on CircleCI integration
CircleCI is nicer than Travis since it allows using custom docker images
transparently, greatly simplifying dependency management.
2019-01-25 10:40:31 +05:30
Kovid Goyal
a1f454937c See if disabling brew update works on Travis as it is very flow (takes eight minutes at the moment) 2019-01-25 09:27:19 +05:30
Kovid Goyal
b041dcc8ce Ensure we dont try to update window title for tabs with no windows 2019-01-24 21:05:46 +05:30
Kovid Goyal
22c65c5d03 Fix window title for minimized windows not being updated
Fixes #1332
2019-01-24 21:04:26 +05:30
Kovid Goyal
60b64dadfe Add tests for the subseq matcher 2019-01-24 20:52:18 +05:30
Kovid Goyal
edb25314c5 Add skeleton for choose kitten 2019-01-23 20:04:46 +05:30
Kovid Goyal
19bce0c23c Start work on a choose kitten for fuzzy selection 2019-01-23 19:38:08 +05:30
Kovid Goyal
8ceb941051 Merge branch 'remove_line' of https://github.com/Luflosi/kitty 2019-01-23 19:35:07 +05:30
Luflosi
8b28cbb30c Remove unwanted line 2019-01-23 12:20:34 +01:00
Kovid Goyal
de130787f6 Make the charsets code useable in kittens 2019-01-23 11:33:45 +05:30
Kovid Goyal
6e94dae9cd Handle cursor_text_color that is already a Color when patching 2019-01-23 10:38:09 +05:30
Kovid Goyal
d2431783f1 Fix using remote control to set cursor text color causing errors when creating new windows
Fixes #1326
2019-01-23 10:14:59 +05:30
Kovid Goyal
5787b472c0 A new option strip_trailing_spaces to optionally remove trailing spaces from lines when copying to clipboard. 2019-01-21 15:48:21 +05:30
Kovid Goyal
6bdfc0387b Mention the new key_demo kitten in the protocol docs 2019-01-21 10:39:42 +05:30
Kovid Goyal
7ba98344b6 Cleanup commit from upstream
2053f3ed22
2019-01-20 14:56:40 +05:30
Kovid Goyal
c887df6ab4 GLFW upstream commit to allow waiting on events without a window
55b1a16f90
2019-01-20 14:55:36 +05:30
Kovid Goyal
a8ad4461a1 Create a kitten to demonstrate the kitty extended keyboard protocol 2019-01-20 14:38:19 +05:30
Kovid Goyal
32a0e28686 macOS: Fix :kbd:cmd+period key not working
Fixes #1318
2019-01-20 13:17:01 +05:30
Kovid Goyal
df13f0ce5a Merge branch 'semicolon' of https://github.com/Luflosi/kitty 2019-01-19 18:02:09 +05:30
Luflosi
972f0c0e2b Remove unnecessary semicolons 2019-01-19 12:28:03 +01:00
Kovid Goyal
c7a3a4d421 Fix use of deprecated sphinx API 2019-01-19 14:16:38 +05:30
Kovid Goyal
fbccfb9d0d version 0.13.3 2019-01-19 14:06:53 +05:30
Kovid Goyal
9fdd8e4ae4 macOS: Fix some kittens causing 100% CPU usage 2019-01-19 14:01:36 +05:30
Kovid Goyal
6b6dea5190 ... 2019-01-19 13:51:18 +05:30
Kovid Goyal
5af551c96d macOS: Fix detection of differ
There can be a wrapper git on macOS that complains about command line
tools installation, so check that passing --help to it actually works.
2019-01-19 12:36:34 +05:30
Kovid Goyal
6761fdca1a ... 2019-01-19 12:16:44 +05:30
Kovid Goyal
725da39ecb macOS: Add aliases for lose window and new tab actions that conform to common Apple shortcuts for these actions
Fixes #1313
2019-01-19 09:18:25 +05:30
Kovid Goyal
9005fc359d Merge branch 'unjam' of https://github.com/jacwah/kitty
Fixes #1312
2019-01-18 22:23:12 +05:30
Jacob Wahlgren
33e4a44008 Unjam event loop when adding pending cocoa action
Fixes the problem reported in
https://github.com/kovidgoyal/kitty/issues/1312.
2019-01-18 17:32:22 +01:00
Kovid Goyal
3bddb9d95b Fix an exception when chaging diff context on very small diffs 2019-01-16 21:24:34 +05:30
Kovid Goyal
fa01e0b76f icat kitten: Add a --stdin option to control if image data is read from stdin
See #1308
2019-01-16 16:35:53 +05:30
Kovid Goyal
f8f188ecff Merge branch 'travis-osx' of https://github.com/stephengroat/kitty 2019-01-16 06:26:02 +05:30
Stephen G
07935d9bd3 Use brew for osx 2019-01-15 15:00:29 -08:00
Kovid Goyal
a827f4190c Merge branch 'fix_white_background_transparency' of https://github.com/Luflosi/kitty 2019-01-14 13:10:15 +05:30
Kovid Goyal
18c108ed03 macOS: Fix a regression that broke mapping of ctrl+tab
Fixes #1304
2019-01-14 10:53:31 +05:30
Kovid Goyal
2d70059f47 Document fix for #1299
Fix #1299
2019-01-14 10:12:05 +05:30
Kovid Goyal
63ff3cfb9f Merge branch 'negative_scroll_alternate_mode' of https://github.com/Luflosi/kitty 2019-01-14 10:10:22 +05:30
Kovid Goyal
ca70f22d46 Add a list of user-created kittens to the docs 2019-01-14 10:03:28 +05:30
Kovid Goyal
c247a6c0cc macOS: Ensure that when running from a bundle, the bundle kitty exe is preferred over any kitty in PATH
Fix #1280
2019-01-14 09:32:49 +05:30
Luflosi
7421a0b9e3 Apply negative scroll multiplier in alternate screen mode
Fixes kovidgoyal/kitty#1299
2019-01-14 00:11:19 +01:00
Kovid Goyal
30b5e8bf8f Merge branch 'patch-1' of https://github.com/robbyoconnor/kitty 2019-01-13 09:50:25 +05:30
Robby O'Connor
96475ce3ee Switch travis to Xenial 2019-01-11 20:53:43 -05:00
Kovid Goyal
24669fb6af Port a couple of fixes from upstream
72c3908e14
cde0aaaab1
2019-01-11 14:20:26 +05:30
Kovid Goyal
851885568f macOS: Fix dragging kitty window tabs in traditional full screen mode causing crashes
Fixes #1296
Apparently, macOS reports NaN DPI values in this scenario.

I dont know enough about cocoa internals to understand why, or
what is actually supposed to happen in this scenario, but at least we
should not crash.
2019-01-11 11:09:34 +05:30
Kovid Goyal
8efbc479e1 Remove unused code 2019-01-09 10:13:43 +05:30
Luflosi
2167bfd5b5 Fix #1221 in a different way 2019-01-08 16:14:41 +01:00
Luflosi
490d4455af Fix white background color not allowing transparency 2019-01-08 16:14:01 +01:00
Kovid Goyal
c94e06ccd2 hints kitten: Start hints numbering at one instead of zero by default. Added an option `--hints-offset` to control it.
Fixes #1289
Fixes #1290
2019-01-08 07:31:54 +05:30
Kovid Goyal
ea37799fb0 Fix linking happening even when not needed 2019-01-06 10:25:37 +05:30
Kovid Goyal
d00fbd73fc Fix a regression in the previous release that broke using `background for cursor_text_color`
Fixes #1288
2019-01-06 10:23:33 +05:30
Kovid Goyal
361b23e3f1 Fix long text docs for copy_to_clipboard 2019-01-04 09:37:59 +05:30
Kovid Goyal
8feccdf63f version 0.13.2 2019-01-04 09:26:51 +05:30
Kovid Goyal
ed905fcf6d Add a new `copy_or_interrupt action that can be mapped to kbd:ctrl+c`. It will copy if there is a selection and interrupt otherwise
Fixes #1286
2019-01-04 09:21:29 +05:30
Kovid Goyal
50a6abaac1 Also fix move_tab to preserve existing tab order 2019-01-04 06:59:38 +05:30
Kovid Goyal
718f7e77a1 Use the current working directory of the foreground process for the *_with_cwd actions that open a new window with the current working directory. 2019-01-03 13:29:52 +05:30
Kovid Goyal
c4aeb1adba Report the current foreground processes as well as the original child process, when using kitty @ ls 2019-01-03 13:14:39 +05:30
Kovid Goyal
d9c69f0a54 Merge branch 'sentexttab' of https://github.com/grimpy/kitty 2019-01-01 18:29:10 +05:30
Jo De Boeck
5afdbbe6f1 Add match-tab for send-text
Signed-off-by: Jo De Boeck <deboeck.jo@gmail.com>
2019-01-01 14:39:28 +02:00
Kovid Goyal
4273cb35bf Linux: Dont fail on systems with fonts that have non-UTF-8 names. Fixes #1281 2018-12-31 07:31:17 +05:30
Kovid Goyal
89be7a031d Fix #1278 2018-12-30 15:22:05 +05:30
Kovid Goyal
06c5127856 Fix #1275 2018-12-29 08:08:24 +05:30
Kovid Goyal
fd298256d7 Merge branch 'more_switch_cases' of https://github.com/Luflosi/kitty 2018-12-28 14:57:18 +05:30
Luflosi
e0246044b7 Add remaining momentum scroll phases to switch statement
According to https://developer.apple.com/documentation/appkit/nsevent/1533550-phase the momentum phase may end with "cancelled" instead of "ended"
2018-12-28 09:03:16 +01:00
Kovid Goyal
2f677990b2 Fix glfwSetGamma generating ramps of invalid sizes
3531c320af
2018-12-28 08:19:17 +05:30
Kovid Goyal
da2e4c8503 ... 2018-12-28 08:14:08 +05:30
Kovid Goyal
a1eb236616 Fix glfwGetGammaRamp error handling
751c6f9a27
2018-12-28 08:13:28 +05:30
Kovid Goyal
11186735c2 Couple of trivial commits from glfw upstream
064dfaa549
751c6f9a27
2018-12-28 08:06:26 +05:30
Kovid Goyal
a038f62a5b Fix #1272 2018-12-28 07:52:29 +05:30
Kovid Goyal
f45acc055e Merge branch 'more_event_phases' of https://github.com/Luflosi/kitty 2018-12-28 07:45:43 +05:30
Luflosi
43a25c49c4 Micro optimization 2018-12-27 15:19:22 +01:00
Luflosi
e47e2b2560 Move check for zero scroll distance to scroll_event() 2018-12-27 15:17:18 +01:00
Luflosi
7652065134 Add more momentum scroll phases 2018-12-27 15:12:57 +01:00
Kovid Goyal
d0da418e49 ... 2018-12-27 08:19:06 +05:30
Kovid Goyal
77e72cfd9a Fix #1270 2018-12-27 08:05:31 +05:30
Kovid Goyal
7b2ecb0498 Forgot a break 2018-12-27 08:02:24 +05:30
Kovid Goyal
318c5bca67 Merge branch 'fix_bitshift' of https://github.com/Luflosi/kitty 2018-12-27 07:57:46 +05:30
Luflosi
d52da934ca Fix typo in bitshift 2018-12-26 22:47:23 +01:00
Kovid Goyal
21951e3668 Add explicit default case 2018-12-26 20:39:39 +05:30
Kovid Goyal
64bef38813 macOS: Fix momentum scrolling continuing when changing the active window/tab
Fixes #1267
2018-12-26 20:39:04 +05:30
Kovid Goyal
fe67e3dde7 Cocoa: Remove subclassing of NSApplication
From upstream: 88c5edb409
2018-12-26 12:29:38 +05:30
Kovid Goyal
fc5e74e457 Report momentum scrolling status of scroll events on cocoa 2018-12-26 11:03:36 +05:30
Kovid Goyal
fdbd8df7b2 Add patch from upstream to report caps lock key presses on cocoa
c4903d9267
2018-12-26 10:01:02 +05:30
Kovid Goyal
246972b59f Add a patch from upstream, altered to not change behavior 2018-12-26 09:58:12 +05:30
Kovid Goyal
6057296499 Cocoa: Move to modern Objective-C literals 2018-12-26 09:45:24 +05:30
Kovid Goyal
b4b2207b93 Merge branch 'issue_1176' of https://github.com/daniel-pfeiffer/kitty
Add a FAQ entry about terminfo and sudo/su
2018-12-25 08:48:57 +05:30
Kovid Goyal
b881364c50 Merge branch 'mouse_scroll_acceleration_alternate_screen_mode' of https://github.com/Luflosi/kitty 2018-12-23 20:41:48 +05:30
Luflosi
76059882c4 Allow for scrolling acceleration in alternate screen mode when using low-resolution input devices like mice 2018-12-23 14:37:50 +01:00
Kovid Goyal
be71f5f1f4 Merge branch 'fix_downward_scrolling' of https://github.com/Luflosi/kitty 2018-12-23 17:25:46 +05:30
Luflosi
021dfcad39 Fix broken downward scrolling 2018-12-23 12:49:00 +01:00
Kovid Goyal
4e7498b854 Fix using the `new_tab !neighbor` action changing the order of the non-neighboring tabs
Fixes #1256
2018-12-23 08:45:34 +05:30
Kovid Goyal
494035c94b remove redundant code 2018-12-23 08:15:57 +05:30
Kovid Goyal
9c4230ad9c Add a comment for why we reset SIGPIPE 2018-12-20 09:29:09 +05:30
Kovid Goyal
056c2c12bb Explicitly reset the SIGPIPE handler in child processes
Fixes #1253
2018-12-20 09:06:21 +05:30
Kovid Goyal
a97c440872 Merge branch 'fix-resize-window-doc' of https://github.com/eepp/kitty 2018-12-20 05:50:37 +05:30
Kovid Goyal
653d823175 Merge branch 'doc-change-font-size-current' of https://github.com/eepp/kitty 2018-12-20 05:49:16 +05:30
Daniel Pfeiffer
c2a2dbc88c Help others avoid issue 1176. 2018-12-20 00:31:57 +01:00
Philippe Proulx
77492d31cf change_font_size current ... changes the current OS window's font size
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
2018-12-19 11:51:05 -05:00
Philippe Proulx
aaa609109e Fix resize_window documentation example
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
2018-12-19 11:34:15 -05:00
Kovid Goyal
2367fad90b Merge branch 'resize-window-cfg' of https://github.com/eepp/kitty 2018-12-19 11:05:31 +05:30
Kovid Goyal
aaa521bd24 Merge branch 'sigint' of https://github.com/jacwah/kitty 2018-12-19 10:07:11 +05:30
Philippe Proulx
d22686da10 Add resize_window configuration action
This patch adds the `resize_window` configuration action, which has the
following arguments:

1. Quality of resize amongst `wider`, `narrower`, `taller`, and
   `shorter` (mandatory).
2. Increment in number of cells (optional, default: 1).

This makes it possible to configure keys as such:

    map ctrl+shift+left resize_window narrower
    map ctrl+shift+right resize_window wider
    map ctrl+shift+up resize_window taller
    map ctrl+shift+down resize_window shorter

and have a behaviour which is somewhat close to Terminator's.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
2018-12-18 20:33:21 -05:00
Jacob Wahlgren
48b93ab28f macOS: Exit on SIGINT
With the default macos_quit_when_last_window_closed no setting, Kitty
would not exit when receiving a SIGINT signal (e.g. from Ctrl-C).
2018-12-19 01:52:47 +01:00
Kovid Goyal
703a1b83a8 macOS: Fix scrolling very slowly with wheel mice not working
Fixes #1238
2018-12-18 11:15:22 +05:30
Kovid Goyal
c9441bd3e2 Add a changelog entry for the dock menu item 2018-12-18 11:00:07 +05:30
Kovid Goyal
9de6d619ee Merge branch 'dockmenu' of https://github.com/jacwah/kitty
Fixes #1242
2018-12-18 10:59:13 +05:30
Jacob Wahlgren
9aae31ef2f macOS: Add "New OS Window" to dock menu
Discussed in #1242.
2018-12-17 23:53:43 +01:00
Kovid Goyal
dca04c549b Forgot to regenerate keys table with plus key. Fixes #1246 2018-12-18 03:03:35 +05:30
Kovid Goyal
69e76d6eeb Frogot to ad dplus key to _glfwGetKeyName 2018-12-17 21:16:57 +05:30
Kovid Goyal
b4a93c67c9 + key change also works on macOS apparently 2018-12-17 13:57:20 +05:30
Kovid Goyal
f098e6c973 Use -std=c11 when building
This is needed for harfbuzz 2.0 on macOS. -std=c11 was supported as of
gcc 4.7 released in 2014. So hopefully this wont break compilation on any
systems otherwise capable of running kitty. Fixes #1196
2018-12-17 08:41:06 +05:30
Kovid Goyal
f8ebba3954 Fix changing cursor_text_color via remote control not working
Fixes #1229
2018-12-16 17:12:49 +05:30
Kovid Goyal
37ee693de2 Fix Private use Unicode area characters followed by spaces at the end of text not being rendered correctly
Fixes #1210
2018-12-16 13:10:47 +05:30
Kovid Goyal
f77ad2b41d Add a couple of extra lib names for libstartup-notification.so
Fixes #1235
2018-12-14 23:01:49 +05:30
Kovid Goyal
e99eb2e72b Handle malformed tab title templates gracefully 2018-12-13 13:43:22 +05:30
Kovid Goyal
86b89072f3 ... 2018-12-13 13:35:17 +05:30
Kovid Goyal
022bee0560 Add a new option tab_title_template to control how tab titles are formatted.
In particular the template can be used to display the tab number next to the title
Merge branch 'tab-title-index' of https://github.com/nerdrew/kitty
2018-12-13 13:33:06 +05:30
Andrew Lazarus
204ea44946 add option to show tab index in tab_bar title 2018-12-12 23:21:08 -08:00
Kovid Goyal
3f2489b306 Linux: Handle keyboards with a "+" key
Adds a plus key to glfw so that it can be mapped as a shortcut. Fixes #1224
2018-12-13 09:56:30 +05:30
Kovid Goyal
291a2d6295 Merge branch 'kitten-stdin-docs' of https://github.com/nerdrew/kitty 2018-12-12 23:07:48 +05:30
Andrew Lazarus
b244d13e8a update docs for kitten STDIN 2018-12-12 09:20:41 -08:00
Kovid Goyal
b33324d07c Merge branch 'patch-1' of https://github.com/voxadam/kitty 2018-12-12 17:41:18 +05:30
Adam Hunt
ae2a641db5 Typo 2018-12-12 03:43:08 -08:00
Kovid Goyal
1cac757365 Merge branch 'yk-terminfo' of https://github.com/yurikhan/kitty 2018-12-12 06:26:45 +05:30
Yuri Khan
992de77040 Declare more function and editing keys with modifiers
Resolves #1220.
2018-12-11 23:42:59 +07:00
Kovid Goyal
f6b5e54890 Fix failing test 2018-12-11 10:08:52 +05:30
Kovid Goyal
d20c65ef80 Graphics protocol: Only delete temporary image-data files if they are in a known temporary file location 2018-12-11 10:00:43 +05:30
Kovid Goyal
4a8562a85f Fix setting background_opacity causing window margins/padding to be slightly different shade from background
Fixes #1221
2018-12-11 08:36:03 +05:30
Kovid Goyal
1ba7b5f5a3 version 0.13.1 2018-12-06 13:23:33 +05:30
Kovid Goyal
f895b7f8cb ... 2018-12-06 13:19:58 +05:30
Kovid Goyal
16542e96bf Fix resizing window smaller and then restoring causing some wrapped lines to not be properly unwrapped
Fix #1206
2018-12-06 12:56:24 +05:30
Kovid Goyal
3005b8b9d6 ... 2018-12-06 11:05:11 +05:30
Kovid Goyal
35653ef4b4 Linux: Fix a regression in the previous release that caused automatic selection of fonts when using aliases such as "monospace" to not work
Fix #1209
2018-12-06 08:42:13 +05:30
Kovid Goyal
36b3582825 Fix passing input via the pipe action to a program without a window not working. 2018-12-06 08:20:25 +05:30
Kovid Goyal
c17c801a31 Detect URL when clicking to activate URL
Makes the case where the screen contents have changed
between the last mouse move and the click work. See #1203
2018-12-05 14:43:01 +05:30
Kovid Goyal
460c353898 version 0.13.0 2018-12-05 14:21:26 +05:30
Kovid Goyal
3fa7007e91 Use the Wu line anti-alias algorithm for drawing undercurls
Fixes #853
2018-12-05 14:02:21 +05:30
Kovid Goyal
4cf6373203 Generate OpenGL bindings with updated glad
See #1179
2018-12-04 16:31:26 +05:30
Kovid Goyal
e0b3bb1830 Move URL parser enum into parser function 2018-12-04 06:59:03 +05:30
Kovid Goyal
47ec372c30 Fix hover detection of URLs not working when hovering over the first colon and slash characters in short URLs
Fixes #1201
2018-12-04 06:52:26 +05:30
Kovid Goyal
d5366a421f ... 2018-12-03 21:35:03 +05:30
Kovid Goyal
3d5977669e Micro optimization 2018-12-03 20:04:58 +05:30
Kovid Goyal
36da668e6f Forgot to fill bitmap offset data when rendering colored glyphs 2018-12-03 20:00:24 +05:30
Kovid Goyal
052913c656 Merge branch 'typo' of https://github.com/Luflosi/kitty 2018-12-03 15:38:18 +05:30
Luflosi
0ef055a2b2 Fix typo in docs 2018-12-03 10:58:23 +01:00
Kovid Goyal
a7bd6922e5 Follow xterm's behavior for the menu key
Fixes #597
Also generate the modified variants of the function keys.
2018-12-03 14:04:26 +05:30
Kovid Goyal
8d9ba4a772 Handle ctrl-c while paging help gracefully 2018-12-03 13:53:13 +05:30
Kovid Goyal
222beedc2a Fix freetype based rendering of non-hinted fonts at small sizes
Now use the post hinting bitmap bearing values instead of the hinting
independent glyph metrics bearing values. Fixes #1173
2018-12-02 14:12:46 +05:30
Kovid Goyal
8ba8320189 Disable brew based build since harfbuzz is currently broken in brew 2018-12-02 14:08:35 +05:30
Kovid Goyal
3501a2a1da ... 2018-12-02 13:52:06 +05:30
Kovid Goyal
819ee94a70 Merge branch 'reset_osc' of https://github.com/martinetd/kitty 2018-11-30 13:52:42 +05:30
Kovid Goyal
7e7dbc5ecf Merge branch 'history_crash' of https://github.com/martinetd/kitty 2018-11-30 13:45:27 +05:30
Dominique Martinet
3a6bc94d25 pager history: fix bufsize calculation
bufsize was bigger than the actual allocated memory

Fixes: b9e6557f72 ("Allow arbitrary sized lines in the secondary scrollback buffer")
2018-11-30 16:06:05 +09:00
Dominique Martinet
07a4cec616 reset terminfo: add an empty OSC sequence to rs1 string
In OSC/OTH mode, the parser accumulate bytes until it fills up or
encounters some end-of-osc sequence.
After entering in either of these mode by mistake, for example by
displaying random bytes (e.g. cat a binary) nothing would print anymore
but input would still work.

In that situation, being able to hit `reset` and recover a usable
terminal helps.

You can try with `echo -e '\xc2\x9e'` for PM
2018-11-30 15:51:38 +09:00
Kovid Goyal
60de840d69 Merge branch 'selection_wide_hilight' of https://github.com/martinetd/kitty 2018-11-30 09:27:05 +05:30
Kovid Goyal
928167c0b2 Merge branch 'x11_selection_timeout' of https://github.com/martinetd/kitty
Fixes #1042
2018-11-30 09:20:44 +05:30
Dominique Martinet
2aac220cdb selection: hilight 2nd half of wide characters last in line 2018-11-30 11:50:26 +09:00
Dominique Martinet
d8a74e8a3c glfw/x11_window/selection: timeout if no answer for two seconds
This prevents kitty to hang forever if a bad client does not give selection
2018-11-30 11:42:45 +09:00
Kovid Goyal
019e6efeda Reduce overlap with text when rendering wavy underline at small font sizes 2018-11-27 07:19:30 +05:30
Kovid Goyal
a7a7216b30 Allow adding line wrap markers when piping screen contents
Also make some data such as scroll position, cursor position and screen
geometry available via an env var when piping. See #719
2018-11-26 13:30:03 +05:30
Kovid Goyal
ae8ca5272b ... 2018-11-25 11:51:40 +05:30
Kovid Goyal
06c1236cc6 Merge branch 'master' of https://github.com/bodqhrohro/kitty 2018-11-23 23:01:42 +05:30
bodqhrohro
4d3982c5cf Fix memory leak on compose table creation 2018-11-23 19:04:09 +02:00
Kovid Goyal
a0ff625f61 When double or triple clicking ignore clicks if they are "far" from each other
Fixes #1093
2018-11-23 11:46:02 +05:30
Kovid Goyal
b44345d78e Ignore failures to update the NSGL layer
Fixes #1168
2018-11-22 18:25:22 +05:30
Luflosi
96229becd1 Make final_color computation consistent across cases 2018-11-22 11:36:29 +01:00
Kovid Goyal
b269cab0b8 Fix unused function on macOS 2018-11-22 15:49:01 +05:30
Kovid Goyal
0b3c8210f3 Various Wayland DPI scaling fixes
Use the glfw window content scale api to get the DPI for windows.
Likely, more accurate than our logic to find the overlapping monitor
to get the DPI.

Also, after a DPI change event send a fake resize event to workaround
render surface not being properly updated.

Fixes #1143
2018-11-22 15:37:33 +05:30
Kovid Goyal
074614bc8e Fix incorrect text-antialiasing when using very low background opacity
Fix #1005
2018-11-22 10:26:40 +05:30
Kovid Goyal
4ceb4cfc22 Fix a crash if the client program tries to restore more modes than it saves
Fixes #1166
2018-11-22 08:57:43 +05:30
Kovid Goyal
0bb08d8bdd When parsing OSC 52 clipboard control codes, handle an empty control parameter
This is apparently used by tmux. See #782
2018-11-21 19:37:39 +05:30
Kovid Goyal
b9e6557f72 Allow arbitrary sized lines in the secondary scrollback buffer 2018-11-21 17:55:43 +05:30
Kovid Goyal
7ed268ea2f Refactor some code into a style I like 2018-11-21 10:54:25 +05:30
Kovid Goyal
a91b3b9487 Revert addition of RGB to terminfo
See discussion 18fe2e8dfa
2018-11-21 10:33:55 +05:30
Kovid Goyal
cdf236d01b Fix #1161 2018-11-21 10:12:05 +05:30
Kovid Goyal
f54efb7886 Merge branch 'asan-launcher.dSYM' of https://github.com/Luflosi/kitty 2018-11-20 22:37:56 +05:30
Luflosi
0ffee56170 Ignore asan-launcher.dSYM directory 2018-11-20 16:03:34 +01:00
Kovid Goyal
ab97646576 Have line_as_ansi indicate when the output is truncated 2018-11-20 11:13:49 +05:30
Kovid Goyal
33b62dcabc Turn on the scrollback pager for all tests 2018-11-20 10:42:17 +05:30
Kovid Goyal
39e6e91d69 Port new coca drag'n drop code from upstream 2018-11-20 10:24:55 +05:30
Kovid Goyal
dedd80c6b5 Fix #1157 2018-11-20 08:51:45 +05:30
Kovid Goyal
df11da74e9 Fix #1156 2018-11-20 08:49:07 +05:30
Kovid Goyal
9991dd6ce4 Generate hash based .pyc files when building
Fixes #1155
2018-11-20 08:42:08 +05:30
Kovid Goyal
e777364f91 Add secondary pager history when requesting history for pipe or @ commands 2018-11-19 19:57:15 +05:30
Kovid Goyal
a32ed5ae5f Avoid creating lots of newline string objects in pagerhist 2018-11-19 12:11:04 +05:30
Kovid Goyal
db1e48848d More robust no modifier check for CSI parsing 2018-11-19 09:53:01 +05:30
Kovid Goyal
c02fa79591 Fix #1153 2018-11-19 09:35:46 +05:30
Kovid Goyal
6f0a59c696 If a permission error occurs creating the kitty config directory use a temp dir as the config directory. Fixes #1152 2018-11-18 20:02:55 +05:30
Kovid Goyal
bc715d4348 Merge branch 'fix-set-background-opacity' of https://github.com/kdarkhan/kitty 2018-11-17 16:01:33 +05:30
Darkhan Kubigenov
55e4761302 Fix set_background_opacity with increment/decrement 2018-11-17 15:21:42 +06:00
Kovid Goyal
18fe2e8dfa Add the new RGB boolean capability to terminfo to indicate we support truecolor
See https://gist.github.com/XVilka/8346728#detection
2018-11-15 13:59:15 +05:30
Kovid Goyal
18a07a78b5 Move the os window clearing into render_os_window
Makes more sense to clear the buffer immediately before rendering rather
than immediately after swapping.
2018-11-14 12:11:26 +05:30
Kovid Goyal
aa7024b264 Bump required version of wayland protocols 2018-11-14 09:16:14 +05:30
Kovid Goyal
c67ab2a6ff ... 2018-11-14 09:01:51 +05:30
Kovid Goyal
d15eab31da Merge branch 'master' of https://github.com/tarmack/kitty 2018-11-14 09:01:22 +05:30
Tarmack
a6900443d5 Wayland primary selection migrated to unstable protocol
This change is actually backwards compatible with the GTK implementation before.
2018-11-13 20:58:02 +01:00
Kovid Goyal
235bcacc7b Make the buffer clearing more robust
Now happens immediately after the buffer is swapped. Fixes #1104
2018-11-13 20:59:39 +05:30
Kovid Goyal
3e26f96744 Add some common synonyms for unicode word searching
Fixes #1133
2018-11-13 15:46:33 +05:30
Kovid Goyal
718111582a Fix #1136 2018-11-12 09:15:41 +05:30
Kovid Goyal
f5cdbe53ea Merge branch 'patch-3' of https://github.com/maximbaz/kitty 2018-11-11 21:38:39 +05:30
Maxim Baz
bf761a7189 Fix typo in changelog 2018-11-11 13:04:53 +01:00
Kovid Goyal
05ee01b4dd Merge branch 'scroll-wayland' of https://github.com/maximbaz/kitty 2018-11-11 12:03:39 +05:30
Kovid Goyal
53166d659e Consolidate options for hiding window decorations
Merged into a single option, hide_window_decorations. Old
aliases still work if set to yes.

Fixes #1127
2018-11-11 11:56:44 +05:30
Kovid Goyal
34aea3bca1 Merge branch 'hints-add-trailing-space' of https://github.com/maximbaz/kitty 2018-11-11 11:03:11 +05:30
Maxim Baz
f26519863f Don't include --progam in the condition 2018-11-10 13:24:39 +01:00
Maxim Baz
a57e96500a hints: optionally add trailing space 2018-11-10 13:19:40 +01:00
Maxim Baz
5e27c21856 Implement touch_scroll_multiplier 2018-11-10 12:33:47 +01:00
Kovid Goyal
4601cd13dc icat kitten: Implement reading image data from STDIN, if STDIN is not connected to a terminal
Fixes #1130
2018-11-10 12:31:09 +05:30
Kovid Goyal
ad92541ff3 Merge branch 'microoptimization' of https://github.com/Luflosi/kitty 2018-11-10 10:50:03 +05:30
Maxim Baz
3f77a2044e Make high resolution scrolling more responsive and configurable 2018-11-09 13:22:03 +01:00
Luflosi
75e57a48e0 Microoptimisation 2018-11-09 10:19:42 +01:00
Kovid Goyal
160fbd2071 Add a terminfo entry for full keyboard mode
Fixes #1122
2018-11-05 08:11:35 +05:30
Kovid Goyal
f5743f4610 Forgot to multiply xscale 2018-11-05 07:56:33 +05:30
Kovid Goyal
82f9aecacb macOS: Fix touch scrolling sensitivity low on retina screens
Fixes #1112
2018-11-04 12:07:55 +05:30
Kovid Goyal
be6556c884 X11: Fix missing check for NET_WM_STATE 2018-11-04 10:20:38 +05:30
Kovid Goyal
f941ffb1fe Merge branch 'document-ctrl-l' of https://github.com/maximbaz/kitty 2018-11-04 10:04:39 +05:30
Maxim Baz
cbdba0b6aa Document how to achieve alternative behavior for Ctrl+L, ref #1113 2018-11-03 20:29:40 +01:00
Kovid Goyal
ce04f102a7 Technically, scroll_until_empty is scroll_until_cursor 2018-11-03 14:23:50 +05:30
Kovid Goyal
fc3bd2d15f Add an action to the `clear_terminal` function to scroll the screen contents into the scrollback buffer
Now if you want to map a key combination that will both scroll the
current screen contents into the scrollback buffer and clear the screen,
you can do something like:

map ctrl+l combine : clear_terminal scroll active : send_text normal,application \x0c

Fixes #1113
2018-11-03 14:18:09 +05:30
Kovid Goyal
a958cabf01 Fix :kbd:ctrl+shift+special key not working in normal and application keyboard modes
Fixes #1114
2018-11-03 09:03:50 +05:30
Kovid Goyal
d0a2eab79e ... 2018-11-02 12:47:13 +05:30
Kovid Goyal
b835afefee Merge branch 'fix-grid-neighbors' of https://github.com/strix/kitty 2018-11-02 10:32:27 +05:30
Brance Boren
d0a7be90f9 Fixed call to Tall.neighbors_for_window 2018-11-01 14:55:13 -06:00
Kovid Goyal
1f3550b84c ... 2018-11-01 07:55:29 +05:30
Kovid Goyal
939212e1d4 Update changelog 2018-10-31 16:11:45 +05:30
Kovid Goyal
7db6318806 Only warn about failure to primary select once 2018-10-31 09:09:46 +05:30
Kovid Goyal
e5d9182606 Since we now have primary selections on wayland, remove it from the click_on_select option's description 2018-10-31 09:04:55 +05:30
Tarmack
d519553581 Implement primary selection for Wayland 2018-10-31 09:03:22 +05:30
Kovid Goyal
e99b1be023 macOS: Ensure stored mouse position is correct when switching to a kitty window
Fixes #1103
2018-10-31 08:38:50 +05:30
Kovid Goyal
e460866ebc Make the bounds check cleaner 2018-10-30 15:02:48 +05:30
Kovid Goyal
23aea68e32 Fix second cell of emoji created using variation selectors not having the same attributes as the first cell
Fix #1109
2018-10-30 15:00:47 +05:30
Kovid Goyal
65c2cbe93a Merge branch 'adjust_column_width_frac' of https://github.com/jjrams/kitty 2018-10-30 11:49:58 +05:30
Kovid Goyal
ee31ba0c76 Merge branch 'multi-pua' of https://github.com/blueyed/kitty 2018-10-30 11:49:05 +05:30
Kovid Goyal
3ed9d9a069 Merge branch 'system_double_click_interval' of https://github.com/Luflosi/kitty 2018-10-28 11:18:43 +05:30
jjrams
721e51c117 Fix typo when using adjust_column_width_frac 2018-10-27 12:24:37 -07:00
Luflosi
09daaf1ec3 Change click_interval default to -1.0 and add help text for negative click_interval values 2018-10-27 17:55:16 +02:00
Kovid Goyal
b2d62f10d2 Dont send frame requests is sync_to_monitor is disabled 2018-10-27 14:04:14 +05:30
Kovid Goyal
0d542b2f60 ... 2018-10-27 13:32:16 +05:30
Kovid Goyal
04fd058e0f Wayland: Improve FPS for rendering with vsync
Now a new frame event is requested after every render. This means
that effective FPS should be close to the refresh rate of the output
source.
2018-10-27 12:33:48 +05:30
Kovid Goyal
31a0a9427e ... 2018-10-27 11:35:25 +05:30
Kovid Goyal
04f10ba570 Fix leak of Wayland callback structure when doing a copy 2018-10-27 11:34:54 +05:30
Kovid Goyal
34b7b2e4e8 Move to using upstream glfw fix for mojave initial render issue 2018-10-26 22:29:05 +05:30
Luflosi
09183772d3 Respect the default system double-click interval 2018-10-26 11:57:33 +02:00
Kovid Goyal
3e4eca5816 Wayland: Fix cursor being reset continuously
Should only do that if the cursor is actually supposed to be animated.
2018-10-26 11:23:34 +05:30
Kovid Goyal
30c6c4697f Merge branch 'x11_enter' of https://github.com/martinetd/kitty 2018-10-26 10:26:10 +05:30
Kovid Goyal
b650275d45 Wayland: Fix copying from hidden kitty windows hanging
Fix #1051
2018-10-26 10:25:08 +05:30
Kovid Goyal
174bd5c57f Commit the wl_surface to ensure that we receive the frame event 2018-10-26 10:12:54 +05:30
Dominique Martinet
ec51a219a7 glfw x11: update cursor position on enter event
kitty would have an incorrect position when clicking after changing window
without moving (e.g. change workspace, create new kitty etc)

For new kitty window, initial position would be 0 and selection paste would
not work because of this
2018-10-26 13:19:12 +09:00
Kovid Goyal
cca2fb967c Avoid malloc for frame callbacks 2018-10-26 08:49:17 +05:30
Kovid Goyal
5b547d9b06 Initial attempt at supporting Wayland frame events
Does not actually work because the wayland frame callback is not called
at all, fo rsome reason I cannot determine.
2018-10-26 07:42:57 +05:30
Luflosi
facb2df3f6 Merge branch 'master' of github:kovidgoyal/kitty into system_double_click_interval 2018-10-25 13:18:43 +02:00
Kovid Goyal
8395076da5 Cocoa: Cleanup
From upstream
2018-10-25 10:32:17 +05:30
Kovid Goyal
e113e0cba7 Allow hiding the tab bar completely, by setting :opt:tab_bar_style to `hidden`.
Fixes #1014
2018-10-25 10:05:43 +05:30
Kovid Goyal
407d19c2dc Remove code to import/export from glfw
Since kitty now uses its own private fork, there is no point.
2018-10-24 14:18:01 +05:30
Luflosi
382367506a [WIP] Respect the default system click_interval 2018-10-24 10:44:24 +02:00
Kovid Goyal
bd5a85a4e7 Fix compilation on ancient linux distros 2018-10-24 08:40:25 +05:30
Kovid Goyal
631f97eb26 Linux: Fix a crash when using the GNU Unifont as a fallback font
Fixes #1087
2018-10-24 08:20:37 +05:30
Kovid Goyal
0c0ce4844c Dont use deprecated FT_Bitmap_New 2018-10-24 07:07:57 +05:30
Kovid Goyal
6bf290149e Allow specifying monospace when calling fc_match 2018-10-24 06:45:06 +05:30
Kovid Goyal
60fa812b60 ... 2018-10-24 06:36:30 +05:30
Kovid Goyal
61f3a39aa0 macOS: Fix incorrect text sizes calaculated when using an external display that is set to mirror the main display
Fix #1056
2018-10-24 06:28:58 +05:30
Kovid Goyal
a6949df727 Linux: Fix match rules used as aliases in Fontconfig configuration not being respected
Fixes #1085
2018-10-23 12:22:18 +05:30
Kovid Goyal
d839a31d7f oops forgot to convert poll timeout to milliseconds 2018-10-23 11:26:37 +05:30
Kovid Goyal
1de510f46f poll at zero timeout as well 2018-10-23 11:09:38 +05:30
Kovid Goyal
0359bbe4be ... 2018-10-23 11:08:13 +05:30
Kovid Goyal
40b355e593 macOS: Fix rendering frames-per-second very low when processing large amounts of input in small chunks
We do this by debouncing wakeup events sent to the main loop by the I/O
thread. Use in the input_delay time to debounce. Apparently processing
wakeup events is very expensive in Cocoa.

Fixes #1082
2018-10-23 10:27:56 +05:30
Kovid Goyal
adf9c4fc5f Remove unused var 2018-10-23 09:05:56 +05:30
Kovid Goyal
ae9d049011 Better fix for initial window render failure on mojave 2018-10-23 09:04:12 +05:30
Kovid Goyal
d24977d164 Disabe brew python upgrade since it is failing for some reason on Travis 2018-10-23 08:35:55 +05:30
Kovid Goyal
3035d64127 Forgot to apply sendEvent micro-optimization to a couple more places 2018-10-23 08:00:20 +05:30
Kovid Goyal
70c9c058e2 Micro-optimization of cocoa event polling 2018-10-21 20:56:27 +05:30
Kovid Goyal
1d9f73adec ... 2018-10-21 20:30:31 +05:30
Kovid Goyal
fca95af49b macOS: Fix IME input for east asian languages
Fix #910
2018-10-21 20:27:03 +05:30
Kovid Goyal
62fe392041 Handle overlay windows when recording window history 2018-10-21 11:56:23 +05:30
Kovid Goyal
097d11819b Add a new `nth_window action that can be used to go to the nth window and also previously active windows, using negative numbers. Similarly, goto_tab` now accepts negative numbers to go to previous windows
Fix #1040
2018-10-21 10:59:06 +05:30
Kovid Goyal
691286f376 Add a minimal example for a python script to display PNG images
See #1080
2018-10-21 07:48:31 +05:30
Kovid Goyal
c910f6c832 When using --debug-keyboard also output matched action for keypresses, if any. Fixes #1021 2018-10-20 14:08:33 +05:30
Kovid Goyal
65f9ac32ef Fix :opt:mouse_hide_wait only taking effect after an event such as cursor blink or key press
Fixes #1073
2018-10-20 14:01:55 +05:30
Kovid Goyal
27f2a2e3d5 Merge branch 'filter_tic_output' of https://github.com/Luflosi/kitty 2018-10-18 18:43:57 +05:30
Luflosi
88aab20376 Loop through lines of tic output to correctly handle multiple lines 2018-10-18 12:25:19 +02:00
Luflosi
a045ac3bd7 Decode tic stderr using utf-8 2018-10-18 12:15:37 +02:00
Kovid Goyal
722b605407 Merge branch 'fix_typo_in_scrollback_lines_docs' of https://github.com/Luflosi/kitty 2018-10-18 10:47:22 +05:30
Kovid Goyal
7f53745077 Fix #1062 2018-10-18 08:30:47 +05:30
Kovid Goyal
7f902c4c03 Fix expansion of env vars not working in the :opt:env directive
Fixes #1075
2018-10-18 08:12:10 +05:30
Luflosi
1205c2055f Fix typo in scrollback_lines docs 2018-10-16 14:41:11 +02:00
Luflosi
f08f0f9dbd Filter tic output to remove "older tic versions may treat the description field as an alias" 2018-10-15 17:17:12 +02:00
Kovid Goyal
093c05e16a When running kitty @ ls also output the current layout for each tab 2018-10-12 18:19:50 +05:30
Kovid Goyal
787100a4dc Modify the kittens sub-system to allow creating custom kittens without any user interface.
See #870
2018-10-12 18:09:37 +05:30
Kovid Goyal
c493583f25 macOS: Fix drag and drop of files not working on mojave
Fixes #1058
2018-10-11 18:36:24 +05:30
Kovid Goyal
b4afbe47b3 wayland: add support for XCURSOR_THEME and XCURSOR_SIZE
These can be set by the compositor or the user to configure the
xcursor theme and size.
2018-10-11 13:39:44 +05:30
Kovid Goyal
6c4aeeeadd ... 2018-10-10 09:39:53 +05:30
Kovid Goyal
5b01519367 Merge branch 'fix-wl-key-repeat' of https://github.com/tarmack/kitty 2018-10-09 18:22:45 +05:30
Tarmack
c494759606 Divide a second over the key repeat Hz value for the timer value 2018-10-09 14:30:36 +02:00
Kovid Goyal
2102c48b87 Mir: Remove this experimental backend
As of the release of Mir 1.0, libmirclient has been deprecated[1] and
its developers recommend clients using it to switch to Wayland.  This
patch removes support for libmirclient and instruct users to use the
experimental Wayland backend instead.

[1] https://discourse.ubuntu.com/t/mir-news-28th-september-2018/8184
2018-10-06 07:53:41 +05:30
Kovid Goyal
c498f4e8ab Linux: Include the null byte in joystick path
This potential bug was found thanks to gcc 8’s -Wstringop-truncation
warning.
2018-10-06 07:49:59 +05:30
Kovid Goyal
05a0166ebd Forgot some mojave substitutions 2018-10-03 22:03:49 +05:30
Kovid Goyal
0484365de6 More fixes for compiling on mojave 2018-10-03 21:50:39 +05:30
Kovid Goyal
cbab3b56de Fixes for compilation on mojave, needs testing 2018-10-03 20:51:25 +05:30
Kovid Goyal
715f7985c7 Fix the `*_with_cwd` actions using the cwd of the overlay window rather than the underlying window's cwd
Fix #1045
2018-10-03 19:26:01 +05:30
Kovid Goyal
2637018b53 Handle broken pipe errors during test compile 2018-10-03 12:46:08 +05:30
Kovid Goyal
1fa66ca45d Wayland: Rename handlers for more unicity 2018-10-03 12:30:48 +05:30
Kovid Goyal
13b10f691d Wayland: Add support for xdg-decoration
This allows compositors which prefer to draw the decorations around
clients to do so, rather than letting GLFW draw its own decorations.
The appearance is thus entirely subject to the compositor used, but
should generally be better than the current solid colour decorations we
have, which we continue to use when the compositor doesn’t support this
protocol or tells us to draw the decorations ourselves.
2018-10-03 12:27:51 +05:30
Kovid Goyal
3fe7d91713 Add some needed includes 2018-10-03 11:06:01 +05:30
Kovid Goyal
98864091ff Move memfd existence test to glfw.py 2018-10-03 11:02:51 +05:30
Kovid Goyal
7750a461aa Fix compilation on systems that dont have the memfd_create syscall 2018-10-03 10:56:47 +05:30
Kovid Goyal
ac98b85157 Wayland: Use memfd_create() and seals if available
This allows the compositor to avoid having to setup and teardown a
SIGBUS signal handler whenever it needs to read from this surface, as it
knows we won’t be able to shrink the file and so doesn’t have to protect
against that.

Only enabled on Linux, since only Linux has memfd_create()
2018-10-03 09:47:04 +05:30
Kovid Goyal
21f6c6a5a8 Wayland: Check for buffer creation failure
This prevents unusable decoration objects from being created, and
invalid cursors from being returned to the user.
2018-10-02 11:30:13 +05:30
Kovid Goyal
b8d1491b99 Merge branch 'pipe-scrollback-secondary-screen' of https://github.com/maximbaz/kitty 2018-10-01 06:47:34 +05:30
Maxim Baz
d9c168d824 Account for secondary screen not having history buffer 2018-09-30 16:45:24 +02:00
Maxim Baz
ee7f4ee1a4 Don't guard against alternate_screen in as_text
Complementary to 15f534a8f9
2018-09-30 14:13:17 +02:00
Kovid Goyal
ee3ce3c7d8 Move cell_as_sgr to line.c 2018-09-30 08:58:33 +05:30
Kovid Goyal
a57f38dbd5 Merge branch 'pagerhist' of https://github.com/martinetd/kitty 2018-09-30 08:41:52 +05:30
Daniel Hahler
3c4cb3c35b get_glyph_width for core text?! 2018-09-29 18:56:54 +02:00
Daniel Hahler
12cfe6d1d1 render_line: use cells based on bitmap width
[ci skip]
2018-09-29 18:38:53 +02:00
Daniel Hahler
c64e8fc434 MAX_NUM_EXTRA_GLYPHS_PUA=4 2018-09-29 16:49:40 +02:00
Kovid Goyal
15f534a8f9 Add access to secondary screen scrollback via the pipe function 2018-09-29 19:59:01 +05:30
Daniel Hahler
8e09e809aa fixup! render_glyphs_in_cells: skip centering glyph for PUA 2018-09-29 16:23:16 +02:00
Daniel Hahler
fec5a80b89 Init bm
Not sure why this became necessary though?!

Fixes:

    Linking kitty/fast_data_types ...
    kitty/freetype.c: In function ‘render_glyphs_in_cells’:
    kitty/freetype.c:514:82: warning: ‘bm.right_edge’ may be used uninitialized in this function [-Wmaybe-uninitialized]
             if (num_cells > 1 && right_edge < canvas_width && (delta = (canvas_width - right_edge) / 2) && delta > 1) {
                                                                                      ^
    kitty/freetype.c:490:21: note: ‘bm.right_edge’ was declared here
         ProcessedBitmap bm;
                         ^
2018-09-29 16:20:10 +02:00
Daniel Hahler
1d50a188c4 render_glyphs_in_cells: skip centering glyph for PUA 2018-09-29 16:19:53 +02:00
Kovid Goyal
b0d34b136f version 0.12.3 2018-09-29 09:15:40 +05:30
Kovid Goyal
7eb234c250 Move kitty.app build instructions from the FAQ to the build page 2018-09-29 08:47:30 +05:30
Daniel Hahler
d52434c0aa fixup! Handle multiple spaces after PUA glyphs
[ci skip]
2018-09-28 23:01:35 +02:00
Daniel Hahler
efc0b830cf Handle multiple spaces after PUA glyphs 2018-09-28 15:34:14 +02:00
Kovid Goyal
4a8c4c4601 Unicode input: Fix an error when searching for the string 'fir'
Fixes #1035
2018-09-28 19:01:20 +05:30
Kovid Goyal
e498cedf56 remove unused import 2018-09-27 08:52:40 +05:30
Kovid Goyal
6c8a52875e Fix #1029 2018-09-27 08:40:16 +05:30
Kovid Goyal
c1397fd366 Merge branch 'unicode_input-reverse' of https://github.com/blueyed/kitty 2018-09-27 08:35:25 +05:30
Daniel Hahler
3323ddcdef unicode_input: use reverse mode for menu selection 2018-09-26 22:50:22 +02:00
Kovid Goyal
1be394cda7 Update CHANGELOG 2018-09-26 19:54:42 +05:30
Kovid Goyal
f292092ffc ... 2018-09-26 19:47:53 +05:30
Kovid Goyal
b82e74f99a Fix for kitty window not being rendered until moved/resized on macOS Mojave
Fixes #887
2018-09-26 19:43:04 +05:30
Kovid Goyal
9b293ad66a Add some more explanation of why TERM is important 2018-09-24 09:28:21 +05:30
Dominique Martinet
618b486fd5 pager history buffer: remove dead code looking for next new line 2018-09-22 19:10:37 +09:00
Dominique Martinet
1986403e42 Add scrollback benchmark 2018-09-22 19:10:37 +09:00
Dominique Martinet
cf51f80b79 cell_as_sgr: avoid unnecessary formatting functions 2018-09-22 19:10:37 +09:00
Dominique Martinet
2fe17aa889 cursor_as_sgr now works on GPUCells becomes cell_as_sgr 2018-09-22 19:10:09 +09:00
Dominique Martinet
f76c8ad30b pager history buffer: alloc buffer progressively
Realloc buffer 1MB at a time until the configured size is reached
2018-09-22 19:10:09 +09:00
Dominique Martinet
c421d3bb59 line_as_ansi: don't reset SGR at start of line
less does not carry the mode over from the previous line anyway, let's
save a few bytes for every line
2018-09-22 19:10:09 +09:00
Dominique Martinet
3d862da2be pager history buffer: implement rewrap
rewarp the buffer the first time it is displayed after the window
changed
2018-09-22 19:10:09 +09:00
Dominique Martinet
10b15caad9 tests: add options param to create_screen()
Always apply defaults when creating a screen (the C-side global state
default will not have the intended values without this), and provide a
way to override default values with a new optional parameter
2018-09-22 18:05:13 +09:00
Dominique Martinet
e08238d5a0 pager history buffer: add config option, keep buffer on resize 2018-09-22 18:02:11 +09:00
Dominique Martinet
d0104660c8 Implement pager scrollback history buffer
For now, use big fixed-size buffer that is lost on resize
2018-09-22 18:02:11 +09:00
Dominique Martinet
a4c2a9ef0d line_as_ansi: only compute sgr if needed 2018-09-22 18:02:11 +09:00
Dominique Martinet
ee39d7ba14 line_as_ansi: remove dead undefs
CHECK_BOOL, CHECK_COLOR and WRITE_COLOR have been removed in
commit 27cd303a05 ("Centralize code to convert to SGR")
2018-09-22 18:02:11 +09:00
261 changed files with 55075 additions and 52297 deletions

104
.circleci/config.yml Normal file
View File

@@ -0,0 +1,104 @@
version: 2
jobs:
lin-sys:
docker:
- image: kovidgoyal/kitty-test:latest
steps:
- checkout
- 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: ./kitty/launcher/kitty +launch test.py
- run: make FAIL_WARN=-W man
- run: make FAIL_WARN=-W html
lin-package:
docker:
- image: kovidgoyal/kitty-test:latest
steps:
- checkout
- run: python3 setup.py linux-package --update-check-interval=0
lin-35:
docker:
- image: kovidgoyal/kitty-test:latest
environment:
CC: gcc
CFLAGS: -funsigned-char
LD_LIBRARY_PATH: /opt/py3.5/lib
ASAN_OPTIONS: leak_check_at_exit=0
steps:
- checkout
- run: /opt/py3.5/bin/python3 setup.py build --debug --verbose --sanitize
- run: ./kitty/launcher/kitty +launch test.py
lin-37:
docker:
- image: kovidgoyal/kitty-test:latest
environment:
CC: clang
LD_LIBRARY_PATH: /opt/py3.7/lib
ASAN_OPTIONS: leak_check_at_exit=0
steps:
- checkout
- run: /opt/py3.7/bin/python3 setup.py build --debug --verbose --sanitize
- run: ./kitty/launcher/kitty +launch test.py
lin-bundle:
docker:
- image: kovidgoyal/kitty-test:latest
environment:
ASAN_OPTIONS: leak_check_at_exit=0
steps:
- 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: ./kitty/launcher/kitty +launch test.py
mac-bundle:
macos:
xcode: "10.1.0"
environment:
LC_ALL: en_US.UTF-8
LANG: en_US.UTF-8
SW: /Users/Shared/buildbot/sw/sw
steps:
- checkout
- run: mkdir -p $SW
- 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: ./kitty/launcher/kitty +launch test.py
mac-brew:
macos:
xcode: "10.2.0"
environment:
LC_ALL: en_US.UTF-8
LANG: en_US.UTF-8
steps:
- checkout
- run: brew bundle
- run: python3 setup.py build --debug --verbose
- 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:
version: 2
all_jobs:
jobs:
- mac-bundle
- lin-sys
- lin-35
- lin-37
- lin-package
- lin-bundle
- mac-brew

View File

@@ -0,0 +1,55 @@
# When changing this file, go to
# https://cloud.docker.com/repository/docker/kovidgoyal/kitty-test/builds and
# click the "Trigger" button under Automated builds to rebuild
FROM ubuntu:latest
# make Apt non-interactive
ENV DEBIAN_FRONTEND=noninteractive
RUN echo 'APT::Get::Assume-Yes "true";' > /etc/apt/apt.conf.d/90circleci \
&& echo 'DPkg::Options "--force-confnew";' >> /etc/apt/apt.conf.d/90circleci \
&& echo 'Acquire::Languages "none";' >> /etc/apt/apt.conf.d/90circleci
# System setup
RUN apt-get update && mkdir -p /usr/share/man/man1 && apt-get install -y python3-flake8 python3-pip python3-pil clang git apt locales sudo openssh-client ca-certificates tar gzip parallel net-tools netcat unzip zip bzip2 gnupg curl wget build-essential apt-utils
# Setup circleci user
RUN groupadd --gid 3434 circleci \
&& useradd --uid 3434 --gid circleci --shell /bin/bash --create-home circleci \
&& echo 'circleci ALL=NOPASSWD: ALL' >> /etc/sudoers.d/50-circleci \
&& echo 'Defaults env_keep += "DEBIAN_FRONTEND"' >> /etc/sudoers.d/env_keep \
&& echo 'Defaults env_keep += "SW"' >> /etc/sudoers.d/env_keep \
&& echo 'Defaults env_keep += "LANG"' >> /etc/sudoers.d/env_keep
# Set timezone to UTC by default
RUN ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime
# Use unicode
RUN locale-gen en_US.UTF-8 || true
ENV LANG=en_US.UTF-8
# Deps needed for building python
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 libcanberra-dev
# Needed to build kitty docs
RUN pip3 install sphinx
# Install multiple pythons
ADD install-python.py /tmp/install-python.py
RUN python3 /tmp/install-python.py py3.5 https://www.python.org/ftp/python/3.5.6/Python-3.5.6.tar.xz
RUN python3 /tmp/install-python.py py3.7 https://www.python.org/ftp/python/3.7.2/Python-3.7.2.tar.xz
# Install kitty bundle
ENV SW=/home/circleci/sw
RUN python3 /tmp/install-python.py bundle https://download.calibre-ebook.com/travis/kitty/linux-64.tar.xz
RUN echo SW=$SW >> /etc/environment
# Clean unused files
RUN apt-get clean -y
USER circleci
LABEL com.circleci.preserve-entrypoint=true
ENTRYPOINT sleep 2h

View File

@@ -0,0 +1,60 @@
#!/usr/bin/env python3
# vim:fileencoding=utf-8
# License: GPLv3 Copyright: 2019, Kovid Goyal <kovid at kovidgoyal.net>
import io
import os
import shlex
import shutil
import subprocess
import sys
import tarfile
from urllib.request import urlopen
PY, URL = sys.argv[1], sys.argv[2]
if PY == 'bundle':
SW = os.environ['SW']
os.mkdir(SW)
os.chdir(SW)
else:
os.chdir('/usr/src')
def run(cmd):
cmd = shlex.split(cmd)
p = subprocess.Popen(cmd)
if p.wait() != 0:
raise SystemExit(p.returncode)
with urlopen(URL) as f:
data = f.read()
with tarfile.open(fileobj=io.BytesIO(data), mode='r:xz') as tf:
tf.extractall()
def replace_in_file(path, src, dest):
with open(path, 'r+') as f:
n = f.read().replace(src, dest)
f.seek(0), f.truncate()
f.write(n)
if PY == 'bundle':
replaced = 0
for dirpath, dirnames, filenames in os.walk(SW):
for f in filenames:
if f.endswith('.pc') or (f.endswith('.py') and f.startswith('_sysconfig')):
replace_in_file(os.path.join(dirpath, f), '/sw/sw', SW)
replaced += 1
if replaced < 2:
raise SystemExit('Failed to replace path to SW in bundle')
else:
src = os.path.abspath(tuple(os.listdir('.'))[0])
os.chdir(src)
run(f'./configure --prefix=/opt/{PY} --enable-shared --with-system-expat --without-ensurepip')
run(f'make -j {os.cpu_count()}')
run('make install')
os.chdir('/')
shutil.rmtree(src)

6
.gitignore vendored
View File

@@ -5,11 +5,11 @@ tags
build
linux-package
kitty.app
logo/*.iconset
compile_commands.json
link_commands.json
glad/out
asan-launcher
kitty-profile
kitty/launcher
*.dSYM
dev
__pycache__
glfw/wayland-*-client-protocol.[ch]

View File

@@ -1,170 +0,0 @@
git:
depth: false
matrix:
fast_finish: true
include:
- os: linux
dist: trusty
group: beta
language: python
sudo: false
env: USE_BUNDLE=1 SW=$HOME/sw PKG_CONFIG_PATH=$SW/lib/pkgconfig LD_LIBRARY_PATH=$SW/lib PYTHON=$SW/bin/python3
addons:
apt:
packages:
- libxi-dev
- libxrandr-dev
- libxinerama-dev
- libxcursor-dev
- libxcb-xkb-dev
- libdbus-1-dev
- os: linux
dist: trusty
group: beta
sudo: false
env:
- CC=gcc CFLAGS=-funsigned-char SANITIZE_ARG=--sanitize
language: python
python: "3.5"
addons:
apt:
packages:
- libfontconfig1-dev
- libharfbuzz-dev
- libxi-dev
- libxrandr-dev
- libxinerama-dev
- libxcursor-dev
- libxcb-xkb-dev
- libpng-dev
- libdbus-1-dev
- python3-pil
- os: linux
dist: trusty
group: beta
sudo: false
env:
- CC=clang SANITIZE_ARG=--sanitize
language: python
python: "3.5"
addons:
apt:
packages:
- libfontconfig1-dev
- libharfbuzz-dev
- libxi-dev
- libxrandr-dev
- libxinerama-dev
- libxcursor-dev
- libxcb-xkb-dev
- libpng-dev
- libdbus-1-dev
- python3-pil
- os: linux
dist: trusty
group: beta
sudo: false
env:
- RUN_FLAKE=1 BUILD_PKG=linux-package
language: python
python: "3.6"
addons:
apt:
packages:
- libfontconfig1-dev
- libharfbuzz-dev
- libxi-dev
- libxrandr-dev
- libxinerama-dev
- libxcursor-dev
- libxcb-xkb-dev
- libpng-dev
- libdbus-1-dev
- python3-pil
- clang
- os: osx
language: generic
env: SWBASE=/Users/Shared/buildbot/sw SW=$SWBASE/sw PATH=$SW/bin:$PATH
- os: osx
language: generic
env: USE_BREW=1 BUILD_PKG=osx-bundle
env:
global:
- PYTHON=python3
- PKG_CONFIG_PATH=$HOME/harfbuzz/lib/pkgconfig:$PKG_CONFIG_PATH
- LD_LIBRARY_PATH=$HOME/harfbuzz/lib:$LD_LIBRARY_PATH
- ASAN_OPTIONS=leak_check_at_exit=0
install: |
set -e
if [[ "$RUN_FLAKE" == "1" ]]; then pip install flake8; fi
if [[ "$TRAVIS_OS_NAME" == 'osx' ]]; then
if [[ "$USE_BREW" == "1" ]]; then
brew update;
brew upgrade python;
brew install harfbuzz --without-graphite2 --without-icu4c --without-freetype;
brew install imagemagick
brew install optipng
brew install librsvg
logo/make.py
else
mkdir -p $SW;
curl https://download.calibre-ebook.com/travis/kitty/osx.tar.xz | tar xJ -C $SW;
fi
else
if [[ "$USE_BUNDLE" == "1" ]]; then
mkdir -p $SW;
curl https://download.calibre-ebook.com/travis/kitty/linux-64.tar.xz | tar xJ -C $SW;
find $SW -type f -name '*.pc' -exec sed -i "s,/sw/sw,$SW,g" {} \;;
find $SW -type f -name '_sysconfig*.py' -exec sed -i "s,/sw/sw,$SW,g" {} \;;
else
pushd /tmp
wget --no-check-certificate http://xkbcommon.org/download/libxkbcommon-0.6.1.tar.xz
tar xf libxkbcommon-0.6.1.tar.xz
cd libxkbcommon-0.6.1
./configure --prefix=$HOME/harfbuzz --disable-dependency-tracking --disable-static
make -j2
make install
wget https://github.com/behdad/harfbuzz/releases/download/1.6.3/harfbuzz-1.6.3.tar.bz2
tar xf harfbuzz-1.6.3.tar.bz2
cd harfbuzz-1.6.3
./configure --prefix=$HOME/harfbuzz --disable-dependency-tracking --disable-static --with-glib=no --with-gobject=no --with-cairo=no --with-fontconfig=no --with-icu=no --with-directwrite=no --with-freetype=yes
make -j2
make install
cd ..
popd
fi
if [[ "$BUILD_PKG" == "linux-package" ]]; then
pip install sphinx
fi
fi
pkg-config --cflags harfbuzz
if [[ "$TRAVIS_OS_NAME" != 'osx' ]]; then
PLIB=$(ldd `which python` | grep libpython | cut -d ' ' -f 3)
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`dirname $PLIB`
fi
set +e
before_script:
- echo LD_LIBRARY_PATH=$LD_LIBRARY_PATH PKG_CONFIG_PATH=$PKG_CONFIG_PATH
- $PYTHON setup.py build --debug --verbose $SANITIZE_ARG;
script: |
set -e
if grep -Inr '\s$' kitty kitty_tests kittens docs *.py *.asciidoc *.rst .gitattributes .gitignore; then echo Trailing whitespace found, aborting.; exit 1; fi
if [[ -z "$SANITIZE_ARG" ]]; then $PYTHON test.py; else ./asan-launcher test.py; fi
if [[ "$RUN_FLAKE" == "1" ]]; then flake8 --count .; fi
if [[ "$BUILD_PKG" == "linux-package" ]]; then make FAIL_WARN=-W man && make FAIL_WARN=-W html; fi
if [[ ! -z "$BUILD_PKG" ]]; then $PYTHON setup.py $BUILD_PKG; fi
set +e

5
Brewfile Normal file
View File

@@ -0,0 +1,5 @@
brew 'pkg-config'
brew 'imagemagick'
brew 'harfbuzz'
brew 'python'
brew 'sphinx-doc'

View File

@@ -1,7 +1,7 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -645,7 +645,7 @@ the "copyright" line and a pointer to where the full notice is found.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
@@ -664,11 +664,11 @@ might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
<https://www.gnu.org/philosophy/why-not-lgpl.html>.

View File

@@ -18,6 +18,9 @@ clean:
debug:
python3 setup.py build $(VVAL) --debug
debug-event-loop:
python3 setup.py build $(VVAL) --debug --extra-logging=event-loop
# Build with the ASAN and UBSAN sanitizers
asan:
python3 setup.py build $(VVAL) --debug --sanitize
@@ -25,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

@@ -2,4 +2,4 @@
See https://sw.kovidgoyal.net/kitty
image::https://travis-ci.org/kovidgoyal/kitty.svg?branch=master[Build status, link=https://travis-ci.org/kovidgoyal/kitty]
image:https://circleci.com/gh/kovidgoyal/kitty.svg?style=svg["Build status", link="https://circleci.com/gh/kovidgoyal/kitty"]

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
@@ -88,7 +88,7 @@ def setup_openssl_environment():
# Workaround for Linux distros that have still failed to get their heads
# out of their asses and implement a common location for SSL certificates.
# It's not that hard people, there exists a wonderful tool called the symlink
# See http://www.mobileread.com/forums/showthread.php?t=256095
# See https://www.mobileread.com/forums/showthread.php?t=256095
if 'SSL_CERT_FILE' not in os.environ and 'SSL_CERT_DIR' not in os.environ:
if os.access('/etc/pki/tls/certs/ca-bundle.crt', os.R_OK):
os.environ['SSL_CERT_FILE'] = '/etc/pki/tls/certs/ca-bundle.crt'

View File

@@ -1,19 +0,0 @@
/*
* linux-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,24 +1,48 @@
#!/usr/bin/env python3
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2019, Kovid Goyal <kovid at kovidgoyal.net>
import glob
import os
import sys
import re
import shutil
import subprocess
import sys
import tempfile
base = os.path.dirname(os.path.abspath(__file__))
os.chdir(base)
sys.path.insert(0, base)
from kitty.terminfo import generate_terminfo # noqa
def compile_terminfo(base):
with tempfile.TemporaryDirectory() as tdir:
proc = subprocess.run(['tic', '-x', '-o' + tdir, 'terminfo/kitty.terminfo'], check=True, stderr=subprocess.PIPE)
regex = '^"terminfo/kitty.terminfo", line [0-9]+, col [0-9]+, terminal \'xterm-kitty\': older tic versions may treat the description field as an alias$'
for error in proc.stderr.decode('utf-8').splitlines():
if not re.match(regex, error):
print(error, file=sys.stderr)
tfiles = glob.glob(os.path.join(tdir, '*', 'xterm-kitty'))
if not tfiles:
raise SystemExit('tic failed to output the compiled kitty terminfo file')
with open('terminfo/kitty.terminfo', 'w') as f:
f.write(generate_terminfo())
tfile = tfiles[0]
directory, xterm_kitty = os.path.split(tfile)
_, directory = os.path.split(directory)
odir = os.path.join(base, directory)
os.makedirs(odir, exist_ok=True)
ofile = os.path.join(odir, xterm_kitty)
shutil.move(tfile, ofile)
os.environ['TERMINFO'] = os.path.join(base, 'terminfo')
subprocess.check_call(['tic', '-x', 'terminfo/kitty.terminfo'])
# On OS X tic puts the compiled database into a different directory
try:
os.mkdir('terminfo/78')
except FileExistsError:
pass
shutil.copy2('terminfo/x/xterm-kitty', 'terminfo/78')
def generate_terminfo():
base = os.path.dirname(os.path.abspath(__file__))
os.chdir(base)
sys.path.insert(0, base)
from kitty.terminfo import generate_terminfo
with open('terminfo/kitty.terminfo', 'w') as f:
f.write(generate_terminfo())
compile_terminfo(os.path.join(base, 'terminfo'))
if __name__ == '__main__':
generate_terminfo()

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

@@ -2,8 +2,8 @@
#
# You can set these variables from the command line.
SPHINXOPTS = -T $(FAIL_WARN)
SPHINXBUILD = python3 .. +launch :sphinx-build
SPHINXOPTS = -j auto -T $(FAIL_WARN)
SPHINXBUILD = sphinx-build
SPHINXPROJ = kitty
SOURCEDIR = .
BUILDDIR = _build

View File

@@ -1,13 +1,6 @@
{% extends "!layout.html" %}
{%- block extrahead %}
<!-- Google Analytics -->
<script>
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
ga('create', 'UA-20736318-2', 'auto');
ga('send', 'pageview');
</script>
<script async="async" src='https://www.google-analytics.com/analytics.js'></script>
<!-- End Google Analytics -->
<!-- kitty analytics placeholder -->
{{ super() }}
{% endblock %}

View File

@@ -1,9 +1,9 @@
Building kitty from source
==============================
.. image:: https://travis-ci.org/kovidgoyal/kitty.svg?branch=master
.. image:: https://circleci.com/gh/kovidgoyal/kitty.svg?style=svg
:alt: Build status
:target: https://travis-ci.org/kovidgoyal/kitty
:target: https://circleci.com/gh/kovidgoyal/kitty
|kitty| is designed to run from source, for easy hackability. Make sure
@@ -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`` and ``libxkbcommon-x11-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,19 +45,30 @@ 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
-------------------------------------------
Run::
make app
This :file:`kitty.app` unlike the released one does not include its own copy of
python and the other dependencies. So if you ever un-install/upgrade those dependencies
you might have to rebuild the app.
Note that the released :file:`kitty.dmg` includes all dependencies, unlike the
:file:`kitty.app` built above and is built automatically by using the :file:`kitty` branch of
`build-calibre <https://github.com/kovidgoyal/build-calibre>`_ however, that
is designed to run on Linux and is not for the faint of heart.
Note for Linux/macOS packagers
----------------------------------
@@ -88,7 +100,13 @@ without needing to install all of |kitty|.
development package of :file:`ncurses`. Also, if you are building from
a git checkout instead of the released source code tarball, you will
need :file:`sphinx-build` from the `Sphinx documentation generator
<http://www.sphinx-doc.org/>`_.
<https://www.sphinx-doc.org/>`_.
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

@@ -2,6 +2,473 @@ Changelog
==============
|kitty| is a feature full, cross-platform, *fast*, GPU based terminal emulator.
To update |kitty|, :doc:`follow the instructions <binary>`.
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]
---------------------
- macOS: The default behavior of the Option key has changed. It now generates
unicode characters rather than acting as the :kbd:`Alt` modifier. See
:opt:`macos_option_as_alt`.
- Support for an arbitrary number of internal clipboard buffers to copy/paste
from, see (:ref:`cpbuf`)
- Allow using the new private internal clipboard buffers with the
:opt:`copy_on_select` option (:iss:`1390`)
- macOS: Allow opening new kitty tabs/top-level windows from Finder
(:pull:`1350`)
- Add an option :opt:`disable_ligatures` to disable
multi-character ligatures under the cursor to make editing easier
or disable them completely (:iss:`461`)
- Allow creating new OS windows in session files (:iss:`1514`)
- Allow setting OS window size in session files
- Add an option :opt:`tab_switch_strategy` to control which
tab becomes active when the current tab is closed (:pull:`1524`)
- Allow specifying a value of ``none`` for the :opt:`selection_foreground`
which will cause kitty to not change text color in selections (:iss:`1358`)
- Make live resizing of OS windows smoother and add an option
:opt:`resize_draw_strategy` to control what is drawn while a
resize is in progress.
- macOS: Improve handling of IME extended input. Compose characters
are now highlighted and the IME panel moves along with the text
(:pull:`1586`). Also fixes handling of delete key in Chinese IME
(:iss:`1461`)
- When a window is closed, switch focus to the previously active window (if
any) instead of picking the previous window in the layout (:iss:`1450`)
- icat kitten: Add support for displaying images at http(s) URLs (:iss:`1340`)
- A new option :opt:`strip_trailing_spaces` to optionally remove trailing
spaces from lines when copying to clipboard.
- A new option :opt:`tab_bar_min_tabs` to control how many tabs must be
present before the tab-bar is shown (:iss:`1382`)
- Automatically check for new releases and notify when an update is available,
via the system notification facilities. Can be controlled by
:opt:`update_check_interval` (:iss:`1342`)
- macOS: Fix :kbd:`cmd+period` key not working (:iss:`1318`)
- macOS: Add an option :opt:`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
hidden in other applications in rare circumstances (:iss:`1218`)
- macOS: Allow assigning only the left or right :kbd:`Option` key to work as the
:kbd:`Alt` key. See :opt:`macos_option_as_alt` for details (:iss:`1022`)
- Fix using remote control to set cursor text color causing errors when
creating new windows (:iss:`1326`)
- Fix window title for minimized windows not being updated (:iss:`1332`)
- macOS: Fix using multi-key sequences to input text ignoring the
first few key presses if the sequence is aborted (:iss:`1311`)
- macOS: Add a number of common macOS keyboard shortcuts
- macOS: Reduce energy consumption by not rendering occluded windows
- Fix scrollback pager history not being cleared when clearing the
main scrollback buffer (:iss:`1387`)
- macOS: When closing a top-level window only switch focus to the previous kitty
window if it is on the same workspace (:iss:`1379`)
- macOS: Fix :opt:`sync_to_monitor` not working on Mojave.
- macOS: Use the system cursor blink interval by default
:opt:`cursor_blink_interval`.
- Wayland: Use the kitty Wayland backend by default. Can be switched back
to using XWayland by setting the environment variable:
``KITTY_DISABLE_WAYLAND=1``
- Add a ``no-append`` setting to :opt:`clipboard_control` to disable
the kitty copy concatenation protocol extension for OSC 52.
- Update to using the Unicode 12 standard
- Unicode input kitten: Allow using the arrow keys in code mode to go to next
and previous unicode symbol.
- macOS: Fix specifying initial window size in cells not working correctly on
Retina screens (:iss:`1444`)
- Fix a regression in version 0.13.0 that caused background colors of space
characters after private use unicode characters to not be respected
(:iss:`1455`)
- Only update the selected text to clipboard when the selection is finished,
not continuously as it is updated. (:iss:`1460`)
- Allow setting :opt:`active_border_color` to ``none`` to not draw a border
around the active window (:iss:`805`)
- Use negative values for :opt:`mouse_hide_wait` to hide the mouse cursor
immediately when pressing a key (:iss:`1534`)
- When encountering errors in :file:`kitty.conf` report them to the user
instead of failing to start.
- Allow the user to control the resize debounce time via
:opt:`resize_debounce_time`.
- Remote control: Make the :ref:`at_set-font-size` command more capable.
It can now increment font size and reset it. It also only acts on the
active top-level window, by default (:iss:`1581`)
- When launching child processes set the :code:`PWD` environment variable
(:iss:`1595`)
- X11: use the window manager's native full-screen implementation when
making windows full-screen (:iss:`1605`)
- Mouse selection: When extending by word, fix extending selection to non-word
characters not working well (:iss:`1616`)
0.13.3 [2019-01-19]
------------------------------
- icat kitten: Add a ``--stdin`` option to control if image data is read from
STDIN (:iss:`1308`)
- hints kitten: Start hints numbering at one instead of zero by default. Added
an option ``--hints-offset`` to control it. (:iss:`1289`)
- Fix a regression in the previous release that broke using ``background`` for
:opt:`cursor_text_color` (:iss:`1288`)
- macOS: Fix dragging kitty window tabs in traditional full screen mode causing
crashes (:iss:`1296`)
- macOS: Ensure that when running from a bundle, the bundle kitty exe is
preferred over any kitty in PATH (:iss:`1280`)
- macOS: Fix a regression that broke mapping of :kbd:`ctrl+tab` (:iss:`1304`)
- Add a list of user-created kittens to the docs
- Fix a regression that broke changing mouse wheel scroll direction with
negative :opt:`wheel_scroll_multiplier` values in full-screen applications
like vim (:iss:`1299`)
- Fix :opt:`background_opacity` not working with pure white backgrounds
(:iss:`1285`)
- macOS: Fix "New OS Window" dock action not working when kitty is not focused
(:iss:`1312`)
- macOS: Add aliases for close window and new tab actions that conform to common
Apple shortcuts for these actions (:iss:`1313`)
- macOS: Fix some kittens causing 100% CPU usage
0.13.2 [2019-01-04]
------------------------------
- Add a new option :opt:`tab_title_template` to control how tab titles
are formatted. In particular the template can be used to display
the tab number next to the title (:iss:`1223`)
- Report the current foreground processes as well as the original child process,
when using `kitty @ ls`
- Use the current working directory of the foreground process for the
`*_with_cwd` actions that open a new window with the current working
directory.
- Add a new ``copy_or_interrupt`` action that can be mapped to kbd:`ctrl+c`. It
will copy if there is a selection and interrupt otherwise (:iss:`1286`)
- Fix setting :opt:`background_opacity` causing window margins/padding to be slightly
different shade from background (:iss:`1221`)
- Handle keyboards with a "+" key (:iss:`1224`)
- Fix Private use Unicode area characters followed by spaces at the end of text
not being rendered correctly (:iss:`1210`)
- macOS: Add an entry to the dock menu to open a new OS window (:iss:`1242`)
- macOS: Fix scrolling very slowly with wheel mice not working (:iss:`1238`)
- Fix changing :opt:`cursor_text_color` via remote control not working
(:iss:`1229`)
- Add an action to resize windows that can be mapped to shortcuts in :file:`kitty.conf`
(:pull:`1245`)
- Fix using the ``new_tab !neighbor`` action changing the order of the
non-neighboring tabs (:iss:`1256`)
- macOS: Fix momentum scrolling continuing when changing the active window/tab
(:iss:`1267`)
0.13.1 [2018-12-06]
------------------------------
- Fix passing input via the pipe action to a program without a window not
working.
- Linux: Fix a regression in the previous release that caused automatic
selection of bold/italic fonts when using aliases such as "monospace" to not
work (:iss:`1209`)
- Fix resizing window smaller and then restoring causing some wrapped lines to not
be properly unwrapped (:iss:`1206`)
0.13.0 [2018-12-05]
------------------------------
- Add an option :opt:`scrollback_pager_history_size` to tell kitty to store
extended scrollback to use when viewing the scrollback buffer in a pager
(:iss:`970`)
- Modify the kittens sub-system to allow creating custom kittens without any
user interface. This is useful for creating more complex actions that can
be bound to key presses in :file:`kitty.conf`. See
doc:`kittens/custom`. (:iss:`870`)
- Add a new ``nth_window`` action that can be used to go to the nth window and
also previously active windows, using negative numbers. Similarly,
``goto_tab`` now accepts negative numbers to go to previously active tabs
(:iss:`1040`)
- Allow hiding the tab bar completely, by setting :opt:`tab_bar_style` to
``hidden``. (:iss:`1014`)
- Allow private use unicode characters to stretch over more than a single
neighboring space (:pull:`1036`)
- Add a new :opt:`touch_scroll_multiplier` option to modify the amount
scrolled by high precision scrolling devices such as touchpads (:pull:`1129`)
- icat kitten: Implement reading image data from STDIN, if STDIN is not
connected to a terminal (:iss:`1130`)
- hints kitten: Insert trailing spaces after matches when using the
``--multiple`` option. Also add a separate ``--add-trailing-space``
option to control this behavior (:pull:`1132`)
- Fix the ``*_with_cwd`` actions using the cwd of the overlay window rather
than the underlying window's cwd (:iss:`1045`)
- Fix incorrect key repeat rate on wayland (:pull:`1055`)
- macOS: Fix drag and drop of files not working on Mojave (:iss:`1058`)
- macOS: Fix IME input for East Asian languages (:iss:`910`)
- macOS: Fix rendering frames-per-second very low when processing
large amounts of input in small chunks (:pull:`1082`)
- macOS: Fix incorrect text sizes calculated when using an external display
that is set to mirror the main display (:iss:`1056`)
- macOS: Use the system default double click interval (:pull:`1090`)
- macOS: Fix touch scrolling sensitivity low on retina screens (:iss:`1112`)
- Linux: Fix incorrect rendering of some fonts when hinting is disabled at
small sizes (:iss:`1173`)
- Linux: Fix match rules used as aliases in Fontconfig configuration not being
respected (:iss:`1085`)
- Linux: Fix a crash when using the GNU Unifont as a fallback font
(:iss:`1087`)
- Wayland: Fix copying from hidden kitty windows hanging (:iss:`1051`)
- Wayland: Add support for the primary selection protocol
implemented by some compositors (:pull:`1095`)
- Fix expansion of env vars not working in the :opt:`env` directive
(:iss:`1075`)
- Fix :opt:`mouse_hide_wait` only taking effect after an event such as cursor
blink or key press (:iss:`1073`)
- Fix the ``set_background_opacity`` action not working correctly
(:pull:`1147`)
- Fix second cell of emoji created using variation selectors not having
the same attributes as the first cell (:iss:`1109`)
- Fix focusing neighboring windows in the grid layout with less than 4 windows
not working (:iss:`1115`)
- Fix :kbd:`ctrl+shift+special` key not working in normal and application keyboard
modes (:iss:`1114`)
- Add a terminfo entry for full keyboard mode.
- Fix incorrect text-antialiasing when using very low background opacity
(:iss:`1005`)
- When double or triple clicking ignore clicks if they are "far" from each
other (:iss:`1093`)
- Follow xterm's behavior for the menu key (:iss:`597`)
- Fix hover detection of URLs not working when hovering over the first colon
and slash characters in short URLs (:iss:`1201`)
0.12.3 [2018-09-29]
------------------------------
- macOS: Fix kitty window not being rendered on macOS Mojave until the window is
moved or resized at least once (:iss:`887`)
- Unicode input: Fix an error when searching for the string 'fir' (:iss:`1035`)
0.12.2 [2018-09-24]
------------------------------
@@ -133,6 +600,9 @@ Changelog
- Add an option :opt:`env` to set environment variables in child processes
from kitty.conf
- Add an action to the ``clear_terminal`` function to scroll the screen
contents into the scrollback buffer (:iss:`1113`)
- Implement high precision scrolling with the trackpad on platforms such as
macOS and Wayland that implement it. (:pull:`819`)
@@ -342,7 +812,7 @@ Changelog
- Add a config option (:opt:`editor`) to set the EDITOR kitty uses (:iss:`580`)
- Add a config option (:opt:`x11_hide_window_decorations`) to hide window
- Add a config option (``x11_hide_window_decorations``) to hide window
decorations under X11/Wayland (:iss:`607`)
- Add an option to @set-window-title to make the title change non-permanent

View File

@@ -1,15 +1,18 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Configuration file for the Sphinx documentation builder.
#
# This file does only contain a selection of the most common options. For a
# full list see the documentation:
# http://www.sphinx-doc.org/en/master/config
# https://www.sphinx-doc.org/en/master/config
import importlib
import os
import re
import subprocess
import sys
import time
from functools import partial
from docutils import nodes
@@ -19,15 +22,19 @@ from pygments.token import (
Comment, Keyword, Literal, Name, Number, String, Whitespace
)
from sphinx import addnodes
from sphinx.environment.adapters.toctree import TocTree
from sphinx.util.logging import getLogger
from kitty.constants import str_version
kitty_src = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if kitty_src not in sys.path:
sys.path.insert(0, kitty_src)
str_version = importlib.import_module('kitty.constants').str_version
# config {{{
# -- Project information -----------------------------------------------------
project = 'kitty'
copyright = '2018, Kovid Goyal'
copyright = time.strftime('%Y, Kovid Goyal')
author = 'Kovid Goyal'
building_man_pages = 'man' in sys.argv
@@ -175,7 +182,7 @@ texinfo_documents = [
# }}}
# GitHub linking inlne roles {{{
# GitHub linking inline roles {{{
def num_role(which, name, rawtext, text, lineno, inliner, options={}, content=[]):
' Link to a github issue '
@@ -214,7 +221,8 @@ def commit_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
# Sidebar ToC {{{
def create_toc(app, pagename):
toctree = app.env.get_toc_for(pagename, app.builder)
tt = TocTree(app.env)
toctree = tt.get_toc_for(pagename, app.builder)
if toctree is not None:
subtree = toctree[toctree.first_child_matching_class(nodes.list_item)]
bl = subtree.first_child_matching_class(nodes.bullet_list)
@@ -268,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):
@@ -475,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
@@ -529,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

@@ -20,6 +20,10 @@ You can also display the current configuration by running ``kitty
:option:`kitty --config` option or use the ``KITTY_CONFIG_DIRECTORY``
environment variable. See the :option:`kitty --config` option for full details.
Comments can be added to the config file as lines starting with the ``#``
character. This works only if the ``#`` character is the first character
in the line.
You can include secondary config files via the :code:`include` directive. If
you use a relative path for include, it is resolved with respect to the
location of the current config file. Note that environment variables are

View File

@@ -6,7 +6,7 @@ Frequently Asked Questions
.. contents::
Some special symbols are rendered small/truncated in kitty?
-----------------------------------------------------------------
-----------------------------------------------------------
The number of cells a unicode character takes up are controlled by the unicode
standard. All characters are rendered in a single cell unless the unicode
@@ -25,24 +25,6 @@ these characters are followed by a space or empty cell in which case kitty
makes use of the extra cell to render them in two cells.
How do I build kitty.app on macOS?
----------------------------------------
Install `imagemagick`, `optipng` and `librsvg` using `brew` or similar (needed
for the logo generation step). And run::
make app
This :file:`kitty.app` unlike the released one does not include its own copy of
python and the other dependencies. So if you ever un-install/upgrade those dependencies
you might have to rebuild the app.
Note that the released :file:`kitty.dmg` includes all dependencies, unlike the
:file:`kitty.app` built above and is built automatically by using the :file:`kitty` branch of
`build-calibre <https://github.com/kovidgoyal/build-calibre>`_ however, that
is designed to run on Linux and is not for the faint of heart.
Using a color theme with a background color does not work well in vim?
-----------------------------------------------------------------------
@@ -66,25 +48,83 @@ terminfo files to the server::
kitty +kitten ssh myserver
If for some reason that does not work (typically because the server is using a
a non POSIX compliant shell), you can use the following one-liner instead (it
non POSIX compliant shell), you can use the following one-liner instead (it
is slower as it needs to ssh into the server twice, but will work with most
servers)::
infocmp xterm-kitty | ssh myserver tic -x -o \~/.terminfo /dev/stdin
If you are behind a proxy (like Balabit) that prevents this, you must redirect the
1st command to a file, copy that to the server and run ``tic`` manually. If you
connect to a server, embedded or Android system that doesn't have ``tic``, copy over
your local file terminfo to the other system as :file:`~/.terminfo/x/xterm-kitty`.
Really, the correct solution for this is to convince the OpenSSH maintainers to
have ssh do this automatically when connecting to a server, so that all
terminals work transparently.
have ssh do this automatically, if possible, when connecting to a server, so that
all terminals work transparently.
Keys such as arrow keys, backspace, delete, home/end, etc. do not work when using su or sudo?
-------------------------------------------------------------------------------------------------
Make sure the TERM environment variable, is ``xterm-kitty``. And either the
TERMINFO environment variable points to a directory containing :file:`x/xterm-kitty`
or that file is under :file:`~/.terminfo/x/`.
Note that ``sudo`` might remove TERMINFO. Then setting it at the shell prompt can
be too late, because command line editing may not be reinitialized. In that case
you can either ask ``sudo`` to set it or if that is not supported, insert an ``env``
command before starting the shell, or, if not possible, after sudo start another
Shell providing the right terminfo path::
sudo … TERMINFO=$HOME/.terminfo bash -i
sudo … env TERMINFO=$HOME/.terminfo bash -i
TERMINFO=/home/ORIGINALUSER/.terminfo exec bash -i
You can configure sudo to preserve TERMINFO by running ``sudo
visudo`` and adding the following line::
Defaults env_keep += "TERM TERMINFO"
If you have double width characters in your prompt, you may also need to
explicitly set a UTF-8 locale, like::
export LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8
How do I change the colors in a running kitty instance?
------------------------------------------------------------
You can either use the
`OSC terminal escape codes <http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands>`_
`OSC terminal escape codes <https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands>`_
to set colors or you can enable :doc:`remote control <remote-control>`
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?
---------------------------------------------------------------
@@ -122,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

@@ -75,6 +75,47 @@ You can also use the *CSI t* escape code to get the screen size. Send
``<ESC>[4;<height>;<width>t`` where *height* and *width* are the window size in
pixels. This escape code is supported in many terminals, not just kitty.
A minimal example
------------------
Some minimal python code to display PNG images in kitty, using the most basic
features of the graphics protocol:
.. code-block:: python
import sys
from base64 import standard_b64encode
def serialize_gr_command(cmd, payload=None):
cmd = ','.join('{}={}'.format(k, v) for k, v in cmd.items())
ans = []
w = ans.append
w(b'\033_G'), w(cmd.encode('ascii'))
if payload:
w(b';')
w(payload)
w(b'\033\\')
return b''.join(ans)
def write_chunked(cmd, data):
data = standard_b64encode(data)
while data:
chunk, data = data[:4096], data[4096:]
m = 1 if data else 0
cmd['m'] = m
sys.stdout.buffer.write(serialize_gr_command(cmd, chunk))
sys.stdout.flush()
cmd.clear()
write_chunked({'a': 'T', 'f': 100}, open(sys.argv[-1], 'rb').read())
Save this script as :file:`png.py`, then you can use it to display any PNG
file in kitty as::
python png.py file.png
The graphics escape code
---------------------------
@@ -160,7 +201,11 @@ Value of `t` Meaning
================== ============
``d`` Direct (the data is transmitted within the escape code itself)
``f`` A simple file
``t`` A temporary file, the terminal emulator will delete the file after reading the pixel data
``t`` A temporary file, the terminal emulator will delete the file after reading the pixel data. For security reasons
the terminal emulator should only delete the file if it
is in a known temporary directory, such as :file:`/tmp`,
:file:`/dev/shm`, :file:`TMPDIR env var if present` and any platform
specific temporary directories.
``s`` A `POSIX shared memory object <http://man7.org/linux/man-pages/man7/shm_overview.7.html>`_.
The terminal emulator will delete it after reading the pixel data
================== ============

View File

@@ -36,6 +36,8 @@ kitty - the fast, featureful, GPU based terminal emulator
separate window using arbitrary programs of your choice. This is useful for
browsing the history comfortably in a pager or editor.
* Has :ref:`multiple copy/paste buffers <cpbuf>`, like vim.
.. figure:: screenshots/screenshot.png
:alt: Screenshot, showing three programs in the 'Tall' layout
@@ -54,15 +56,18 @@ Pre-built binaries of |kitty| are available for both macOS and Linux.
See the :doc:`binary install instructions </binary>`. You can also
:doc:`build from source </build>`.
If you are on Linux, you can also use your distribution's |kitty| package.
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/>`_,
`NixOS <https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/misc/kitty/default.nix>`_,
`Gentoo <https://packages.gentoo.org/packages/x11-terms/kitty>`_,
`Fedora <https://copr.fedorainfracloud.org/coprs/gagbo/kitty-latest/>`_,
`Void Linux <https://github.com/void-linux/void-packages/blob/master/srcpkgs/kitty/template>`_.
`Void Linux <https://github.com/void-linux/void-packages/blob/master/srcpkgs/kitty/template>`_,
and `Solus <https://dev.getsol.us/source/kitty/>`_.
See :doc:`Configuring kitty <conf>` for help on configuring |kitty| and
:doc:`Invocation <invocation>` for the command line arguments |kitty| supports.
@@ -90,7 +95,7 @@ formatting, etc. It even extends existing text formatting escape codes,
to add support for features not available elsewhere, such as colored and
styled (curly) underlines. One of the design goals of |kitty| is to be
easily extensible so that new features can be added in the future with
relatively less effort.
relatively little effort.
Tabs and Windows
-------------------
@@ -108,12 +113,12 @@ Scrolling
======================== =======================
Action Shortcut
======================== =======================
Scroll line up :sc:`scroll_line_up`
Scroll line down :sc:`scroll_line_down`
Scroll page up :sc:`scroll_page_up`
Scroll page down :sc:`scroll_page_down`
Scroll to top :sc:`scroll_home`
Scroll to bottom :sc:`scroll_end`
Scroll line up :sc:`scroll_line_up` (also :kbd:`⌥+⌘+⇞` and :kbd:`⌘+↑` on macOS)
Scroll line down :sc:`scroll_line_down` (also :kbd:`⌥+⌘+⇟` and :kbd:`⌘+↓` on macOS)
Scroll page up :sc:`scroll_page_up` (also :kbd:`⌘+⇞` on macOS)
Scroll page down :sc:`scroll_page_down` (also :kbd:`⌘+⇟` on macOS)
Scroll to top :sc:`scroll_home` (also :kbd:`⌘+↖` on macOS)
Scroll to bottom :sc:`scroll_end` (also :kbd:`⌘+↘` on macOS)
======================== =======================
Tabs
@@ -122,14 +127,14 @@ Tabs
======================== =======================
Action Shortcut
======================== =======================
New tab :sc:`new_tab`
Close tab :sc:`close_tab`
Next tab :sc:`next_tab` (also :kbd:`control+tab` on macOS)
Previous tab :sc:`previous_tab` (also :kbd:`control+shift+tab` on macOS)
New tab :sc:`new_tab` (also :kbd:`⌘+t` on macOS)
Close tab :sc:`close_tab` (also :kbd:`⌘+w` on macOS)
Next tab :sc:`next_tab` (also :kbd:`^+⇥` and :kbd:`⇧+⌘+]` on macOS)
Previous tab :sc:`previous_tab` (also :kbd:`⇧+^+⇥` and :kbd:`⇧+⌘+[` on macOS)
Next layout :sc:`next_layout`
Move tab forward :sc:`move_tab_forward`
Move tab backward :sc:`move_tab_backward`
Set tab title :sc:`set_tab_title`
Set tab title :sc:`set_tab_title` (also :kbd:`⇧+⌘+i` on macOS)
======================== =======================
@@ -139,15 +144,16 @@ Windows
======================== =======================
Action Shortcut
======================== =======================
New window :sc:`new_window`
New window :sc:`new_window` (also :kbd:`⌘+↩` on macOS)
New OS window :sc:`new_os_window` (also :kbd:`⌘+n` on macOS)
Close window :sc:`close_window`
Close window :sc:`close_window` (also :kbd:`⇧+⌘+d` on macOS)
Next window :sc:`next_window`
Previous window :sc:`previous_window`
Move window forward :sc:`move_window_forward`
Move window backward :sc:`move_window_backward`
Move window to top :sc:`move_window_to_top`
Focus specific window :sc:`first_window`, :sc:`second_window` ... :sc:`tenth_window`
(also :kbd:`⌘+1`, :kbd:`⌘+2` ... :kbd:`⌘+9` on macOS)
(clockwise from the top-left)
======================== =======================
@@ -160,6 +166,13 @@ windows and move windows around (similar to window movement in vim)::
map shift+down move_window up
...
You can also define a shortcut to switch to the previously active window::
map ctrl+p nth_window -1
``nth_window`` will focus the nth window for positive numbers and the
previously active windows for negative numbers.
Other keyboard shortcuts
----------------------------------
@@ -170,11 +183,11 @@ Action Shortcut
Copy to clipboard :sc:`copy_to_clipboard` (also :kbd:`⌘+c` on macOS)
Paste from clipboard :sc:`paste_from_clipboard` (also :kbd:`⌘+v` on macOS)
Paste from selection :sc:`paste_from_selection`
Increase font size :sc:`increase_font_size`
Decrease font size :sc:`decrease_font_size`
Restore font size :sc:`reset_font_size`
Toggle fullscreen :sc:`toggle_fullscreen` (also :kbd:`^⌘+f` on macOS)
on
Increase font size :sc:`increase_font_size` (also :kbd:`⌘++` on macOS)
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`
@@ -209,13 +222,26 @@ You can switch between layouts using the :sc:`next_layout` key combination. You
also create shortcuts to select particular layouts, and choose which layouts
you want to enable/disable, see :ref:`conf-kitty-shortcuts.layout` for examples.
You can resize windows inside layouts. Press :sc:`start_resizing_window` to
You can resize windows inside layouts. Press :sc:`start_resizing_window` (also :kbd:`⌘+r` on macOS) to
enter resizing mode and follow the on-screen instructions. In a given window
layout only some operations may be possible for a particular window. For
example, in the Tall layout you can make the first window wider/narrower, but
not taller/shorter. Note that what you are resizing is actually not a window,
but a row/column in the layout, all windows in that row/column will be resized.
You can also define shortcuts in :file:`kitty.conf` to make the active window
wider, narrower, taller, or shorter by mapping to the ``resize_window``
action, for example::
map ctrl+left resize_window narrower
map ctrl+right resize_window wider
map ctrl+up resize_window taller
map ctrl+down resize_window shorter 3
The ``resize_window`` action has a second, optional argument to control
the resizing increment (a positive integer that defaults to 1).
Some layouts take options to control their behavior. For example, the ``fat``
and ``tall`` layouts accept the ``bias`` option to control how the available
space is split up. To specify the option, in :opt:`kitty.conf <enabled_layouts>` use::
@@ -320,6 +346,12 @@ For example:
# Set the current layout
layout stack
launch zsh
# Create a new OS window
new_os_window
# set new window size to 80x25 cells
os_window_size 80c 25c
launch sh
# Make the current window the active (focused) window
focus
launch emacs
@@ -328,11 +360,16 @@ For example:
Mouse features
-------------------
* You can also hold down :kbd:`ctrl+shift` and click on a URL to open it in a browser.
* You can double click to select a word and triple click to select a line.
* You can right click to extend a previous selection
* You can hold down :kbd:`ctrl+shift` and click on a URL to open it in a browser.
* You can double click to select a word and then drag to select more words.
* You can triple click to select a line and then drag to select more lines.
* You can right click to extend a previous selection.
* You can hold down :kbd:`ctrl+alt` and drag with the mouse to select in
columns
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
@@ -370,6 +407,26 @@ arbitrary, command running in a new window, tab or overlay, for example::
Would open the scrollback buffer in a new window when you press the :kbd:`F1`
key. See :sc:`show_scrollback` for details.
If you wish to store very large amounts of scrollback to view using the piping or
:sc:`show_scrollback` features, you can use the :opt:`scrollback_pager_history_size`
option.
.. _cpbuf:
Multiple copy/paste buffers
-----------------------------
In addition to being able to copy/paste from the system clipboard, in |kitty| you
can also setup an arbitrary number of copy paste buffers. To do so, simply add
something like the following to your :file:`kitty.conf`::
map f1 copy_to_buffer a
map f2 paste_from_buffer a
This will allow you to press :kbd:`F1` to copy the current selection to an
internal buffer named ``a`` and :kbd:`F2` to paste from that buffer. The buffer
names are arbitrary strings, so you can define as many such buffers as you
need.
Frequently Asked Questions
---------------------------------
@@ -393,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
~~~~~~~~~
@@ -431,3 +496,4 @@ See :doc:`changelog`.
*
kittens/*
generated/rc

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
@@ -72,7 +72,10 @@ class Reporter: # {{{
def get_latest_release_data():
print('Checking for latest release on GitHub...')
req = urllib.Request('https://api.github.com/repos/kovidgoyal/kitty/releases/latest', headers={'Accept': 'application/vnd.github.v3+json'})
res = urllib.urlopen(req).read().decode('utf-8')
try:
res = urllib.urlopen(req).read().decode('utf-8')
except Exception as err:
raise SystemExit('Failed to contact {} with error: {}'.format(req.get_full_url(), err))
data = json.loads(res)
html_url = data['html_url'].replace('/tag/', '/download/').rstrip('/')
for asset in data.get('assets', ()):

View File

@@ -43,6 +43,8 @@ Now in :file:`kitty.conf` add the lines::
Start kitty and press :kbd:`ctrl+k` and you should see the kitten running.
The best way to develop your own kittens is to modify one of the built in
kittens. Look in the kittens sub-directory of the kitty source code for those.
Or see below for a list of :ref:`third-party kittens <external_kittens>`,
that other kitty users have created.
Passing arguments to kittens
@@ -68,7 +70,14 @@ function, telling kitty what kind of input your kitten would like. For example:
.. code-block:: py
def handle_result(...):
# in main, STDIN is for the kitten process and will contain
# the contents of the screen
def main(args):
return sys.stdin.read()
# in handle_result, STDIN is for the kitty process itself, rather
# than the kitten process and should not be read from.
def handle_result(args, stdin_data, target_window_id, boss):
pass
handle_result.type_of_input = 'text'
@@ -78,3 +87,60 @@ This will send the plain text of the active window to the kitten's
instead. If you want line wrap markers as well, use ``screen-ansi``
or just ``screen``. For the scrollback buffer as well, use
``history``, ``ansi-history`` or ``screen-history``.
Using kittens to script kitty, without any terminal UI
-----------------------------------------------------------
If you would like your kitten to script kitty, without bothering to write a
terminal program, you can tell the kittens system to run the
``handle_result()`` function without first running the ``main()`` function.
For example, here is a kitten that "zooms/unzooms" the current terminal window
by switching to the stack layout or back to the previous layout.
Create a file in the kitty config folder, :file:`~/.config/kitty/zoom_toggle.py`
.. code-block:: py
def main(args):
pass
def handle_result(args, answer, target_window_id, boss):
tab = boss.active_tab
if tab is not None:
if tab.current_layout.name == 'stack':
tab.last_used_layout()
else:
tab.goto_layout('stack')
handle_result.no_ui = True
Now in kitty.conf add::
map f11 kitten zoom_toggle.py
Pressing :kbd:`F11` will now act as a zoom toggle function. You can get even
more fancy, switching the kitty OS window to fullscreen as well as changing the
layout, by simply adding the line::
boss.toggle_fullscreen()
to the ``handle_result()`` function, above.
.. _external_kittens:
Kittens created by kitty users
---------------------------------------------
`vim-kitty-navigator <https://github.com/knubie/vim-kitty-navigator>`_
Allows you to navigate seamlessly between vim and kitty splits using a consistent set of hotkeys.
`smart-scroll <https://github.com/yurikhan/kitty-smart-scroll>`_
Makes the kitty scroll bindings work in full screen applications
`insert password <https://github.com/kovidgoyal/kitty/issues/1222>`_
Insert a password from a CLI password manager, taking care to only do it at
a password prompt.

View File

@@ -15,6 +15,8 @@ In :guilabel:`Code` mode, you enter a unicode character by typing in the hex cod
character and pressing enter, for example, type in ``2716`` and press enter to get
✖. You can also choose a character from the list of recently used characters by
typing a leading period and then the two character index and pressing Enter.
The up and down arrow keys can be used to choose the previous and next unicode
symbol respectively.
In :guilabel:`Name` mode you instead type words from the character name and use the arrow
keys/tab to select the character from the displayed matches. You can also type

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

92
docs/pipe.rst Normal file
View File

@@ -0,0 +1,92 @@
Working with the screen and history buffer contents
======================================================
You can pipe the contents of the current screen and history buffer as
:file:`STDIN` to an arbitrary program using the ``pipe`` function. The program
can be displayed in a kitty window or overlay.
For example, the following in :file:`kitty.conf` will open the scrollback
buffer in less in an overlay window, when you press :kbd:`F1`::
map f1 pipe @ansi overlay less +G -R
The syntax of the ``pipe`` function is::
pipe <input placeholder> <destination window type> <command line to run>
The piping environment
--------------------------
The program to which the data is piped has a special environment variable
declared, ``KITTY_PIPE_DATA`` whose contents are::
KITTY_PIPE_DATA={scrolled_by}:{cursor_x},{cursor_y}:{lines},{columns}
where ``scrolled_by`` is the number of lines kitty is currently scrolled by,
``cursor_(x|y)`` is the position of the cursor on the screen with ``(1,1)``
being the top left corner and ``{lines},{columns}`` being the number of rows
and columns of the screen.
You can choose where to run the pipe program:
``overlay``
An overlay window over the current kitty window
``window``
A new kitty window
``os_window``
A new top-level window
``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
Input placeholders
--------------------
There are various different kinds of placeholders
``@text``
Plain text, current screen + scrollback buffer
``@ansi``
Text with formatting, current screen + scrollback buffer
``@screen``
Plain text, only current screen
``@ansi_screen``
Text with formatting, only current screen
``@alternate``
Plain text, secondary screen. The secondary screen is the screen not currently displayed. For
example if you run a fullscreen terminal application, the secondary screen will
be the screen you return to when quitting the application.
``@ansi_alternate``
Text with formatting, secondary screen.
``@alternate_scrollback``
Plain text, secondary screen + scrollback, if any.
``@ansi_alternate_scrollback``
Text with formatting, secondary screen + scrollback, if any.
``none``
No input
You can also add the suffix ``_wrap`` to the placeholder, in which case kitty
will insert the carriage return at every line wrap location (where long lines
are wrapped at screen edges). This is useful if you want to pipe to program
that wants to duplicate the screen layout of the screen.

View File

@@ -6,7 +6,7 @@ These are typically in the form of new or re-purposed escape codes. While these
extensions are currently |kitty| specific, it would be nice to get some of them
adopted more broadly, to push the state of terminal emulators forward.
The goal of these extensions is to be as small an unobtrusive as possible,
The goal of these extensions is to be as small and unobtrusive as possible,
while filling in some gaps in the existing xterm protocol. In particular, one
of the goals of this specification is explicitly not to "re-imagine" the tty.
The tty should remain what it is -- a device for efficiently processing text
@@ -51,6 +51,9 @@ To reset the underline color (also previously reserved and unused)::
<ESC>[59m
The underline color must remain the same under reverse video, if it has a
color, if not, it should follow the foreground color.
To detect support for this feature in a terminal emulator, query the terminfo database
for the ``Su`` boolean capability.
@@ -133,6 +136,10 @@ Alt -- ``0x2``, Control -- ``0x4`` and Super -- ``0x8``. ``<key>`` is a number
(encoded in base85) corresponding to the key pressed. The key name to number
mapping is defined in :doc:`this table <key-encoding>`.
Client programs must ignore events for keys they do not know. The mapping in
the above table is stable and will never change, however, new codes might be
added to it in the future, for new keys.
For example::
<ESC>_KpGp<ESC>\ is <Ctrl>+<Alt>+x (press)
@@ -141,6 +148,12 @@ For example::
This encoding means each key event is represented by 8 or 9 printable ascii
only bytes, for maximum robustness.
To see the full mode in action, run::
kitty +kitten key_demo
Support for this mode is indicated by the ``fullkbd`` boolean capability
in the terminfo database, in case querying for it via DECQRM is inconvenient.
.. _ext_styles:
@@ -158,7 +171,7 @@ The motivation for this extension is the various problems with the existing
solution for erasing to background color, namely the *background color erase
(bce)* capability. See
`this discussion <https://github.com/kovidgoyal/kitty/issues/160#issuecomment-346470545>`_
and `this FAQ <http://invisible-island.net/ncurses/ncurses.faq.html#bce_mismatches>`_
and `this FAQ <https://invisible-island.net/ncurses/ncurses.faq.html#bce_mismatches>`_
for a summary of problems with *bce*.
For example, to set the background color to blue in a
@@ -206,3 +219,7 @@ first, for example::
<ESC>]52;c;!<ESC>\
Here ``!`` is not valid base64 encoded text, so it clears the clipboard.
In case you're using software that can't be easily adapted to this
protocol extension, it can be disabled by specifying ``no-append`` to the
:opt:`clipboard_control` setting.

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 ot 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 dont 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

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# vim:fileencoding=utf-8
# License: GPLv3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
@@ -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

@@ -3,6 +3,7 @@
# License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
import os
import re
import sys
from collections import defaultdict
from contextlib import contextmanager
@@ -87,6 +88,11 @@ def parse_ucd():
if category.startswith('M'):
marks.add(codepoint)
# Some common synonyms
word_search_map['bee'] |= word_search_map['honeybee']
word_search_map['lambda'] |= word_search_map['lamda']
word_search_map['lamda'] |= word_search_map['lambda']
def split_two(line):
spec, rest = line.split(';', 1)
@@ -276,7 +282,8 @@ def gen_ucd():
p('combining_type mark_for_codepoint(char_type c) {')
rmap = codepoint_to_mark_map(p, mark_map)
p('}\n')
if rmap[0xfe0e] != 1281:
expected = int(re.search(r'^#define VS15 (\d+)', open('kitty/unicode-data.h').read(), 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]
))
@@ -360,16 +367,15 @@ def gen_names():
root = TrieNode()
all_trie_nodes.append(root)
def add_word(word_idx):
word = word_map[word_idx]
def add_word(word_idx, word):
parent = root
for letter in map(ord, word):
idx = parent.add_letter(letter)
parent = all_trie_nodes[idx]
parent.match_offset = offsets_array[word_idx]
for i in range(len(word_map)):
add_word(i)
for i, word in enumerate(word_map):
add_word(i, word)
children_array = [0]
for node in all_trie_nodes:
if node.children:

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__':

124
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>
@@ -21,16 +23,16 @@
#endif
static inline double
monotonic() {
monotonic(void) {
struct timespec ts = {0};
#ifdef CLOCK_HIGHRES
clock_gettime(CLOCK_HIGHRES, &ts);
clock_gettime(CLOCK_HIGHRES, &ts);
#elif CLOCK_MONOTONIC_RAW
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
#else
clock_gettime(CLOCK_MONOTONIC, &ts);
clock_gettime(CLOCK_MONOTONIC, &ts);
#endif
return (((double)ts.tv_nsec) / 1e9) + (double)ts.tv_sec;
return (((double)ts.tv_nsec) / 1e9) + (double)ts.tv_sec;
}
void
@@ -55,6 +57,7 @@ addWatch(EventLoopData *eld, const char* name, int fd, int events, int enabled,
w->fd = fd; w->events = events; w->enabled = enabled;
w->callback = cb;
w->callback_data = cb_data;
w->free = NULL;
w->id = ++watch_counter;
update_fds(eld);
return w->id;
@@ -64,6 +67,10 @@ addWatch(EventLoopData *eld, const char* name, int fd, int events, int enabled,
for (nfds_t i = 0; i < eld->which##_count; i++) { \
if (eld->which[i].id == item_id) { \
eld->which##_count--; \
if (eld->which[i].callback_data && eld->which[i].free) { \
eld->which[i].free(eld->which[i].id, eld->which[i].callback_data); \
eld->which[i].callback_data = NULL; eld->which[i].free = NULL; \
} \
if (i < eld->which##_count) { \
memmove(eld->which + i, eld->which + i + 1, sizeof(eld->which[0]) * (eld->which##_count - i)); \
} \
@@ -102,7 +109,7 @@ update_timers(EventLoopData *eld) {
}
id_type
addTimer(EventLoopData *eld, const char *name, double interval, int enabled, timer_callback_func cb, void *cb_data) {
addTimer(EventLoopData *eld, const char *name, double interval, int enabled, bool repeats, timer_callback_func cb, void *cb_data, GLFWuserdatafreefun free) {
if (eld->timers_count >= sizeof(eld->timers)/sizeof(eld->timers[0])) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Too many timers added");
return 0;
@@ -111,11 +118,13 @@ addTimer(EventLoopData *eld, const char *name, double interval, int enabled, tim
t->interval = interval;
t->name = name;
t->trigger_at = enabled ? monotonic() + interval : DBL_MAX;
t->repeats = repeats;
t->callback = cb;
t->callback_data = cb_data;
t->free = free;
t->id = ++timer_counter;
update_timers(eld);
return t->id;
return timer_counter;
}
void
@@ -123,6 +132,14 @@ removeTimer(EventLoopData *eld, id_type timer_id) {
removeX(timers, timer_id, update_timers);
}
void
removeAllTimers(EventLoopData *eld) {
for (nfds_t i = 0; i < eld->timers_count; i++) {
if (eld->timers[i].free && eld->timers[i].callback_data) eld->timers[i].free(eld->timers[i].id, eld->timers[i].callback_data);
}
eld->timers_count = 0;
}
void
toggleTimer(EventLoopData *eld, id_type timer_id, int enabled) {
for (nfds_t i = 0; i < eld->timers_count; i++) {
@@ -182,7 +199,7 @@ dispatchEvents(EventLoopData *eld) {
unsigned
dispatchTimers(EventLoopData *eld) {
if (!eld->timers_count || eld->timers[0].trigger_at == DBL_MAX) return 0;
static struct { timer_callback_func func; id_type id; void* data; } dispatches[sizeof(eld->timers)/sizeof(eld->timers[0])];
static struct { timer_callback_func func; id_type id; void* data; bool repeats; } dispatches[sizeof(eld->timers)/sizeof(eld->timers[0])];
unsigned num_dispatches = 0;
double now = monotonic();
for (nfds_t i = 0; i < eld->timers_count && eld->timers[i].trigger_at <= now; i++) {
@@ -190,35 +207,105 @@ dispatchTimers(EventLoopData *eld) {
dispatches[num_dispatches].func = eld->timers[i].callback;
dispatches[num_dispatches].id = eld->timers[i].id;
dispatches[num_dispatches].data = eld->timers[i].callback_data;
dispatches[num_dispatches].repeats = eld->timers[i].repeats;
num_dispatches++;
}
// we dispatch separately so that the callbacks can modify timers
for (unsigned i = 0; i < num_dispatches; i++) {
dispatches[i].func(dispatches[i].id, dispatches[i].data);
if (!dispatches[i].repeats) {
removeTimer(eld, dispatches[i].id);
}
}
if (num_dispatches) update_timers(eld);
return num_dispatches;
}
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) {
@@ -251,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
//

29
glfw/backend_utils.h vendored
View File

@@ -27,15 +27,28 @@
#pragma once
#include <poll.h>
#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*);
typedef void (* GLFWuserdatafreefun)(id_type, void*);
typedef struct {
int fd, events, enabled, ready;
watch_callback_func callback;
void *callback_data;
GLFWuserdatafreefun free;
id_type id;
const char *name;
} Watch;
@@ -45,30 +58,40 @@ typedef struct {
double interval, trigger_at;
timer_callback_func callback;
void *callback_data;
GLFWuserdatafreefun free;
const char *name;
bool repeats;
} Timer;
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);
id_type addTimer(EventLoopData *eld, const char *name, double interval, int enabled, timer_callback_func cb, void *cb_data);
id_type addTimer(EventLoopData *eld, const char *name, double interval, int enabled, bool repeats, timer_callback_func cb, void *cb_data, GLFWuserdatafreefun free);
void removeTimer(EventLoopData *eld, id_type timer_id);
void removeAllTimers(EventLoopData *eld);
void toggleTimer(EventLoopData *eld, id_type timer_id, int enabled);
void changeTimerInterval(EventLoopData *eld, id_type timer_id, double interval);
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
//------------------------------------------------------------------------
// 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,10 +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
//
@@ -198,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)
{
@@ -215,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 =
@@ -225,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 =
@@ -242,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"));
@@ -265,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 =
@@ -274,16 +276,40 @@ static GLFWbool initializeTIS(void)
return updateUnicodeDataNS();
}
@interface GLFWLayoutListener : NSObject
@interface GLFWHelper : NSObject
@end
@implementation GLFWLayoutListener
@implementation GLFWHelper
- (void)selectedKeyboardInputSourceChanged:(NSObject* )object
{
(void)object;
updateUnicodeDataNS();
}
- (void)doNothing:(id)object
{
(void)object;
}
@end // GLFWHelper
@interface GLFWApplication : NSApplication
- (void)tick_callback;
- (void)render_frame_received:(id)displayIDAsID;
@end
@implementation GLFWApplication
- (void)tick_callback
{
_glfwDispatchTickCallback();
}
- (void)render_frame_received:(id)displayIDAsID
{
CGDirectDisplayID displayID = [(NSNumber*)displayIDAsID unsignedIntValue];
_glfwDispatchRenderFrame(displayID);
}
@end
@@ -291,16 +317,76 @@ static GLFWbool initializeTIS(void)
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
static inline bool
is_ctrl_tab(NSEvent *event, NSEventModifierFlags modifierFlags) {
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) {
if (modifierFlags != NSEventModifierFlagCommand) return false;
if ([event.charactersIgnoringModifiers isEqualToString:@"."]) return true;
return false;
}
int _glfwPlatformInit(void)
{
_glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init];
@autoreleasepool {
_glfw.ns.helper = [[GLFWHelper alloc] init];
[NSThread detachNewThreadSelector:@selector(doNothing:)
toTarget:_glfw.ns.helper
withObject:nil];
[GLFWApplication sharedApplication];
NSEvent* (^keydown_block)(NSEvent*) = ^ NSEvent* (NSEvent* event)
{
NSEventModifierFlags modifierFlags = [event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
if (is_ctrl_tab(event, modifierFlags) || is_cmd_period(event, modifierFlags)) {
// Cocoa swallows Ctrl+Tab to cycle between views
[[NSApp keyWindow].contentView keyDown:event];
}
return event;
};
NSEvent* (^keyup_block)(NSEvent*) = ^ NSEvent* (NSEvent* event)
{
NSEventModifierFlags modifierFlags = [event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
if (modifierFlags & NSEventModifierFlagCommand) {
// From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost
// This works around an AppKit bug, where key up events while holding
// down the command key don't get sent to the key window.
[[NSApp keyWindow] sendEvent:event];
}
if (is_ctrl_tab(event, modifierFlags) || is_cmd_period(event, modifierFlags)) {
// Cocoa swallows Ctrl+Tab to cycle between views
[[NSApp keyWindow].contentView keyUp:event];
}
return event;
};
_glfw.ns.keyUpMonitor =
[NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskKeyUp
handler:keyup_block];
_glfw.ns.keyDownMonitor =
[NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskKeyDown
handler:keydown_block];
if (_glfw.hints.init.ns.chdir)
changeToResourcesDirectory();
_glfw.ns.listener = [[GLFWLayoutListener alloc] init];
[[NSNotificationCenter defaultCenter]
addObserver:_glfw.ns.listener
addObserver:_glfw.ns.helper
selector:@selector(selectedKeyboardInputSourceChanged:)
name:NSTextInputContextKeyboardSelectionDidChangeNotification
object:nil];
@@ -309,22 +395,28 @@ 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;
_glfwInitTimerNS();
_glfwInitJoysticksNS();
_glfwPollMonitorsNS();
return GLFW_TRUE;
return true;
} // autoreleasepool
}
void _glfwPlatformTerminate(void)
{
@autoreleasepool {
_glfwClearDisplayLinks();
if (_glfw.ns.inputSource)
{
CFRelease(_glfw.ns.inputSource);
@@ -345,32 +437,165 @@ void _glfwPlatformTerminate(void)
_glfw.ns.delegate = nil;
}
if (_glfw.ns.listener)
if (_glfw.ns.helper)
{
[[NSNotificationCenter defaultCenter]
removeObserver:_glfw.ns.listener
removeObserver:_glfw.ns.helper
name:NSTextInputContextKeyboardSelectionDidChangeNotification
object:nil];
[[NSNotificationCenter defaultCenter]
removeObserver:_glfw.ns.listener];
[_glfw.ns.listener release];
_glfw.ns.listener = nil;
removeObserver:_glfw.ns.helper];
[_glfw.ns.helper release];
_glfw.ns.helper = nil;
}
if (_glfw.ns.keyUpMonitor)
[NSEvent removeMonitor:_glfw.ns.keyUpMonitor];
if (_glfw.ns.keyDownMonitor)
[NSEvent removeMonitor:_glfw.ns.keyDownMonitor];
free(_glfw.ns.clipboardString);
_glfwTerminateNSGL();
_glfwTerminateJoysticksNS();
[_glfw.ns.autoreleasePool release];
_glfw.ns.autoreleasePool = nil;
} // autoreleasepool
}
const char* _glfwPlatformGetVersionString(void)
{
return _GLFW_VERSION_NUMBER " Cocoa NSGL"
return _GLFW_VERSION_NUMBER " Cocoa NSGL EGL OSMesa"
#if defined(_GLFW_BUILD_DLL)
" dynamic"
#endif
;
}
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_lock && tick_callback) {
[tick_lock lock];
while(tick_callback_requested) {
tick_callback_requested = false;
tick_callback(tick_callback_data);
}
[tick_lock unlock];
}
}
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) {
[NSApp stop:nil];
_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;
}
typedef struct {
NSTimer *os_timer;
unsigned long long id;
bool repeats;
double interval;
GLFWuserdatafun callback;
void *callback_data;
GLFWuserdatafun free_callback_data;
} Timer;
static Timer timers[128] = {{0}};
static size_t num_timers = 0;
static inline void
remove_timer_at(size_t idx) {
if (idx < num_timers) {
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; }
remove_i_from_array(timers, idx, num_timers);
}
}
static void schedule_timer(Timer *t) {
t->os_timer = [NSTimer scheduledTimerWithTimeInterval:t->interval repeats:(t->repeats ? YES: NO) block:^(NSTimer *os_timer) {
for (size_t i = 0; i < num_timers; i++) {
if (timers[i].os_timer == os_timer) {
timers[i].callback(timers[i].id, timers[i].callback_data);
if (!timers[i].repeats) remove_timer_at(i);
break;
}
}
}];
}
unsigned long long _glfwPlatformAddTimer(double interval, bool repeats, GLFWuserdatafun callback, void *callback_data, GLFWuserdatafun free_callback) {
static unsigned long long timer_counter = 0;
if (num_timers >= sizeof(timers)/sizeof(timers[0]) - 1) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Too many timers added");
return 0;
}
Timer *t = timers + num_timers++;
t->id = ++timer_counter;
t->repeats = repeats;
t->interval = interval;
t->callback = callback;
t->callback_data = callback_data;
t->free_callback_data = free_callback;
schedule_timer(t);
return timer_counter;
}
void _glfwPlatformRemoveTimer(unsigned long long timer_id) {
for (size_t i = 0; i < num_timers; i++) {
if (timers[i].id == timer_id) {
remove_timer_at(i);
break;
}
}
}
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;
if (t->os_timer) { [t->os_timer invalidate]; t->os_timer = NULL; }
t->interval = interval;
if (enabled) schedule_timer(t);
break;
}
}
}

View File

@@ -1,7 +1,7 @@
//========================================================================
// GLFW 3.3 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
//------------------------------------------------------------------------
// 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;
@@ -220,9 +222,18 @@ static void matchCallback(void* context,
case kHIDUsage_GD_Hatswitch:
target = hats;
break;
case kHIDUsage_GD_DPadUp:
case kHIDUsage_GD_DPadRight:
case kHIDUsage_GD_DPadDown:
case kHIDUsage_GD_DPadLeft:
case kHIDUsage_GD_SystemMainMenu:
case kHIDUsage_GD_Select:
case kHIDUsage_GD_Start:
target = buttons;
break;
}
}
else if (page == kHIDPage_Button)
else if (page == kHIDPage_Button || page == kHIDPage_Consumer)
target = buttons;
if (target)
@@ -261,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;
@@ -307,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;
@@ -397,12 +408,12 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
if (raw > axis->maximum)
axis->maximum = raw;
const long delta = axis->maximum - axis->minimum;
if (delta == 0)
const long size = axis->maximum - axis->minimum;
if (size == 0)
_glfwInputJoystickAxis(js, (int) i, 0.f);
else
{
const float value = (2.f * (raw - axis->minimum) / delta) - 1.f;
const float value = (2.f * (raw - axis->minimum) / size) - 1.f;
_glfwInputJoystickAxis(js, (int) i, value);
}
}
@@ -417,7 +428,8 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
_GLFWjoyelementNS* button = (_GLFWjoyelementNS*)
CFArrayGetValueAtIndex(js->ns.buttons, i);
const char value = getElementValue(js, button) - button->minimum;
_glfwInputJoystickButton(js, (int) i, value);
const int state = (value > 0) ? GLFW_PRESS : GLFW_RELEASE;
_glfwInputJoystickButton(js, (int) i, state);
}
for (i = 0; i < CFArrayGetCount(js->ns.hats); i++)
@@ -454,9 +466,8 @@ void _glfwPlatformUpdateGamepadGUID(char* guid)
(strncmp(guid + 20, "000000000000", 12) == 0))
{
char original[33];
strcpy(original, guid);
strncpy(original, guid, sizeof(original) - 1);
sprintf(guid, "03000000%.4s0000%.4s000000000000",
original, original + 16);
}
}

View File

@@ -2,7 +2,7 @@
// GLFW 3.3 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,11 +24,14 @@
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include "internal.h"
#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include <IOKit/graphics/IOGraphicsLib.h>
#include <CoreVideo/CVBase.h>
@@ -115,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);
@@ -132,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
@@ -148,7 +151,7 @@ static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode,
GLFWvidmode result;
result.width = (int) CGDisplayModeGetWidth(mode);
result.height = (int) CGDisplayModeGetHeight(mode);
result.refreshRate = (int) CGDisplayModeGetRefreshRate(mode);
result.refreshRate = (int) round(CGDisplayModeGetRefreshRate(mode));
if (result.refreshRate == 0)
{
@@ -212,27 +215,87 @@ static void endFadeReservation(CGDisplayFadeReservationToken token)
}
}
// Finds and caches the NSScreen corresponding to the specified monitor
//
static bool refreshMonitorScreen(_GLFWmonitor* monitor)
{
if (monitor->ns.screen)
return true;
for (NSScreen* screen in [NSScreen screens])
{
NSNumber* displayID = [screen deviceDescription][@"NSScreenNumber"];
// HACK: Compare unit numbers instead of display IDs to work around
// display replacement on machines with automatic graphics
// switching
if (monitor->ns.unitNumber == CGDisplayUnitNumber([displayID unsignedIntValue]))
{
monitor->ns.screen = screen;
return true;
}
}
_glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to find a screen for monitor");
return false;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
void _glfwClearDisplayLinks() {
for (size_t i = 0; i < _glfw.ns.displayLinks.count; i++) {
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;
}
static CVReturn displayLinkCallback(
CVDisplayLinkRef displayLink UNUSED,
const CVTimeStamp* now UNUSED, const CVTimeStamp* outputTime UNUSED,
CVOptionFlags flagsIn UNUSED, CVOptionFlags* flagsOut UNUSED, void* userInfo)
{
CGDirectDisplayID displayID = (CGDirectDisplayID)userInfo;
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) {
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;
}
_GLFWDisplayLinkNS *entry = &_glfw.ns.displayLinks.entries[_glfw.ns.displayLinks.count++];
memset(entry, 0, sizeof(_GLFWDisplayLinkNS));
entry->displayID = displayID;
CVDisplayLinkCreateWithCGDisplay(displayID, &entry->displayLink);
CVDisplayLinkSetOutputCallback(entry->displayLink, &displayLinkCallback, (void*)(uintptr_t)displayID);
}
// 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*));
@@ -241,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;
@@ -266,16 +328,17 @@ 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);
free(name);
_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);
@@ -283,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))
@@ -355,7 +415,7 @@ void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor)
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor UNUSED)
{
}
@@ -372,35 +432,8 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
float* xscale, float* yscale)
{
if (!monitor->ns.screen)
{
NSUInteger i;
NSArray* screens = [NSScreen screens];
for (i = 0; i < [screens count]; i++)
{
NSScreen* screen = [screens objectAtIndex:i];
NSNumber* displayID =
[[screen deviceDescription] objectForKey:@"NSScreenNumber"];
// HACK: Compare unit numbers instead of display IDs to work around
// display replacement on machines with automatic graphics
// switching
if (monitor->ns.unitNumber ==
CGDisplayUnitNumber([displayID unsignedIntValue]))
{
monitor->ns.screen = screen;
break;
}
}
if (i == [screens count])
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to find a screen for monitor");
return;
}
}
if (!refreshMonitorScreen(monitor))
return;
const NSRect points = [monitor->ns.screen frame];
const NSRect pixels = [monitor->ns.screen convertRectToBacking:points];
@@ -411,22 +444,38 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
*yscale = (float) (pixels.size.height / points.size.height);
}
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
int* xpos, int* ypos,
int* width, int* height)
{
if (!refreshMonitorScreen(monitor))
return;
const NSRect frameRect = [monitor->ns.screen visibleFrame];
if (xpos)
*xpos = frameRect.origin.x;
if (ypos)
*ypos = _glfwTransformYNS(frameRect.origin.y + frameRect.size.height - 1);
if (width)
*width = frameRect.size.width;
if (height)
*height = frameRect.size.height;
}
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))
@@ -434,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;
@@ -455,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);
}
void _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,
@@ -481,7 +529,7 @@ void _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);
@@ -489,14 +537,14 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
}
free(values);
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;
@@ -523,4 +571,3 @@ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* handle)
_GLFW_REQUIRE_INIT_OR_RETURN(kCGNullDirectDisplay);
return monitor->ns.displayID;
}

75
glfw/cocoa_platform.h vendored
View File

@@ -1,7 +1,7 @@
//========================================================================
// GLFW 3.3 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
@@ -27,19 +27,46 @@
#include <stdint.h>
#include <dlfcn.h>
#if defined(__OBJC__)
#import <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h>
#else
#include <Carbon/Carbon.h>
#include <ApplicationServices/ApplicationServices.h>
#if defined(__OBJC__)
#import <Cocoa/Cocoa.h>
#import <CoreVideo/CoreVideo.h>
#else
typedef void* id;
typedef void* CVDisplayLinkRef;
#endif
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200
#define NSBitmapFormatAlphaNonpremultiplied NSAlphaNonpremultipliedBitmapFormat
#define NSEventMaskAny NSAnyEventMask
#define NSEventMaskKeyUp NSKeyUpMask
#define NSEventModifierFlagCapsLock NSAlphaShiftKeyMask
#define NSEventModifierFlagCommand NSCommandKeyMask
#define NSEventModifierFlagControl NSControlKeyMask
#define NSEventModifierFlagDeviceIndependentFlagsMask NSDeviceIndependentModifierFlagsMask
#define NSEventModifierFlagOption NSAlternateKeyMask
#define NSEventModifierFlagShift NSShiftKeyMask
#define NSEventTypeApplicationDefined NSApplicationDefined
#define NSWindowStyleMaskBorderless NSBorderlessWindowMask
#define NSWindowStyleMaskClosable NSClosableWindowMask
#define NSWindowStyleMaskMiniaturizable NSMiniaturizableWindowMask
#define NSWindowStyleMaskResizable NSResizableWindowMask
#define NSWindowStyleMaskTitled NSTitledWindowMask
#endif
#if (MAC_OS_X_VERSION_MAX_ALLOWED < 101400)
#define NSPasteboardTypeFileURL NSFilenamesPboardType
#define NSBitmapFormatAlphaNonpremultiplied NSAlphaNonpremultipliedBitmapFormat
#define NSPasteboardTypeString NSStringPboardType
#define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity
#endif
typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
typedef int (* GLFWcocoatextinputfilterfun)(int,int,int);
typedef int (* GLFWcocoatextinputfilterfun)(int,int,unsigned int, unsigned long);
typedef int (* GLFWapplicationshouldhandlereopenfun)(int);
typedef int (* GLFWcocoatogglefullscreenfun)(GLFWwindow*);
typedef void (* GLFWcocoarenderframefun)(GLFWwindow*);
typedef struct VkMacOSSurfaceCreateInfoMVK
{
@@ -89,7 +116,8 @@ typedef struct _GLFWwindowNS
id view;
id layer;
GLFWbool maximized;
bool maximized;
bool retina;
// Cached window properties to filter out duplicate events
int width, height;
@@ -107,20 +135,31 @@ typedef struct _GLFWwindowNS
GLFWcocoatogglefullscreenfun toggleFullscreenCallback;
// Dead key state
UInt32 deadKeyState;
// Whether a render frame has been requested for this window
bool renderFrameRequested;
GLFWcocoarenderframefun renderFrameCallback;
} _GLFWwindowNS;
typedef struct _GLFWDisplayLinkNS
{
CVDisplayLinkRef displayLink;
CGDirectDisplayID displayID;
double lastRenderFrameRequestedAt;
} _GLFWDisplayLinkNS;
// Cocoa-specific global data
//
typedef struct _GLFWlibraryNS
{
CGEventSourceRef eventSource;
id delegate;
id autoreleasePool;
GLFWbool cursorHidden;
bool cursorHidden;
TISInputSourceRef inputSource;
IOHIDManagerRef hidManager;
id unicodeData;
id listener;
id helper;
id keyUpMonitor;
id keyDownMonitor;
char keyName[64];
char text[256];
@@ -141,6 +180,11 @@ typedef struct _GLFWlibraryNS
CFStringRef kPropertyUnicodeKeyLayoutData;
} tis;
struct {
_GLFWDisplayLinkNS entries[256];
size_t count;
} displayLinks;
} _GLFWlibraryNS;
// Cocoa-specific per-monitor data
@@ -176,3 +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 _glfwRestartDisplayLinks(void);
void _glfwDispatchTickCallback(void);
void _glfwDispatchRenderFrame(CGDirectDisplayID);
void _glfwShutdownCVDisplayLink(unsigned long long, void*);
void _glfwCocoaPostEmptyEvent(void);

2
glfw/cocoa_time.c vendored
View File

@@ -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

71
glfw/context.c vendored
View File

@@ -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;
@@ -358,7 +360,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
window->context.source = ctxconfig->source;
window->context.client = GLFW_OPENGL_API;
previous = _glfwPlatformGetTls(&_glfw.contextSlot);;
previous = _glfwPlatformGetTls(&_glfw.contextSlot);
glfwMakeContextCurrent((GLFWwindow*) window);
window->context.GetIntegerv = (PFNGLGETINTEGERVPROC)
@@ -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
@@ -755,4 +757,3 @@ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
return window->context.getProcAddress(procname);
}

134
glfw/dbus_glfw.c vendored
View File

@@ -43,16 +43,17 @@ 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;
@@ -83,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);
@@ -108,7 +109,7 @@ add_dbus_timeout(DBusTimeout *timeout, void *data) {
int enabled = dbus_timeout_get_enabled(timeout) ? 1 : 0;
double interval = ((double)dbus_timeout_get_interval(timeout)) / 1000.0;
if (interval < 0) return FALSE;
id_type timer_id = addTimer(dbus_data->eld, data, interval, enabled, on_dbus_timer_ready, timeout);
id_type timer_id = addTimer(dbus_data->eld, data, interval, enabled, true, on_dbus_timer_ready, timeout, NULL);
if (!timer_id) return FALSE;
id_type *idp = malloc(sizeof(id_type));
if (!idp) {
@@ -122,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);
@@ -172,11 +173,20 @@ glfw_dbus_dispatch(DBusConnection *conn) {
}
void
glfw_dbus_terminate(_GLFWDBUSData *dbus) {
glfw_dbus_session_bus_dispatch() {
if (session_bus) glfw_dbus_dispatch(session_bus);
}
void
glfw_dbus_terminate(_GLFWDBUSData *dbus UNUSED) {
if (dbus_data) {
dbus_data->eld = NULL;
dbus_data = NULL;
}
if (session_bus) {
dbus_connection_unref(session_bus);
session_bus = NULL;
}
}
void
@@ -185,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;
@@ -223,34 +233,43 @@ method_reply_received(DBusPendingCall *pending, void *user_data) {
}
}
static GLFWbool
bool
call_method_with_msg(DBusConnection *conn, DBusMessage *msg, int timeout, dbus_pending_callback callback, void *user_data) {
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 false;
res->callback = callback;
res->user_data = user_data;
dbus_pending_call_set_notify(pending, method_reply_received, res, free);
retval = true;
} else {
REPORT("out of memory");
}
} else {
if (dbus_connection_send(conn, msg, NULL)) {
retval = true;
} else {
REPORT("out of memory");
}
}
return retval;
#undef REPORT
}
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;
MethodResponse *res = malloc(sizeof(MethodResponse));
if (!res) { dbus_message_unref(msg); return GLFW_FALSE; }
res->callback = callback;
res->user_data = user_data;
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)) {
if (callback) {
DBusPendingCall *pending = NULL;
if (dbus_connection_send_with_reply(conn, msg, &pending, timeout)) {
dbus_pending_call_set_notify(pending, method_reply_received, res, free);
retval = GLFW_TRUE;
} else {
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to call DBUS method: %s on node: %s and interface: %s out of memory", method, node, interface);
}
} else {
if (dbus_connection_send(conn, msg, NULL)) {
retval = GLFW_TRUE;
} else {
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to call DBUS method: %s on node: %s and interface: %s out of memory", method, node, interface);
}
}
retval = call_method_with_msg(conn, msg, timeout, callback, user_data);
} else {
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to call DBUS method: %s on node: %s and interface: %s could not add arguments", method, node, interface);
}
@@ -259,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);
@@ -269,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);
@@ -293,3 +312,38 @@ glfw_dbus_match_signal(DBusMessage *msg, const char *interface, ...) {
va_end(ap);
return ans;
}
static void
glfw_dbus_connect_to_session_bus(void) {
DBusError error;
dbus_error_init(&error);
if (session_bus) {
dbus_connection_unref(session_bus);
}
session_bus = dbus_bus_get(DBUS_BUS_SESSION, &error);
if (dbus_error_is_set(&error)) {
report_error(&error, "Failed to connect to DBUS session bus");
session_bus = NULL;
return;
}
static const char *name = "session-bus";
if (!dbus_connection_set_watch_functions(session_bus, add_dbus_watch, remove_dbus_watch, toggle_dbus_watch, (void*)name, NULL)) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to set DBUS watches on connection to: %s", name);
dbus_connection_close(session_bus);
dbus_connection_unref(session_bus);
return;
}
if (!dbus_connection_set_timeout_functions(session_bus, add_dbus_timeout, remove_dbus_timeout, toggle_dbus_timeout, (void*)name, NULL)) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to set DBUS timeout functions on connection to: %s", name);
dbus_connection_close(session_bus);
dbus_connection_unref(session_bus);
return;
}
}
DBusConnection *
glfw_dbus_session_bus() {
if (!session_bus) glfw_dbus_connect_to_session_bus();
return session_bus;
}

14
glfw/dbus_glfw.h vendored
View File

@@ -37,14 +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);
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 *);
GLFWbool glfw_dbus_get_args(DBusMessage *msg, const char *failmsg, ...);
void glfw_dbus_session_bus_dispatch(void);
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);

120
glfw/egl_context.c vendored
View File

@@ -2,7 +2,7 @@
// GLFW 3.3 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,11 +593,20 @@ 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;
EGLint a = EGL_MIN_SWAP_INTERVAL;
if (!eglGetConfigAttrib(_glfw.egl.display, config, a, &a)) {
_glfwInputError(GLFW_VERSION_UNAVAILABLE, "EGL: could not check for non-blocking buffer swap with error: %s", getEGLErrorString(eglGetError()));
} else {
if (a > 0) {
_glfwInputError(GLFW_VERSION_UNAVAILABLE, "EGL: non-blocking swap buffers not available, minimum swap interval is: %d", a);
}
}
// Load the appropriate client library
if (!_glfw.egl.KHR_get_all_proc_addresses)
{
@@ -686,7 +681,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to load client library");
return GLFW_FALSE;
return false;
}
}
@@ -697,7 +692,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
window->context.getProcAddress = getProcAddressEGL;
window->context.destroy = destroyContextEGL;
return GLFW_TRUE;
return true;
}
#undef setAttrib
@@ -705,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)
@@ -720,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,
@@ -734,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
@@ -783,4 +778,3 @@ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle)
return window->context.egl.surface;
}

43
glfw/egl_context.h vendored
View File

@@ -2,7 +2,7 @@
// GLFW 3.3 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
@@ -43,34 +43,30 @@ typedef Window EGLNativeWindowType;
#define EGLAPIENTRY
typedef struct wl_display* EGLNativeDisplayType;
typedef struct wl_egl_window* EGLNativeWindowType;
#elif defined(_GLFW_MIR)
#define EGLAPIENTRY
typedef MirEGLNativeDisplayType EGLNativeDisplayType;
typedef MirEGLNativeWindowType EGLNativeWindowType;
#else
#error "No supported EGL platform selected"
#endif
#define EGL_SUCCESS 0x3000
#define EGL_NOT_INITIALIZED 0x3001
#define EGL_SUCCESS 0x3000
#define EGL_NOT_INITIALIZED 0x3001
#define EGL_BAD_ACCESS 0x3002
#define EGL_BAD_ALLOC 0x3003
#define EGL_BAD_ATTRIBUTE 0x3004
#define EGL_BAD_CONFIG 0x3005
#define EGL_BAD_CONTEXT 0x3006
#define EGL_BAD_CURRENT_SURFACE 0x3007
#define EGL_BAD_DISPLAY 0x3008
#define EGL_BAD_CONTEXT 0x3006
#define EGL_BAD_CURRENT_SURFACE 0x3007
#define EGL_BAD_DISPLAY 0x3008
#define EGL_BAD_MATCH 0x3009
#define EGL_BAD_NATIVE_PIXMAP 0x300a
#define EGL_BAD_NATIVE_WINDOW 0x300b
#define EGL_BAD_PARAMETER 0x300c
#define EGL_BAD_SURFACE 0x300d
#define EGL_BAD_SURFACE 0x300d
#define EGL_CONTEXT_LOST 0x300e
#define EGL_COLOR_BUFFER_TYPE 0x303f
#define EGL_RGB_BUFFER 0x308e
#define EGL_SURFACE_TYPE 0x3033
#define EGL_WINDOW_BIT 0x0004
#define EGL_RENDERABLE_TYPE 0x3040
#define EGL_RENDERABLE_TYPE 0x3040
#define EGL_OPENGL_ES_BIT 0x0001
#define EGL_OPENGL_ES2_BIT 0x0004
#define EGL_OPENGL_BIT 0x0008
@@ -80,7 +76,7 @@ typedef MirEGLNativeWindowType EGLNativeWindowType;
#define EGL_RED_SIZE 0x3024
#define EGL_DEPTH_SIZE 0x3025
#define EGL_STENCIL_SIZE 0x3026
#define EGL_SAMPLES 0x3031
#define EGL_SAMPLES 0x3031
#define EGL_OPENGL_ES_API 0x30a0
#define EGL_OPENGL_API 0x30a2
#define EGL_NONE 0x3038
@@ -91,6 +87,8 @@ typedef MirEGLNativeWindowType EGLNativeWindowType;
#define EGL_NO_DISPLAY ((EGLDisplay) 0)
#define EGL_NO_CONTEXT ((EGLContext) 0)
#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType) 0)
#define EGL_MIN_SWAP_INTERVAL 0x303B
#define EGL_MAX_SWAP_INTERVAL 0x303C
#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
@@ -175,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;
@@ -205,15 +203,14 @@ 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);
#endif /*_GLFW_X11*/

View File

@@ -1,11 +1,10 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
import json
import os
import re
import shutil
import sys
_plat = sys.platform.lower()
@@ -22,20 +21,17 @@ def wayland_protocol_file_name(base, ext='c'):
return 'wayland-{}-client-protocol.{}'.format(base, ext)
def init_env(env, pkg_config, at_least_version, module='x11'):
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.cflags.append('-D_GLFW_' + module.upper())
ans.cflags.append('-D_GLFW_BUILD_DLL')
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()
@@ -76,11 +72,20 @@ def init_env(env, pkg_config, at_least_version, module='x11'):
for dep in 'wayland-egl wayland-client wayland-cursor xkbcommon dbus-1'.split():
ans.cflags.extend(pkg_config(dep, '--cflags-only-I'))
ans.ldpaths.extend(pkg_config(dep, '--libs'))
has_memfd_create = test_compile(env.cc, '-Werror', src='''#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
int main(void) {
return syscall(__NR_memfd_create, "test", 0);
}''')
if has_memfd_create:
ans.cppflags.append('-DHAS_MEMFD_CREATE')
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):
@@ -90,42 +95,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))))
def collect_source_information():
raw = open('src/CMakeLists.txt').read()
mraw = open('CMakeLists.txt').read()
def extract_sources(group, start_pos=0):
for which in 'HEADERS SOURCES'.split():
yield which.lower(), list(filter(
lambda x: x[0] not in '"$',
re.search(
r'{0}_{1}\s+([^)]+?)[)]'.format(group, which),
raw[start_pos:]
).group(1).strip().split()
))
wayland_protocols = re.search(r'WaylandProtocols\s+(\S+)\s+', mraw).group(1)
wayland_protocols = list(map(int, wayland_protocols.split('.')))
ans = {
'common': dict(extract_sources('common')),
'wayland_protocols': wayland_protocols,
}
for group in 'cocoa win32 x11 wayland osmesa'.split():
m = re.search('_GLFW_' + group.upper(), raw)
ans[group] = dict(extract_sources('glfw', m.start()))
if group in ('x11', 'wayland'):
for joystick in ('linux', 'null'):
ans[group]['headers'].append('{}_joystick.h'.format(joystick))
ans[group]['sources'].append('{}_joystick.c'.format(joystick))
if group == 'wayland':
ans[group]['protocols'] = p = []
for m in re.finditer(r'WAYLAND_PROTOCOLS_PKGDATADIR\}/(.+?)"?$', raw, flags=re.M):
p.append(m.group(1))
return ans
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:
@@ -160,6 +135,8 @@ class Function:
if a == 'void':
continue
self.args.append(Arg(a))
if not self.args:
self.args = [Arg('void v')]
def declaration(self):
return 'typedef {restype} (*{name}_func)({args});\n{name}_func {name}_impl;\n#define {name} {name}_impl'.format(
@@ -179,7 +156,7 @@ class Function:
return ans
def generate_wrappers(glfw_header, glfw_native_header):
def generate_wrappers(glfw_header):
src = open(glfw_header).read()
functions = []
first = None
@@ -192,16 +169,22 @@ def generate_wrappers(glfw_header, glfw_native_header):
functions.append(Function(decl))
for line in '''\
void* glfwGetCocoaWindow(GLFWwindow* window)
void* glfwGetNSGLContext(GLFWwindow *window)
uint32_t glfwGetCocoaMonitor(GLFWmonitor* monitor)
GLFWcocoatextinputfilterfun glfwSetCocoaTextInputFilter(GLFWwindow* window, GLFWcocoatextinputfilterfun callback)
GLFWcocoatogglefullscreenfun glfwSetCocoaToggleFullscreenIntercept(GLFWwindow *window, GLFWcocoatogglefullscreenfun callback)
GLFWapplicationshouldhandlereopenfun glfwSetApplicationShouldHandleReopen(GLFWapplicationshouldhandlereopenfun callback)
void glfwGetCocoaKeyEquivalent(int glfw_key, int glfw_mods, void* cocoa_key, void* cocoa_mods)
void glfwCocoaRequestRenderFrame(GLFWwindow *w, GLFWcocoarenderframefun callback)
void* glfwGetX11Display(void)
int32_t glfwGetX11Window(GLFWwindow* window)
void glfwSetX11SelectionString(const char* string)
const char* glfwGetX11SelectionString(void)
void glfwSetPrimarySelectionString(GLFWwindow* window, const char* string)
const char* glfwGetPrimarySelectionString(GLFWwindow* window, void)
int glfwGetXKBScancode(const char* key_name, int case_sensitive)
void glfwRequestWaylandFrameEvent(GLFWwindow *handle, unsigned long long id, GLFWwaylandframecallbackfunc callback)
unsigned long long glfwDBusUserNotify(const char *app_name, const char* icon, const char *summary, const char *body, \
const char *action_text, int32_t timeout, GLFWDBusnotificationcreatedfun callback, void *data)
void glfwDBusSetUserNotificationHandler(GLFWDBusnotificationactivatedfun handler)
'''.splitlines():
if line:
functions.append(Function(line.strip(), check_fail=False))
@@ -217,10 +200,13 @@ def generate_wrappers(glfw_header, glfw_native_header):
{}
typedef int (* GLFWcocoatextinputfilterfun)(int,int,unsigned int);
typedef int (* GLFWcocoatextinputfilterfun)(int,int,unsigned int,unsigned long);
typedef int (* GLFWapplicationshouldhandlereopenfun)(int);
typedef int (* GLFWcocoatogglefullscreenfun)(GLFWwindow*);
typedef void (* GLFWcocoarenderframefun)(GLFWwindow*);
typedef void (*GLFWwaylandframecallbackfunc)(unsigned long long id);
typedef void (*GLFWDBusnotificationcreatedfun)(unsigned long long, uint32_t, void*);
typedef void (*GLFWDBusnotificationactivatedfun)(uint32_t, const char*);
{}
const char* load_glfw(const char* path);
@@ -250,7 +236,7 @@ load_glfw(const char* path) {
}
void
unload_glfw() {
unload_glfw(void) {
if (handle) { dlclose(handle); handle = NULL; }
}
'''.replace('LOAD', '\n\n '.join(f.load() for f in functions))
@@ -258,53 +244,9 @@ unload_glfw() {
f.write(code)
def from_glfw(glfw_dir):
os.chdir(glfw_dir)
sinfo = collect_source_information()
files_to_copy = set()
for x in sinfo.values():
if isinstance(x, dict):
headers, sources = x['headers'], x['sources']
for name in headers + sources:
files_to_copy.add(os.path.abspath(os.path.join('src', name)))
glfw_header = os.path.abspath('include/GLFW/glfw3.h')
glfw_native_header = os.path.abspath('include/GLFW/glfw3native.h')
os.chdir(base)
for x in os.listdir('.'):
if x.rpartition('.') in ('c', 'h'):
os.unlink(x)
for src in files_to_copy:
shutil.copy2(src, '.')
shutil.copy2(glfw_header, '.')
json.dump(
sinfo,
open('source-info.json', 'w'),
indent=2,
ensure_ascii=False,
sort_keys=True
)
generate_wrappers(glfw_header, glfw_native_header)
def to_glfw(glfw_dir):
src = base
for x in os.listdir(src):
if x in ('glfw.py', 'glfw3.h', '__pycache__', 'source-info.json') or x.startswith('wayland-'):
continue
xp = os.path.join(src, x)
shutil.copyfile(xp, os.path.join(glfw_dir, 'src', x))
shutil.copyfile(os.path.join(src, 'glfw3.h'), os.path.join(glfw_dir, 'include/GLFW/glfw3.h'))
def main():
glfw_dir = os.path.abspath(os.path.join(base, '../../glfw'))
q = sys.argv[1].lower().replace('_', '-')
if q == 'from-glfw':
from_glfw(glfw_dir)
elif q == 'to-glfw':
to_glfw(glfw_dir)
else:
raise SystemExit('First argument must be one of to-glfw or from-glfw')
os.chdir(os.path.dirname(os.path.abspath(__file__)))
generate_wrappers('glfw3.h')
if __name__ == '__main__':

550
glfw/glfw3.h vendored

File diff suppressed because it is too large Load Diff

149
glfw/glx_context.c vendored
View File

@@ -2,7 +2,7 @@
// GLFW 3.3 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;
}

43
glfw/glx_context.h vendored
View File

@@ -2,7 +2,7 @@
// GLFW 3.3 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
@@ -29,11 +29,11 @@
#define GLX_RGBA_BIT 0x00000001
#define GLX_WINDOW_BIT 0x00000001
#define GLX_DRAWABLE_TYPE 0x8010
#define GLX_RENDER_TYPE 0x8011
#define GLX_RENDER_TYPE 0x8011
#define GLX_RGBA_TYPE 0x8014
#define GLX_DOUBLEBUFFER 5
#define GLX_STEREO 6
#define GLX_AUX_BUFFERS 7
#define GLX_AUX_BUFFERS 7
#define GLX_RED_SIZE 8
#define GLX_GREEN_SIZE 9
#define GLX_BLUE_SIZE 10
@@ -42,7 +42,7 @@
#define GLX_STENCIL_SIZE 13
#define GLX_ACCUM_RED_SIZE 14
#define GLX_ACCUM_GREEN_SIZE 15
#define GLX_ACCUM_BLUE_SIZE 16
#define GLX_ACCUM_BLUE_SIZE 16
#define GLX_ACCUM_ALPHA_SIZE 17
#define GLX_SAMPLES 0x186a1
#define GLX_VISUAL_ID 0x800b
@@ -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

@@ -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 GLFWbool
MIN(size_t a, size_t b) {
static inline size_t
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;
}

6
glfw/ibus_glfw.h vendored
View File

@@ -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);

71
glfw/init.c vendored
View File

@@ -2,7 +2,7 @@
// GLFW 3.3 - 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)
{
@@ -193,6 +195,20 @@ void _glfwInputError(int code, const char* format, ...)
_glfwErrorCallback(code, description);
}
void
_glfwDebug(const char *format, ...) {
if (format)
{
va_list vl;
fprintf(stderr, "[%.4f] ", glfwGetTime());
va_start(vl, format);
vfprintf(stderr, format, vl);
va_end(vl);
fprintf(stderr, "\n");
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
@@ -201,7 +217,7 @@ void _glfwInputError(int code, const char* format, ...)
GLFWAPI int glfwInit(void)
{
if (_glfw.initialized)
return GLFW_TRUE;
return true;
memset(&_glfw, 0, sizeof(_glfw));
_glfw.hints.init = _glfwInitHints;
@@ -209,7 +225,7 @@ GLFWAPI int glfwInit(void)
if (!_glfwPlatformInit())
{
terminate();
return GLFW_FALSE;
return false;
}
if (!_glfwPlatformCreateMutex(&_glfw.errorLock) ||
@@ -217,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();
@@ -235,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)
@@ -320,3 +336,30 @@ GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun)
_GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun);
return cbfun;
}
GLFWAPI void glfwRunMainLoop(GLFWtickcallback callback, void *data)
{
_GLFW_REQUIRE_INIT();
_glfwPlatformRunMainLoop(callback, data);
}
GLFWAPI void glfwStopMainLoop(void) {
_GLFW_REQUIRE_INIT();
_glfwPlatformStopMainLoop();
}
GLFWAPI unsigned long long glfwAddTimer(
double interval, bool repeats, GLFWuserdatafun callback,
void *callback_data, GLFWuserdatafun free_callback)
{
return _glfwPlatformAddTimer(interval, repeats, callback, callback_data, free_callback);
}
GLFWAPI void glfwUpdateTimer(unsigned long long timer_id, double interval, bool enabled) {
_glfwPlatformUpdateTimer(timer_id, interval, enabled);
}
GLFWAPI void glfwRemoveTimer(unsigned long long timer_id) {
_glfwPlatformRemoveTimer(timer_id);
}

130
glfw/input.c vendored
View File

@@ -2,7 +2,7 @@
// GLFW 3.3 - 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;
@@ -312,7 +314,7 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
}
// Notifies shared code of a cursor motion event
// The position is specified in client-area relative screen coordinates
// The position is specified in content area relative screen coordinates
//
void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos)
{
@@ -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,16 +408,16 @@ _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;
js->hatCount = hatCount;
strcpy(js->guid, guid);
strncpy(js->guid, guid, sizeof(js->guid) - 1);
js->mapping = findValidMapping(js);
return js;
@@ -487,6 +489,8 @@ const char* _glfwGetKeyName(int key)
case GLFW_KEY_SLASH: return "SLASH";
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";
@@ -564,6 +568,17 @@ const char* _glfwGetKeyName(int key)
}
}
// 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 //////
//////////////////////////////////////////////////////////////////////////
@@ -622,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;
@@ -642,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;
@@ -661,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);
}
@@ -821,20 +838,15 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot,
return (GLFWcursor*) cursor;
}
GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape)
GLFWAPI GLFWcursor* glfwCreateStandardCursor(GLFWCursorShape shape)
{
_GLFWcursor* cursor;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (shape != GLFW_ARROW_CURSOR &&
shape != GLFW_IBEAM_CURSOR &&
shape != GLFW_CROSSHAIR_CURSOR &&
shape != GLFW_HAND_CURSOR &&
shape != GLFW_HRESIZE_CURSOR &&
shape != GLFW_VRESIZE_CURSOR)
if (shape >= GLFW_INVALID_CURSOR)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid standard cursor 0x%08X", shape);
_glfwInputError(GLFW_INVALID_ENUM, "Invalid standard cursor: %d", shape);
return NULL;
}
@@ -914,7 +926,7 @@ GLFWAPI void glfwUpdateIMEState(GLFWwindow* handle, int which, int a, int b, int
assert(window != NULL);
_GLFW_REQUIRE_INIT();
#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND)
#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND) || defined(_GLFW_COCOA)
_glfwPlatformUpdateIMEState(window, which, a, b, c, d);
#else
(void)window; (void)which; (void)a; (void)b; (void)c; (void)d;
@@ -982,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);
}
@@ -1184,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)
{
@@ -1234,7 +1246,7 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string)
js->mapping = findValidMapping(js);
}
return GLFW_TRUE;
return true;
}
GLFWAPI int glfwJoystickIsGamepad(int jid)
@@ -1244,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;
}
@@ -1301,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++)
{
@@ -1353,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);
@@ -1369,12 +1383,28 @@ 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 UNUSED, const char* string)
{
assert(string != NULL);
_GLFW_REQUIRE_INIT();
_glfwPlatformSetPrimarySelectionString(string);
}
GLFWAPI const char* glfwGetPrimarySelectionString(GLFWwindow* handle UNUSED)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return _glfwPlatformGetPrimarySelectionString();
}
#endif
GLFWAPI double glfwGetTime(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(0.0);

199
glfw/internal.h vendored
View File

@@ -2,7 +2,7 @@
// GLFW 3.3 - 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 int GLFWbool;
typedef unsigned long long GLFWid;
typedef struct _GLFWerror _GLFWerror;
@@ -87,8 +86,8 @@ typedef GLFWglproc (* _GLFWgetprocaddressfun)(const char*);
typedef void (* _GLFWdestroycontextfun)(_GLFWwindow*);
#define GL_VERSION 0x1f02
#define GL_NONE 0
#define GL_COLOR_BUFFER_BIT 0x00004000
#define GL_NONE 0
#define GL_COLOR_BUFFER_BIT 0x00004000
#define GL_UNSIGNED_BYTE 0x1401
#define GL_EXTENSIONS 0x1f03
#define GL_NUM_EXTENSIONS 0x821d
@@ -105,7 +104,7 @@ typedef void (* _GLFWdestroycontextfun)(_GLFWwindow*);
#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82fc
#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008
typedef int GLint;
typedef int GLint;
typedef unsigned int GLuint;
typedef unsigned int GLenum;
typedef unsigned int GLbitfield;
@@ -129,7 +128,6 @@ typedef enum VkStructureType
VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR = 1000004000,
VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR = 1000005000,
VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000,
VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR = 1000007000,
VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000,
VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
@@ -191,14 +189,19 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void);
#include "x11_platform.h"
#elif defined(_GLFW_WAYLAND)
#include "wl_platform.h"
#elif defined(_GLFW_MIR)
#include "mir_platform.h"
#elif defined(_GLFW_OSMESA)
#include "null_platform.h"
#else
#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)
@@ -222,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
//
@@ -244,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;
};
@@ -264,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 {
@@ -299,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;
};
@@ -332,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;
};
@@ -347,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;
@@ -364,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
@@ -378,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;
@@ -394,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];
@@ -411,6 +434,7 @@ struct _GLFWwindow
GLFWwindowclosefun close;
GLFWwindowrefreshfun refresh;
GLFWwindowfocusfun focus;
GLFWwindowocclusionfun occlusion;
GLFWwindowiconifyfun iconify;
GLFWwindowmaximizefun maximize;
GLFWframebuffersizefun fbsize;
@@ -421,6 +445,7 @@ struct _GLFWwindow
GLFWscrollfun scroll;
GLFWkeyboardfun keyboard;
GLFWdropfun drop;
GLFWliveresizefun liveResize;
} callbacks;
// This is defined in the window API's platform.h
@@ -485,7 +510,7 @@ struct _GLFWmapping
//
struct _GLFWjoystick
{
GLFWbool present;
bool present;
float* axes;
int axisCount;
unsigned char* buttons;
@@ -521,7 +546,7 @@ struct _GLFWmutex
//
struct _GLFWlibrary
{
GLFWbool initialized;
bool initialized;
struct {
_GLFWinitconfig init;
@@ -554,25 +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;
#elif defined(_GLFW_MIR)
GLFWbool KHR_mir_surface;
bool KHR_wayland_surface;
#endif
} vk;
@@ -584,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
@@ -611,7 +634,7 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos);
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
const GLFWimage* image, int xhot, int yhot, int count);
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape);
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, GLFWCursorShape shape);
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor);
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor);
@@ -622,13 +645,18 @@ void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor);
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos);
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
float* xscale, float* yscale);
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height);
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count);
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode);
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
void _glfwPlatformSetClipboardString(const char* string);
const char* _glfwPlatformGetClipboardString(void);
#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND)
void _glfwPlatformSetPrimarySelectionString(const char* string);
const char* _glfwPlatformGetPrimarySelectionString(void);
#endif
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode);
void _glfwPlatformUpdateGamepadGUID(char* guid);
@@ -653,11 +681,13 @@ void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
int maxwidth, int maxheight);
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom);
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height);
void _glfwInputLiveResize(_GLFWwindow* window, bool started);
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
int* left, int* top,
int* right, int* bottom);
void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
float* xscale, float* yscale);
double _glfwPlatformGetDoubleClickInterval(_GLFWwindow* window);
void _glfwPlatformIconifyWindow(_GLFWwindow* window);
void _glfwPlatformRestoreWindow(_GLFWwindow* window);
void _glfwPlatformMaximizeWindow(_GLFWwindow* window);
@@ -669,16 +699,18 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window);
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor,
int xpos, int ypos, int width, int height,
int refreshRate);
bool _glfwPlatformToggleFullscreen(_GLFWwindow *w, unsigned int flags);
int _glfwPlatformWindowFocused(_GLFWwindow* window);
int _glfwPlatformWindowOccluded(_GLFWwindow* window);
int _glfwPlatformWindowIconified(_GLFWwindow* window);
int _glfwPlatformWindowVisible(_GLFWwindow* window);
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);
@@ -696,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);
@@ -711,14 +743,15 @@ void _glfwPlatformUnlockMutex(_GLFWmutex* mutex);
////// GLFW event API //////
//////////////////////////////////////////////////////////////////////////
void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused);
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);
@@ -727,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);
@@ -737,25 +770,33 @@ void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value);
void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement);
void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window);
#if defined(__GNUC__)
#if defined(__GNUC__) || defined(__clang__)
void _glfwInputError(int code, const char* format, ...)
__attribute__((format(printf, 2, 3)));
void _glfwDebug(const char* format, ...)
__attribute__((format(printf, 1, 2)));
#else
void _glfwInputError(int code, const char* format, ...);
void _glfwDebug(const char* format, ...);
#endif
#ifdef DEBUG_EVENT_LOOP
#define EVDBG(...) _glfwDebug(__VA_ARGS__)
#else
#define EVDBG(...)
#endif
//////////////////////////////////////////////////////////////////////////
////// 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);
@@ -773,11 +814,17 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
int hatCount);
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();
_GLFWwindow* _glfwFocusedWindow(void);
_GLFWwindow* _glfwWindowForId(GLFWid id);
void _glfwPlatformRunMainLoop(GLFWtickcallback, 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, bool enabled);
void _glfwPlatformRemoveTimer(unsigned long long timer_id);
char* _glfw_strdup(const char* source);

86
glfw/linux_joystick.c vendored
View File

@@ -2,7 +2,7 @@
// GLFW 3.3 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,30 +124,25 @@ 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;
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, EVIOCGBIT(0, sizeof(evBits)), evBits) < 0 ||
ioctl(linjs.fd, EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits) < 0 ||
@@ -158,19 +153,23 @@ static GLFWbool openJoystickDevice(const char* path)
"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;
}
char name[256] = "";
if (ioctl(linjs.fd, 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,20 +222,20 @@ 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));
strncpy(linjs.path, path, sizeof(linjs.path) - 1);
memcpy(&js->linjs, &linjs, sizeof(linjs));
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,7 +427,6 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
return js->present;
}
void _glfwPlatformUpdateGamepadGUID(char* guid)
void _glfwPlatformUpdateGamepadGUID(char* guid UNUSED)
{
}

View File

@@ -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);

105
glfw/linux_notify.c vendored Normal file
View File

@@ -0,0 +1,105 @@
/*
* linux_notify.c
* Copyright (C) 2019 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#include "internal.h"
#include "linux_notify.h"
#include <stdlib.h>
#define NOTIFICATIONS_SERVICE "org.freedesktop.Notifications"
#define NOTIFICATIONS_PATH "/org/freedesktop/Notifications"
#define NOTIFICATIONS_IFACE "org.freedesktop.Notifications"
static notification_id_type notification_id = 0;
typedef struct {
notification_id_type next_id;
GLFWDBusnotificationcreatedfun callback;
void *data;
} NotificationCreatedData;
static GLFWDBusnotificationactivatedfun activated_handler = NULL;
void
glfw_dbus_set_user_notification_activated_handler(GLFWDBusnotificationactivatedfun handler) {
activated_handler = handler;
}
void
notification_created(DBusMessage *msg, const char* errmsg, void *data) {
if (errmsg) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Notify: Failed to create notification error: %s", errmsg);
if (data) free(data);
return;
}
uint32_t notification_id;
if (!glfw_dbus_get_args(msg, "Failed to get Notification uid", DBUS_TYPE_UINT32, &notification_id, DBUS_TYPE_INVALID)) return;
NotificationCreatedData *ncd = (NotificationCreatedData*)data;
if (ncd->callback) ncd->callback(ncd->next_id, notification_id, ncd->data);
if (data) free(data);
}
static DBusHandlerResult
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;
const char *action;
if (glfw_dbus_get_args(msg, "Failed to get args from ActionInvoked notification signal",
DBUS_TYPE_UINT32, &notification_id, DBUS_TYPE_STRING, &action, DBUS_TYPE_INVALID)) {
if (activated_handler) {
activated_handler(notification_id, action);
return DBUS_HANDLER_RESULT_HANDLED;
}
}
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
notification_id_type
glfw_dbus_send_user_notification(const char *app_name, const char* icon, const char *summary, const char *body, const char* action_name, int32_t timeout, GLFWDBusnotificationcreatedfun callback, void *user_data) {
DBusConnection *session_bus = glfw_dbus_session_bus();
static DBusConnection *added_signal_match = NULL;
if (!session_bus) return 0;
if (added_signal_match != session_bus) {
dbus_bus_add_match(session_bus, "type='signal',interface='" NOTIFICATIONS_IFACE "',member='ActionInvoked'", NULL);
dbus_connection_add_filter(session_bus, message_handler, NULL, NULL);
added_signal_match = session_bus;
}
NotificationCreatedData *data = malloc(sizeof(NotificationCreatedData));
if (!data) return 0;
data->next_id = ++notification_id;
data->callback = callback; data->data = user_data;
if (!data->next_id) data->next_id = ++notification_id;
uint32_t replaces_id = 0;
DBusMessage *msg = dbus_message_new_method_call(NOTIFICATIONS_SERVICE, NOTIFICATIONS_PATH, NOTIFICATIONS_IFACE, "Notify");
if (!msg) { free(data); return 0; }
DBusMessageIter args, array;
dbus_message_iter_init_append(msg, &args);
#define OOMMSG { free(data); data = NULL; dbus_message_unref(msg); _glfwInputError(GLFW_PLATFORM_ERROR, "%s", "Out of memory allocating DBUS message for notification\n"); return 0; }
#define APPEND(type, val) { if (!dbus_message_iter_append_basic(&args, type, val)) OOMMSG }
APPEND(DBUS_TYPE_STRING, &app_name)
APPEND(DBUS_TYPE_UINT32, &replaces_id)
APPEND(DBUS_TYPE_STRING, &icon)
APPEND(DBUS_TYPE_STRING, &summary)
APPEND(DBUS_TYPE_STRING, &body)
if (!dbus_message_iter_open_container(&args, DBUS_TYPE_ARRAY, "s", &array)) OOMMSG;
if (action_name) {
static const char* default_action = "default";
dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING, &default_action);
dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING, &action_name);
}
if (!dbus_message_iter_close_container(&args, &array)) OOMMSG;
if (!dbus_message_iter_open_container(&args, DBUS_TYPE_ARRAY, "{sv}", &array)) OOMMSG;
if (!dbus_message_iter_close_container(&args, &array)) OOMMSG;
APPEND(DBUS_TYPE_INT32, &timeout)
#undef OOMMSG
#undef APPEND
if (!call_method_with_msg(session_bus, msg, 5000, notification_created, data)) return 0;
return data->next_id;
}

19
glfw/linux_notify.h vendored Normal file
View File

@@ -0,0 +1,19 @@
/*
* Copyright (C) 2019 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#pragma once
#include "dbus_glfw.h"
#include "internal.h"
typedef unsigned long long notification_id_type;
typedef void (*GLFWDBusnotificationcreatedfun)(notification_id_type, uint32_t, void*);
typedef void (*GLFWDBusnotificationactivatedfun)(uint32_t, const char*);
notification_id_type
glfw_dbus_send_user_notification(const char *app_name, const char* icon, const char *summary, const char *body, const char *action_name, int32_t timeout, GLFWDBusnotificationcreatedfun, void*);
void
glfw_dbus_set_user_notification_activated_handler(GLFWDBusnotificationactivatedfun handler);

50
glfw/main_loop.h vendored Normal file
View File

@@ -0,0 +1,50 @@
/*
* Copyright (C) 2019 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#pragma once
#include "internal.h"
#ifndef GLFW_LOOP_BACKEND
#define GLFW_LOOP_BACKEND x11
#endif
static bool keep_going = false;
void _glfwPlatformStopMainLoop(void) {
if (keep_going) {
keep_going = false;
_glfwPlatformPostEmptyEvent();
}
}
void _glfwPlatformRunMainLoop(GLFWtickcallback tick_callback, void* data) {
keep_going = 1;
EventLoopData *eld = &_glfw.GLFW_LOOP_BACKEND.eventLoopData;
while(keep_going) {
_glfwPlatformWaitEvents();
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) {
return addTimer(&_glfw.GLFW_LOOP_BACKEND.eventLoopData, "user timer", interval, 1, repeats, callback, callback_data, free_callback);
}
void _glfwPlatformRemoveTimer(unsigned long long timer_id) {
removeTimer(&_glfw.GLFW_LOOP_BACKEND.eventLoopData, timer_id);
}
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);
}

2
glfw/mappings.h vendored
View File

@@ -1,7 +1,7 @@
//========================================================================
// GLFW 3.3 - 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

54
glfw/memfd.h vendored Normal file
View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2018 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#pragma once
#ifdef HAS_MEMFD_CREATE
#include <unistd.h>
#include <sys/syscall.h>
static inline int memfd_create(const char *name, unsigned int flags) {
return syscall(__NR_memfd_create, name, flags);
}
#ifndef F_LINUX_SPECIFIC_BASE
#define F_LINUX_SPECIFIC_BASE 1024
#endif
#ifndef F_ADD_SEALS
#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
#define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10)
#define F_SEAL_SEAL 0x0001 /* prevent further seals from being set */
#define F_SEAL_SHRINK 0x0002 /* prevent file from shrinking */
#define F_SEAL_GROW 0x0004 /* prevent file from growing */
#define F_SEAL_WRITE 0x0008 /* prevent writes */
#endif
#ifndef MFD_CLOEXEC
#define MFD_CLOEXEC 0x0001U
#define MFD_ALLOW_SEALING 0x0002U
#endif
#else
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
static inline int
createTmpfileCloexec(char* tmpname)
{
int fd;
fd = mkostemp(tmpname, O_CLOEXEC);
if (fd >= 0)
unlink(tmpname);
return fd;
}
#endif

76
glfw/monitor.c vendored
View File

@@ -2,7 +2,7 @@
// GLFW 3.3 - 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,6 +329,27 @@ 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)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
if (xpos)
*xpos = 0;
if (ypos)
*ypos = 0;
if (width)
*width = 0;
if (height)
*height = 0;
_GLFW_REQUIRE_INIT();
_glfwPlatformGetMonitorWorkarea(monitor, xpos, ypos, width, height);
}
GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
@@ -427,12 +447,12 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle)
GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
{
int i;
unsigned short values[256];
unsigned int i;
unsigned short* values;
GLFWgammaramp ramp;
const GLFWgammaramp* original;
assert(handle != NULL);
assert(gamma == gamma);
assert(gamma >= 0.f);
assert(gamma > 0.f);
assert(gamma <= FLT_MAX);
_GLFW_REQUIRE_INIT();
@@ -443,18 +463,22 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
return;
}
for (i = 0; i < 256; i++)
original = glfwGetGammaRamp(handle);
if (!original)
return;
values = calloc(original->size, sizeof(unsigned short));
for (i = 0; i < original->size; i++)
{
float value;
// Calculate intensity
value = i / 255.f;
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;
}
@@ -462,9 +486,10 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
ramp.red = values;
ramp.green = values;
ramp.blue = values;
ramp.size = 256;
ramp.size = original->size;
glfwSetGammaRamp(handle, &ramp);
free(values);
}
GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
@@ -475,7 +500,8 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_glfwFreeGammaArrays(&monitor->currentRamp);
_glfwPlatformGetGammaRamp(monitor, &monitor->currentRamp);
if (!_glfwPlatformGetGammaRamp(monitor, &monitor->currentRamp))
return NULL;
return &monitor->currentRamp;
}
@@ -501,8 +527,10 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
_GLFW_REQUIRE_INIT();
if (!monitor->originalRamp.size)
_glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp);
{
if (!_glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp))
return;
}
_glfwPlatformSetGammaRamp(monitor, ramp);
}

13
glfw/nsgl_context.h vendored
View File

@@ -1,7 +1,7 @@
//========================================================================
// GLFW 3.3 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
@@ -33,7 +33,7 @@
typedef struct _GLFWcontextNSGL
{
id pixelFormat;
id object;
id object;
} _GLFWcontextNSGL;
@@ -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
//------------------------------------------------------------------------
// 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,19 +45,17 @@ static void swapBuffersNSGL(_GLFWwindow* window)
[window->context.nsgl.object flushBuffer];
}
static void swapIntervalNSGL(int interval)
static void swapIntervalNSGL(int interval UNUSED)
{
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
GLint sync = interval;
[window->context.nsgl.object setValues:&sync
forParameter:NSOpenGLCPSwapInterval];
// As of Mojave this does not work so we use CVDisplayLink instead
_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)
@@ -64,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];
@@ -90,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"));
@@ -101,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
@@ -115,7 +114,7 @@ void _glfwTerminateNSGL(void)
// Create the OpenGL context
//
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
bool _glfwCreateContextNSGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
@@ -123,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)
@@ -132,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;
}
}
@@ -175,9 +167,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
// Info.plist for unbundled applications
// HACK: This assumes that NSOpenGLPixelFormat will remain
// a straightforward wrapper of its CGL counterpart
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
addAttrib(kCGLPFASupportsAutomaticGraphicsSwitching);
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
}
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
@@ -242,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
@@ -278,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;
@@ -293,15 +283,23 @@ 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:NSOpenGLCPSurfaceOpacity];
[window->context.nsgl.object setValues:&opaque
forParameter:NSOpenGLContextParameterSurfaceOpacity];
}
if (window->ns.retina)
[window->ns.view setWantsBestResolutionOpenGLSurface:YES];
GLint interval = 0;
[window->context.nsgl.object setValues:&interval
forParameter:NSOpenGLContextParameterSwapInterval];
[window->context.nsgl.object setView:window->ns.view];
window->context.makeCurrent = makeContextCurrentNSGL;
@@ -311,7 +309,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
window->context.getProcAddress = getProcAddressNSGL;
window->context.destroy = destroyContextNSGL;
return GLFW_TRUE;
return true;
}
@@ -332,4 +330,3 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle)
return window->context.nsgl.object;
}

6
glfw/null_init.c vendored
View File

@@ -2,7 +2,7 @@
// GLFW 3.3 - 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
//------------------------------------------------------------------------
// 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
//------------------------------------------------------------------------
// 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 ""

13
glfw/null_monitor.c vendored
View File

@@ -2,7 +2,7 @@
// GLFW 3.3 - 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,6 +51,12 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
*yscale = 1.f;
}
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
int* xpos, int* ypos,
int* width, int* height)
{
}
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
{
return NULL;
@@ -58,8 +66,9 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
{
}
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{
return false;
}
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)

View File

@@ -2,7 +2,7 @@
// GLFW 3.3 - 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

53
glfw/null_window.c vendored
View File

@@ -2,7 +2,7 @@
// GLFW 3.3 - 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)
@@ -148,6 +150,11 @@ void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
*yscale = 1.f;
}
double _glfwPlatformGetDoubleClickInterval(_GLFWwindow* window)
{
return 0.5;
}
void _glfwPlatformIconifyWindow(_GLFWwindow* window)
{
}
@@ -162,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)
{
}
@@ -207,7 +214,7 @@ void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
int _glfwPlatformWindowBell(_GLFWwindow* window)
{
return GLFW_FALSE;
return false;
}
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
@@ -224,17 +231,22 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window)
int _glfwPlatformWindowFocused(_GLFWwindow* window)
{
return GLFW_FALSE;
return false;
}
int _glfwPlatformWindowOccluded(_GLFWwindow* window)
{
return false;
}
int _glfwPlatformWindowIconified(_GLFWwindow* window)
{
return GLFW_FALSE;
return false;
}
int _glfwPlatformWindowVisible(_GLFWwindow* window)
{
return GLFW_FALSE;
return false;
}
void _glfwPlatformPollEvents(void)
@@ -269,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)
@@ -312,7 +324,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
return GLFW_FALSE;
return false;
}
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
@@ -323,3 +335,4 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
// This seems like the most appropriate error to return here
return VK_ERROR_INITIALIZATION_FAILED;
}

74
glfw/osmesa_context.c vendored
View File

@@ -2,7 +2,7 @@
// GLFW 3.3 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)
@@ -240,8 +235,8 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
if (ctxconfig->forward)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"OSMesa: Foward-compatible contexts not supported");
return GLFW_FALSE;
"OSMesa: Forward-compatible contexts not supported");
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)
@@ -367,4 +362,3 @@ GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle)
return window->context.osmesa.handle;
}

View File

@@ -2,7 +2,7 @@
// GLFW 3.3 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);

30
glfw/posix_thread.c vendored
View File

@@ -2,7 +2,7 @@
// GLFW 3.3 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);
}

6
glfw/posix_thread.h vendored
View File

@@ -2,7 +2,7 @@
// GLFW 3.3 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;

8
glfw/posix_time.c vendored
View File

@@ -2,7 +2,7 @@
// GLFW 3.3 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;
}
}

4
glfw/posix_time.h vendored
View File

@@ -2,7 +2,7 @@
// GLFW 3.3 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;

View File

@@ -64,14 +64,18 @@
"egl_context.h",
"osmesa_context.h",
"linux_joystick.h",
"null_joystick.h"
"null_joystick.h",
"linux_notify.h",
"main_loop.h"
],
"protocols": [
"stable/xdg-shell/xdg-shell.xml",
"stable/viewporter/viewporter.xml",
"unstable/relative-pointer/relative-pointer-unstable-v1.xml",
"unstable/pointer-constraints/pointer-constraints-unstable-v1.xml",
"unstable/idle-inhibit/idle-inhibit-unstable-v1.xml"
"unstable/idle-inhibit/idle-inhibit-unstable-v1.xml",
"unstable/xdg-decoration/xdg-decoration-unstable-v1.xml",
"unstable/primary-selection/primary-selection-unstable-v1.xml"
],
"sources": [
"wl_init.c",
@@ -86,12 +90,13 @@
"osmesa_context.c",
"backend_utils.c",
"linux_joystick.c",
"null_joystick.c"
"null_joystick.c",
"linux_notify.c"
]
},
"wayland_protocols": [
1,
12
17
],
"win32": {
"headers": [
@@ -126,7 +131,9 @@
"egl_context.h",
"osmesa_context.h",
"linux_joystick.h",
"null_joystick.h"
"null_joystick.h",
"linux_notify.h",
"main_loop.h"
],
"sources": [
"x11_init.c",
@@ -142,7 +149,8 @@
"osmesa_context.c",
"backend_utils.c",
"linux_joystick.c",
"null_joystick.c"
"null_joystick.c",
"linux_notify.c"
]
}
}
}

50
glfw/vulkan.c vendored
View File

@@ -2,7 +2,7 @@
// GLFW 3.3 - 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,40 +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;
#elif defined(_GLFW_MIR)
else if (strcmp(ep[i].extensionName, "VK_KHR_mir_surface") == 0)
_glfw.vk.KHR_mir_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)
@@ -221,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);
}
@@ -263,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;
@@ -276,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,
@@ -326,4 +325,3 @@ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance,
return _glfwPlatformCreateWindowSurface(instance, window, allocator, surface);
}

744
glfw/wgl_context.c vendored
View File

@@ -1,744 +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);

627
glfw/win32_init.c vendored
View File

@@ -1,627 +0,0 @@
//========================================================================
// GLFW 3.3 Win32 - 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>
static const GUID _glfw_GUID_DEVINTERFACE_HID =
{0x4d1e55b2,0xf16f,0x11cf,{0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30}};
#define GUID_DEVINTERFACE_HID _glfw_GUID_DEVINTERFACE_HID
#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG)
// Executables (but not DLLs) exporting this symbol with this value will be
// automatically directed to the high-performance GPU on Nvidia Optimus systems
// with up-to-date drivers
//
__declspec(dllexport) DWORD NvOptimusEnablement = 1;
// Executables (but not DLLs) exporting this symbol with this value will be
// automatically directed to the high-performance GPU on AMD PowerXpress systems
// with up-to-date drivers
//
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
#endif // _GLFW_USE_HYBRID_HPG
#if defined(_GLFW_BUILD_DLL)
// GLFW DLL entry point
//
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{
return TRUE;
}
#endif // _GLFW_BUILD_DLL
// Load necessary libraries (DLLs)
//
static GLFWbool loadLibraries(void)
{
_glfw.win32.winmm.instance = LoadLibraryA("winmm.dll");
if (!_glfw.win32.winmm.instance)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to load winmm.dll");
return GLFW_FALSE;
}
_glfw.win32.winmm.GetTime = (PFN_timeGetTime)
GetProcAddress(_glfw.win32.winmm.instance, "timeGetTime");
_glfw.win32.user32.instance = LoadLibraryA("user32.dll");
if (!_glfw.win32.user32.instance)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to load user32.dll");
return GLFW_FALSE;
}
_glfw.win32.user32.SetProcessDPIAware_ = (PFN_SetProcessDPIAware)
GetProcAddress(_glfw.win32.user32.instance, "SetProcessDPIAware");
_glfw.win32.user32.ChangeWindowMessageFilterEx_ = (PFN_ChangeWindowMessageFilterEx)
GetProcAddress(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx");
_glfw.win32.user32.EnableNonClientDpiScaling_ = (PFN_EnableNonClientDpiScaling)
GetProcAddress(_glfw.win32.user32.instance, "EnableNonClientDpiScaling");
_glfw.win32.user32.SetProcessDpiAwarenessContext_ = (PFN_SetProcessDpiAwarenessContext)
GetProcAddress(_glfw.win32.user32.instance, "SetProcessDpiAwarenessContext");
_glfw.win32.user32.GetDpiForWindow_ = (PFN_GetDpiForWindow)
GetProcAddress(_glfw.win32.user32.instance, "GetDpiForWindow");
_glfw.win32.user32.AdjustWindowRectExForDpi_ = (PFN_AdjustWindowRectExForDpi)
GetProcAddress(_glfw.win32.user32.instance, "AdjustWindowRectExForDpi");
_glfw.win32.dinput8.instance = LoadLibraryA("dinput8.dll");
if (_glfw.win32.dinput8.instance)
{
_glfw.win32.dinput8.Create = (PFN_DirectInput8Create)
GetProcAddress(_glfw.win32.dinput8.instance, "DirectInput8Create");
}
{
int i;
const char* names[] =
{
"xinput1_4.dll",
"xinput1_3.dll",
"xinput9_1_0.dll",
"xinput1_2.dll",
"xinput1_1.dll",
NULL
};
for (i = 0; names[i]; i++)
{
_glfw.win32.xinput.instance = LoadLibraryA(names[i]);
if (_glfw.win32.xinput.instance)
{
_glfw.win32.xinput.GetCapabilities = (PFN_XInputGetCapabilities)
GetProcAddress(_glfw.win32.xinput.instance, "XInputGetCapabilities");
_glfw.win32.xinput.GetState = (PFN_XInputGetState)
GetProcAddress(_glfw.win32.xinput.instance, "XInputGetState");
break;
}
}
}
_glfw.win32.dwmapi.instance = LoadLibraryA("dwmapi.dll");
if (_glfw.win32.dwmapi.instance)
{
_glfw.win32.dwmapi.IsCompositionEnabled = (PFN_DwmIsCompositionEnabled)
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled");
_glfw.win32.dwmapi.Flush = (PFN_DwmFlush)
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmFlush");
_glfw.win32.dwmapi.EnableBlurBehindWindow = (PFN_DwmEnableBlurBehindWindow)
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow");
}
_glfw.win32.shcore.instance = LoadLibraryA("shcore.dll");
if (_glfw.win32.shcore.instance)
{
_glfw.win32.shcore.SetProcessDpiAwareness_ = (PFN_SetProcessDpiAwareness)
GetProcAddress(_glfw.win32.shcore.instance, "SetProcessDpiAwareness");
_glfw.win32.shcore.GetDpiForMonitor_ = (PFN_GetDpiForMonitor)
GetProcAddress(_glfw.win32.shcore.instance, "GetDpiForMonitor");
}
_glfw.win32.ntdll.instance = LoadLibraryA("ntdll.dll");
if (_glfw.win32.ntdll.instance)
{
_glfw.win32.ntdll.RtlVerifyVersionInfo_ = (PFN_RtlVerifyVersionInfo)
GetProcAddress(_glfw.win32.ntdll.instance, "RtlVerifyVersionInfo");
}
return GLFW_TRUE;
}
// Unload used libraries (DLLs)
//
static void freeLibraries(void)
{
if (_glfw.win32.xinput.instance)
FreeLibrary(_glfw.win32.xinput.instance);
if (_glfw.win32.dinput8.instance)
FreeLibrary(_glfw.win32.dinput8.instance);
if (_glfw.win32.winmm.instance)
FreeLibrary(_glfw.win32.winmm.instance);
if (_glfw.win32.user32.instance)
FreeLibrary(_glfw.win32.user32.instance);
if (_glfw.win32.dwmapi.instance)
FreeLibrary(_glfw.win32.dwmapi.instance);
if (_glfw.win32.shcore.instance)
FreeLibrary(_glfw.win32.shcore.instance);
if (_glfw.win32.ntdll.instance)
FreeLibrary(_glfw.win32.ntdll.instance);
}
// Create key code translation tables
//
static void createKeyTables(void)
{
int scancode;
memset(_glfw.win32.keycodes, -1, sizeof(_glfw.win32.keycodes));
memset(_glfw.win32.scancodes, -1, sizeof(_glfw.win32.scancodes));
_glfw.win32.keycodes[0x00B] = GLFW_KEY_0;
_glfw.win32.keycodes[0x002] = GLFW_KEY_1;
_glfw.win32.keycodes[0x003] = GLFW_KEY_2;
_glfw.win32.keycodes[0x004] = GLFW_KEY_3;
_glfw.win32.keycodes[0x005] = GLFW_KEY_4;
_glfw.win32.keycodes[0x006] = GLFW_KEY_5;
_glfw.win32.keycodes[0x007] = GLFW_KEY_6;
_glfw.win32.keycodes[0x008] = GLFW_KEY_7;
_glfw.win32.keycodes[0x009] = GLFW_KEY_8;
_glfw.win32.keycodes[0x00A] = GLFW_KEY_9;
_glfw.win32.keycodes[0x01E] = GLFW_KEY_A;
_glfw.win32.keycodes[0x030] = GLFW_KEY_B;
_glfw.win32.keycodes[0x02E] = GLFW_KEY_C;
_glfw.win32.keycodes[0x020] = GLFW_KEY_D;
_glfw.win32.keycodes[0x012] = GLFW_KEY_E;
_glfw.win32.keycodes[0x021] = GLFW_KEY_F;
_glfw.win32.keycodes[0x022] = GLFW_KEY_G;
_glfw.win32.keycodes[0x023] = GLFW_KEY_H;
_glfw.win32.keycodes[0x017] = GLFW_KEY_I;
_glfw.win32.keycodes[0x024] = GLFW_KEY_J;
_glfw.win32.keycodes[0x025] = GLFW_KEY_K;
_glfw.win32.keycodes[0x026] = GLFW_KEY_L;
_glfw.win32.keycodes[0x032] = GLFW_KEY_M;
_glfw.win32.keycodes[0x031] = GLFW_KEY_N;
_glfw.win32.keycodes[0x018] = GLFW_KEY_O;
_glfw.win32.keycodes[0x019] = GLFW_KEY_P;
_glfw.win32.keycodes[0x010] = GLFW_KEY_Q;
_glfw.win32.keycodes[0x013] = GLFW_KEY_R;
_glfw.win32.keycodes[0x01F] = GLFW_KEY_S;
_glfw.win32.keycodes[0x014] = GLFW_KEY_T;
_glfw.win32.keycodes[0x016] = GLFW_KEY_U;
_glfw.win32.keycodes[0x02F] = GLFW_KEY_V;
_glfw.win32.keycodes[0x011] = GLFW_KEY_W;
_glfw.win32.keycodes[0x02D] = GLFW_KEY_X;
_glfw.win32.keycodes[0x015] = GLFW_KEY_Y;
_glfw.win32.keycodes[0x02C] = GLFW_KEY_Z;
_glfw.win32.keycodes[0x028] = GLFW_KEY_APOSTROPHE;
_glfw.win32.keycodes[0x02B] = GLFW_KEY_BACKSLASH;
_glfw.win32.keycodes[0x033] = GLFW_KEY_COMMA;
_glfw.win32.keycodes[0x00D] = GLFW_KEY_EQUAL;
_glfw.win32.keycodes[0x029] = GLFW_KEY_GRAVE_ACCENT;
_glfw.win32.keycodes[0x01A] = GLFW_KEY_LEFT_BRACKET;
_glfw.win32.keycodes[0x00C] = GLFW_KEY_MINUS;
_glfw.win32.keycodes[0x034] = GLFW_KEY_PERIOD;
_glfw.win32.keycodes[0x01B] = GLFW_KEY_RIGHT_BRACKET;
_glfw.win32.keycodes[0x027] = GLFW_KEY_SEMICOLON;
_glfw.win32.keycodes[0x035] = GLFW_KEY_SLASH;
_glfw.win32.keycodes[0x056] = GLFW_KEY_WORLD_2;
_glfw.win32.keycodes[0x00E] = GLFW_KEY_BACKSPACE;
_glfw.win32.keycodes[0x153] = GLFW_KEY_DELETE;
_glfw.win32.keycodes[0x14F] = GLFW_KEY_END;
_glfw.win32.keycodes[0x01C] = GLFW_KEY_ENTER;
_glfw.win32.keycodes[0x001] = GLFW_KEY_ESCAPE;
_glfw.win32.keycodes[0x147] = GLFW_KEY_HOME;
_glfw.win32.keycodes[0x152] = GLFW_KEY_INSERT;
_glfw.win32.keycodes[0x15D] = GLFW_KEY_MENU;
_glfw.win32.keycodes[0x151] = GLFW_KEY_PAGE_DOWN;
_glfw.win32.keycodes[0x149] = GLFW_KEY_PAGE_UP;
_glfw.win32.keycodes[0x045] = GLFW_KEY_PAUSE;
_glfw.win32.keycodes[0x146] = GLFW_KEY_PAUSE;
_glfw.win32.keycodes[0x039] = GLFW_KEY_SPACE;
_glfw.win32.keycodes[0x00F] = GLFW_KEY_TAB;
_glfw.win32.keycodes[0x03A] = GLFW_KEY_CAPS_LOCK;
_glfw.win32.keycodes[0x145] = GLFW_KEY_NUM_LOCK;
_glfw.win32.keycodes[0x046] = GLFW_KEY_SCROLL_LOCK;
_glfw.win32.keycodes[0x03B] = GLFW_KEY_F1;
_glfw.win32.keycodes[0x03C] = GLFW_KEY_F2;
_glfw.win32.keycodes[0x03D] = GLFW_KEY_F3;
_glfw.win32.keycodes[0x03E] = GLFW_KEY_F4;
_glfw.win32.keycodes[0x03F] = GLFW_KEY_F5;
_glfw.win32.keycodes[0x040] = GLFW_KEY_F6;
_glfw.win32.keycodes[0x041] = GLFW_KEY_F7;
_glfw.win32.keycodes[0x042] = GLFW_KEY_F8;
_glfw.win32.keycodes[0x043] = GLFW_KEY_F9;
_glfw.win32.keycodes[0x044] = GLFW_KEY_F10;
_glfw.win32.keycodes[0x057] = GLFW_KEY_F11;
_glfw.win32.keycodes[0x058] = GLFW_KEY_F12;
_glfw.win32.keycodes[0x064] = GLFW_KEY_F13;
_glfw.win32.keycodes[0x065] = GLFW_KEY_F14;
_glfw.win32.keycodes[0x066] = GLFW_KEY_F15;
_glfw.win32.keycodes[0x067] = GLFW_KEY_F16;
_glfw.win32.keycodes[0x068] = GLFW_KEY_F17;
_glfw.win32.keycodes[0x069] = GLFW_KEY_F18;
_glfw.win32.keycodes[0x06A] = GLFW_KEY_F19;
_glfw.win32.keycodes[0x06B] = GLFW_KEY_F20;
_glfw.win32.keycodes[0x06C] = GLFW_KEY_F21;
_glfw.win32.keycodes[0x06D] = GLFW_KEY_F22;
_glfw.win32.keycodes[0x06E] = GLFW_KEY_F23;
_glfw.win32.keycodes[0x076] = GLFW_KEY_F24;
_glfw.win32.keycodes[0x038] = GLFW_KEY_LEFT_ALT;
_glfw.win32.keycodes[0x01D] = GLFW_KEY_LEFT_CONTROL;
_glfw.win32.keycodes[0x02A] = GLFW_KEY_LEFT_SHIFT;
_glfw.win32.keycodes[0x15B] = GLFW_KEY_LEFT_SUPER;
_glfw.win32.keycodes[0x137] = GLFW_KEY_PRINT_SCREEN;
_glfw.win32.keycodes[0x138] = GLFW_KEY_RIGHT_ALT;
_glfw.win32.keycodes[0x11D] = GLFW_KEY_RIGHT_CONTROL;
_glfw.win32.keycodes[0x036] = GLFW_KEY_RIGHT_SHIFT;
_glfw.win32.keycodes[0x15C] = GLFW_KEY_RIGHT_SUPER;
_glfw.win32.keycodes[0x150] = GLFW_KEY_DOWN;
_glfw.win32.keycodes[0x14B] = GLFW_KEY_LEFT;
_glfw.win32.keycodes[0x14D] = GLFW_KEY_RIGHT;
_glfw.win32.keycodes[0x148] = GLFW_KEY_UP;
_glfw.win32.keycodes[0x052] = GLFW_KEY_KP_0;
_glfw.win32.keycodes[0x04F] = GLFW_KEY_KP_1;
_glfw.win32.keycodes[0x050] = GLFW_KEY_KP_2;
_glfw.win32.keycodes[0x051] = GLFW_KEY_KP_3;
_glfw.win32.keycodes[0x04B] = GLFW_KEY_KP_4;
_glfw.win32.keycodes[0x04C] = GLFW_KEY_KP_5;
_glfw.win32.keycodes[0x04D] = GLFW_KEY_KP_6;
_glfw.win32.keycodes[0x047] = GLFW_KEY_KP_7;
_glfw.win32.keycodes[0x048] = GLFW_KEY_KP_8;
_glfw.win32.keycodes[0x049] = GLFW_KEY_KP_9;
_glfw.win32.keycodes[0x04E] = GLFW_KEY_KP_ADD;
_glfw.win32.keycodes[0x053] = GLFW_KEY_KP_DECIMAL;
_glfw.win32.keycodes[0x135] = GLFW_KEY_KP_DIVIDE;
_glfw.win32.keycodes[0x11C] = GLFW_KEY_KP_ENTER;
_glfw.win32.keycodes[0x059] = GLFW_KEY_KP_EQUAL;
_glfw.win32.keycodes[0x037] = GLFW_KEY_KP_MULTIPLY;
_glfw.win32.keycodes[0x04A] = GLFW_KEY_KP_SUBTRACT;
for (scancode = 0; scancode < 512; scancode++)
{
if (_glfw.win32.keycodes[scancode] > 0)
_glfw.win32.scancodes[_glfw.win32.keycodes[scancode]] = scancode;
}
}
// Creates a dummy window for behind-the-scenes work
//
static HWND createHelperWindow(void)
{
MSG msg;
HWND window = CreateWindowExW(WS_EX_OVERLAPPEDWINDOW,
_GLFW_WNDCLASSNAME,
L"GLFW message window",
WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
0, 0, 1, 1,
NULL, NULL,
GetModuleHandleW(NULL),
NULL);
if (!window)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to create helper window");
return NULL;
}
// HACK: The command to the first ShowWindow call is ignored if the parent
// process passed along a STARTUPINFO, so clear that with a no-op call
ShowWindow(window, SW_HIDE);
// Register for HID device notifications
{
DEV_BROADCAST_DEVICEINTERFACE_W dbi;
ZeroMemory(&dbi, sizeof(dbi));
dbi.dbcc_size = sizeof(dbi);
dbi.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
dbi.dbcc_classguid = GUID_DEVINTERFACE_HID;
_glfw.win32.deviceNotificationHandle =
RegisterDeviceNotificationW(window,
(DEV_BROADCAST_HDR*) &dbi,
DEVICE_NOTIFY_WINDOW_HANDLE);
}
while (PeekMessageW(&msg, _glfw.win32.helperWindowHandle, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return window;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Returns a wide string version of the specified UTF-8 string
//
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source)
{
WCHAR* target;
int count;
count = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0);
if (!count)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert string from UTF-8");
return NULL;
}
target = calloc(count, sizeof(WCHAR));
if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, count))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert string from UTF-8");
free(target);
return NULL;
}
return target;
}
// Returns a UTF-8 string version of the specified wide string
//
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source)
{
char* target;
int size;
size = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
if (!size)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert string to UTF-8");
return NULL;
}
target = calloc(size, 1);
if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, size, NULL, NULL))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert string to UTF-8");
free(target);
return NULL;
}
return target;
}
// Reports the specified error, appending information about the last Win32 error
//
void _glfwInputErrorWin32(int error, const char* description)
{
WCHAR buffer[_GLFW_MESSAGE_SIZE] = L"";
char message[_GLFW_MESSAGE_SIZE] = "";
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_MAX_WIDTH_MASK,
NULL,
GetLastError() & 0xffff,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
buffer,
sizeof(buffer),
NULL);
WideCharToMultiByte(CP_UTF8, 0, buffer, -1, message, sizeof(message), NULL, NULL);
_glfwInputError(error, "%s: %s", description, message);
}
// Updates key names according to the current keyboard layout
//
void _glfwUpdateKeyNamesWin32(void)
{
int key;
BYTE state[256] = {0};
memset(_glfw.win32.keynames, 0, sizeof(_glfw.win32.keynames));
for (key = GLFW_KEY_SPACE; key <= GLFW_KEY_LAST; key++)
{
UINT vk;
int scancode, length;
WCHAR chars[16];
scancode = _glfw.win32.scancodes[key];
if (scancode == -1)
continue;
if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_ADD)
{
const UINT vks[] = {
VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3,
VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7,
VK_NUMPAD8, VK_NUMPAD9, VK_DECIMAL, VK_DIVIDE,
VK_MULTIPLY, VK_SUBTRACT, VK_ADD
};
vk = vks[key - GLFW_KEY_KP_0];
}
else
vk = MapVirtualKey(scancode, MAPVK_VSC_TO_VK);
length = ToUnicode(vk, scancode, state,
chars, sizeof(chars) / sizeof(WCHAR),
0);
if (length == -1)
{
length = ToUnicode(vk, scancode, state,
chars, sizeof(chars) / sizeof(WCHAR),
0);
}
if (length < 1)
continue;
WideCharToMultiByte(CP_UTF8, 0, chars, 1,
_glfw.win32.keynames[key],
sizeof(_glfw.win32.keynames[key]),
NULL, NULL);
}
}
// Replacement for IsWindowsVersionOrGreater as MinGW lacks versionhelpers.h
//
BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp)
{
OSVERSIONINFOEXW osvi = { sizeof(osvi), major, minor, 0, 0, {0}, sp };
DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR;
ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
cond = VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
// HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
// latter lies unless the user knew to embedd a non-default manifest
// announcing support for Windows 10 via supportedOS GUID
return RtlVerifyVersionInfo(&osvi, mask, cond) == 0;
}
// Checks whether we are on at least the specified build of Windows 10
//
BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build)
{
OSVERSIONINFOEXW osvi = { sizeof(osvi), 10, 0, build };
DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER;
ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
cond = VerSetConditionMask(cond, VER_BUILDNUMBER, VER_GREATER_EQUAL);
// HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
// latter lies unless the user knew to embedd a non-default manifest
// announcing support for Windows 10 via supportedOS GUID
return RtlVerifyVersionInfo(&osvi, mask, cond) == 0;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
int _glfwPlatformInit(void)
{
// To make SetForegroundWindow work as we want, we need to fiddle
// with the FOREGROUNDLOCKTIMEOUT system setting (we do this as early
// as possible in the hope of still being the foreground process)
SystemParametersInfoW(SPI_GETFOREGROUNDLOCKTIMEOUT, 0,
&_glfw.win32.foregroundLockTimeout, 0);
SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, UIntToPtr(0),
SPIF_SENDCHANGE);
if (!loadLibraries())
return GLFW_FALSE;
createKeyTables();
_glfwUpdateKeyNamesWin32();
if (_glfwIsWindows10CreatorsUpdateOrGreaterWin32())
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
else if (IsWindows8Point1OrGreater())
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
else if (IsWindowsVistaOrGreater())
SetProcessDPIAware();
if (!_glfwRegisterWindowClassWin32())
return GLFW_FALSE;
_glfw.win32.helperWindowHandle = createHelperWindow();
if (!_glfw.win32.helperWindowHandle)
return GLFW_FALSE;
_glfwInitTimerWin32();
_glfwInitJoysticksWin32();
_glfwPollMonitorsWin32();
return GLFW_TRUE;
}
void _glfwPlatformTerminate(void)
{
if (_glfw.win32.deviceNotificationHandle)
UnregisterDeviceNotification(_glfw.win32.deviceNotificationHandle);
if (_glfw.win32.helperWindowHandle)
DestroyWindow(_glfw.win32.helperWindowHandle);
_glfwUnregisterWindowClassWin32();
// Restore previous foreground lock timeout system setting
SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,
UIntToPtr(_glfw.win32.foregroundLockTimeout),
SPIF_SENDCHANGE);
free(_glfw.win32.clipboardString);
free(_glfw.win32.rawInput);
_glfwTerminateWGL();
_glfwTerminateEGL();
_glfwTerminateJoysticksWin32();
freeLibraries();
}
const char* _glfwPlatformGetVersionString(void)
{
return _GLFW_VERSION_NUMBER " Win32 WGL EGL"
#if defined(__MINGW32__)
" MinGW"
#elif defined(_MSC_VER)
" VisualC"
#endif
#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG)
" hybrid-GPU"
#endif
#if defined(_GLFW_BUILD_DLL)
" DLL"
#endif
;
}

751
glfw/win32_joystick.c vendored
View File

@@ -1,751 +0,0 @@
//========================================================================
// GLFW 3.3 Win32 - 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 <stdio.h>
#include <math.h>
#define _GLFW_TYPE_AXIS 0
#define _GLFW_TYPE_SLIDER 1
#define _GLFW_TYPE_BUTTON 2
#define _GLFW_TYPE_POV 3
// Data produced with DirectInput device object enumeration
//
typedef struct _GLFWobjenumWin32
{
IDirectInputDevice8W* device;
_GLFWjoyobjectWin32* objects;
int objectCount;
int axisCount;
int sliderCount;
int buttonCount;
int povCount;
} _GLFWobjenumWin32;
// Define local copies of the necessary GUIDs
//
static const GUID _glfw_IID_IDirectInput8W =
{0xbf798031,0x483a,0x4da2,{0xaa,0x99,0x5d,0x64,0xed,0x36,0x97,0x00}};
static const GUID _glfw_GUID_XAxis =
{0xa36d02e0,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_YAxis =
{0xa36d02e1,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_ZAxis =
{0xa36d02e2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_RxAxis =
{0xa36d02f4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_RyAxis =
{0xa36d02f5,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_RzAxis =
{0xa36d02e3,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_Slider =
{0xa36d02e4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_POV =
{0xa36d02f2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
#define IID_IDirectInput8W _glfw_IID_IDirectInput8W
#define GUID_XAxis _glfw_GUID_XAxis
#define GUID_YAxis _glfw_GUID_YAxis
#define GUID_ZAxis _glfw_GUID_ZAxis
#define GUID_RxAxis _glfw_GUID_RxAxis
#define GUID_RyAxis _glfw_GUID_RyAxis
#define GUID_RzAxis _glfw_GUID_RzAxis
#define GUID_Slider _glfw_GUID_Slider
#define GUID_POV _glfw_GUID_POV
// Object data array for our clone of c_dfDIJoystick
// Generated with https://github.com/elmindreda/c_dfDIJoystick2
//
static DIOBJECTDATAFORMAT _glfwObjectDataFormats[] =
{
{ &GUID_XAxis,DIJOFS_X,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_YAxis,DIJOFS_Y,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_ZAxis,DIJOFS_Z,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_RxAxis,DIJOFS_RX,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_RyAxis,DIJOFS_RY,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_RzAxis,DIJOFS_RZ,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_Slider,DIJOFS_SLIDER(0),DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_Slider,DIJOFS_SLIDER(1),DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_POV,DIJOFS_POV(0),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ &GUID_POV,DIJOFS_POV(1),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ &GUID_POV,DIJOFS_POV(2),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ &GUID_POV,DIJOFS_POV(3),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(0),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(1),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(2),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(3),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(4),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(5),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(6),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(7),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(8),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(9),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(10),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(11),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(12),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(13),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(14),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(15),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(16),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(17),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(18),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(19),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(20),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(21),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(22),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(23),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(24),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(25),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(26),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(27),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(28),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(29),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(30),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(31),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
};
// Our clone of c_dfDIJoystick
//
static const DIDATAFORMAT _glfwDataFormat =
{
sizeof(DIDATAFORMAT),
sizeof(DIOBJECTDATAFORMAT),
DIDFT_ABSAXIS,
sizeof(DIJOYSTATE),
sizeof(_glfwObjectDataFormats) / sizeof(DIOBJECTDATAFORMAT),
_glfwObjectDataFormats
};
// Returns a description fitting the specified XInput capabilities
//
static const char* getDeviceDescription(const XINPUT_CAPABILITIES* xic)
{
switch (xic->SubType)
{
case XINPUT_DEVSUBTYPE_WHEEL:
return "XInput Wheel";
case XINPUT_DEVSUBTYPE_ARCADE_STICK:
return "XInput Arcade Stick";
case XINPUT_DEVSUBTYPE_FLIGHT_STICK:
return "XInput Flight Stick";
case XINPUT_DEVSUBTYPE_DANCE_PAD:
return "XInput Dance Pad";
case XINPUT_DEVSUBTYPE_GUITAR:
return "XInput Guitar";
case XINPUT_DEVSUBTYPE_DRUM_KIT:
return "XInput Drum Kit";
case XINPUT_DEVSUBTYPE_GAMEPAD:
{
if (xic->Flags & XINPUT_CAPS_WIRELESS)
return "Wireless Xbox Controller";
else
return "Xbox Controller";
}
}
return "Unknown XInput Device";
}
// Lexically compare device objects
//
static int compareJoystickObjects(const void* first, const void* second)
{
const _GLFWjoyobjectWin32* fo = first;
const _GLFWjoyobjectWin32* so = second;
if (fo->type != so->type)
return fo->type - so->type;
return fo->offset - so->offset;
}
// Checks whether the specified device supports XInput
// Technique from FDInputJoystickManager::IsXInputDeviceFast in ZDoom
//
static GLFWbool supportsXInput(const GUID* guid)
{
UINT i, count = 0;
RAWINPUTDEVICELIST* ridl;
GLFWbool result = GLFW_FALSE;
if (GetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)) != 0)
return GLFW_FALSE;
ridl = calloc(count, sizeof(RAWINPUTDEVICELIST));
if (GetRawInputDeviceList(ridl, &count, sizeof(RAWINPUTDEVICELIST)) == (UINT) -1)
{
free(ridl);
return GLFW_FALSE;
}
for (i = 0; i < count; i++)
{
RID_DEVICE_INFO rdi;
char name[256];
UINT size;
if (ridl[i].dwType != RIM_TYPEHID)
continue;
ZeroMemory(&rdi, sizeof(rdi));
rdi.cbSize = sizeof(rdi);
size = sizeof(rdi);
if ((INT) GetRawInputDeviceInfoA(ridl[i].hDevice,
RIDI_DEVICEINFO,
&rdi, &size) == -1)
{
continue;
}
if (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) != (LONG) guid->Data1)
continue;
memset(name, 0, sizeof(name));
size = sizeof(name);
if ((INT) GetRawInputDeviceInfoA(ridl[i].hDevice,
RIDI_DEVICENAME,
name, &size) == -1)
{
break;
}
name[sizeof(name) - 1] = '\0';
if (strstr(name, "IG_"))
{
result = GLFW_TRUE;
break;
}
}
free(ridl);
return result;
}
// Frees all resources associated with the specified joystick
//
static void closeJoystick(_GLFWjoystick* js)
{
if (js->win32.device)
{
IDirectInputDevice8_Unacquire(js->win32.device);
IDirectInputDevice8_Release(js->win32.device);
}
_glfwFreeJoystick(js);
_glfwInputJoystick(js, GLFW_DISCONNECTED);
}
// DirectInput device object enumeration callback
// Insights gleaned from SDL
//
static BOOL CALLBACK deviceObjectCallback(const DIDEVICEOBJECTINSTANCEW* doi,
void* user)
{
_GLFWobjenumWin32* data = user;
_GLFWjoyobjectWin32* object = data->objects + data->objectCount;
if (DIDFT_GETTYPE(doi->dwType) & DIDFT_AXIS)
{
DIPROPRANGE dipr;
if (memcmp(&doi->guidType, &GUID_Slider, sizeof(GUID)) == 0)
object->offset = DIJOFS_SLIDER(data->sliderCount);
else if (memcmp(&doi->guidType, &GUID_XAxis, sizeof(GUID)) == 0)
object->offset = DIJOFS_X;
else if (memcmp(&doi->guidType, &GUID_YAxis, sizeof(GUID)) == 0)
object->offset = DIJOFS_Y;
else if (memcmp(&doi->guidType, &GUID_ZAxis, sizeof(GUID)) == 0)
object->offset = DIJOFS_Z;
else if (memcmp(&doi->guidType, &GUID_RxAxis, sizeof(GUID)) == 0)
object->offset = DIJOFS_RX;
else if (memcmp(&doi->guidType, &GUID_RyAxis, sizeof(GUID)) == 0)
object->offset = DIJOFS_RY;
else if (memcmp(&doi->guidType, &GUID_RzAxis, sizeof(GUID)) == 0)
object->offset = DIJOFS_RZ;
else
return DIENUM_CONTINUE;
ZeroMemory(&dipr, sizeof(dipr));
dipr.diph.dwSize = sizeof(dipr);
dipr.diph.dwHeaderSize = sizeof(dipr.diph);
dipr.diph.dwObj = doi->dwType;
dipr.diph.dwHow = DIPH_BYID;
dipr.lMin = -32768;
dipr.lMax = 32767;
if (FAILED(IDirectInputDevice8_SetProperty(data->device,
DIPROP_RANGE,
&dipr.diph)))
{
return DIENUM_CONTINUE;
}
if (memcmp(&doi->guidType, &GUID_Slider, sizeof(GUID)) == 0)
{
object->type = _GLFW_TYPE_SLIDER;
data->sliderCount++;
}
else
{
object->type = _GLFW_TYPE_AXIS;
data->axisCount++;
}
}
else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_BUTTON)
{
object->offset = DIJOFS_BUTTON(data->buttonCount);
object->type = _GLFW_TYPE_BUTTON;
data->buttonCount++;
}
else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_POV)
{
object->offset = DIJOFS_POV(data->povCount);
object->type = _GLFW_TYPE_POV;
data->povCount++;
}
data->objectCount++;
return DIENUM_CONTINUE;
}
// DirectInput device enumeration callback
//
static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
{
int jid = 0;
DIDEVCAPS dc;
DIPROPDWORD dipd;
IDirectInputDevice8* device;
_GLFWobjenumWin32 data;
_GLFWjoystick* js;
char guid[33];
char name[256];
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
_GLFWjoystick* js = _glfw.joysticks + jid;
if (js->present)
{
if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0)
return DIENUM_CONTINUE;
}
}
if (supportsXInput(&di->guidProduct))
return DIENUM_CONTINUE;
if (FAILED(IDirectInput8_CreateDevice(_glfw.win32.dinput8.api,
&di->guidInstance,
&device,
NULL)))
{
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create device");
return DIENUM_CONTINUE;
}
if (FAILED(IDirectInputDevice8_SetDataFormat(device, &_glfwDataFormat)))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to set device data format");
IDirectInputDevice8_Release(device);
return DIENUM_CONTINUE;
}
ZeroMemory(&dc, sizeof(dc));
dc.dwSize = sizeof(dc);
if (FAILED(IDirectInputDevice8_GetCapabilities(device, &dc)))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to query device capabilities");
IDirectInputDevice8_Release(device);
return DIENUM_CONTINUE;
}
ZeroMemory(&dipd, sizeof(dipd));
dipd.diph.dwSize = sizeof(dipd);
dipd.diph.dwHeaderSize = sizeof(dipd.diph);
dipd.diph.dwHow = DIPH_DEVICE;
dipd.dwData = DIPROPAXISMODE_ABS;
if (FAILED(IDirectInputDevice8_SetProperty(device,
DIPROP_AXISMODE,
&dipd.diph)))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to set device axis mode");
IDirectInputDevice8_Release(device);
return DIENUM_CONTINUE;
}
memset(&data, 0, sizeof(data));
data.device = device;
data.objects = calloc(dc.dwAxes + dc.dwButtons + dc.dwPOVs,
sizeof(_GLFWjoyobjectWin32));
if (FAILED(IDirectInputDevice8_EnumObjects(device,
deviceObjectCallback,
&data,
DIDFT_AXIS | DIDFT_BUTTON | DIDFT_POV)))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to enumerate device objects");
IDirectInputDevice8_Release(device);
free(data.objects);
return DIENUM_CONTINUE;
}
qsort(data.objects, data.objectCount,
sizeof(_GLFWjoyobjectWin32),
compareJoystickObjects);
if (!WideCharToMultiByte(CP_UTF8, 0,
di->tszInstanceName, -1,
name, sizeof(name),
NULL, NULL))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert joystick name to UTF-8");
IDirectInputDevice8_Release(device);
free(data.objects);
return DIENUM_STOP;
}
// Generate a joystick GUID that matches the SDL 2.0.5+ one
if (memcmp(&di->guidProduct.Data4[2], "PIDVID", 6) == 0)
{
sprintf(guid, "03000000%02x%02x0000%02x%02x000000000000",
(uint8_t) di->guidProduct.Data1,
(uint8_t) (di->guidProduct.Data1 >> 8),
(uint8_t) (di->guidProduct.Data1 >> 16),
(uint8_t) (di->guidProduct.Data1 >> 24));
}
else
{
sprintf(guid, "05000000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
name[0], name[1], name[2], name[3],
name[4], name[5], name[6], name[7],
name[8], name[9], name[10]);
}
js = _glfwAllocJoystick(name, guid,
data.axisCount + data.sliderCount,
data.buttonCount,
data.povCount);
if (!js)
{
IDirectInputDevice8_Release(device);
free(data.objects);
return DIENUM_STOP;
}
js->win32.device = device;
js->win32.guid = di->guidInstance;
js->win32.objects = data.objects;
js->win32.objectCount = data.objectCount;
_glfwInputJoystick(js, GLFW_CONNECTED);
return DIENUM_CONTINUE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Initialize joystick interface
//
void _glfwInitJoysticksWin32(void)
{
if (_glfw.win32.dinput8.instance)
{
if (FAILED(DirectInput8Create(GetModuleHandle(NULL),
DIRECTINPUT_VERSION,
&IID_IDirectInput8W,
(void**) &_glfw.win32.dinput8.api,
NULL)))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to create interface");
}
}
_glfwDetectJoystickConnectionWin32();
}
// Close all opened joystick handles
//
void _glfwTerminateJoysticksWin32(void)
{
int jid;
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
closeJoystick(_glfw.joysticks + jid);
if (_glfw.win32.dinput8.api)
IDirectInput8_Release(_glfw.win32.dinput8.api);
}
// Checks for new joysticks after DBT_DEVICEARRIVAL
//
void _glfwDetectJoystickConnectionWin32(void)
{
if (_glfw.win32.xinput.instance)
{
DWORD index;
for (index = 0; index < XUSER_MAX_COUNT; index++)
{
int jid;
char guid[33];
XINPUT_CAPABILITIES xic;
_GLFWjoystick* js;
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
if (_glfw.joysticks[jid].present &&
_glfw.joysticks[jid].win32.device == NULL &&
_glfw.joysticks[jid].win32.index == index)
{
break;
}
}
if (jid <= GLFW_JOYSTICK_LAST)
continue;
if (XInputGetCapabilities(index, 0, &xic) != ERROR_SUCCESS)
continue;
// Generate a joystick GUID that matches the SDL 2.0.5+ one
sprintf(guid, "78696e707574%02x000000000000000000",
xic.SubType & 0xff);
js = _glfwAllocJoystick(getDeviceDescription(&xic), guid, 6, 10, 1);
if (!js)
continue;
js->win32.index = index;
_glfwInputJoystick(js, GLFW_CONNECTED);
}
}
if (_glfw.win32.dinput8.api)
{
if (FAILED(IDirectInput8_EnumDevices(_glfw.win32.dinput8.api,
DI8DEVCLASS_GAMECTRL,
deviceCallback,
NULL,
DIEDFL_ALLDEVICES)))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Failed to enumerate DirectInput8 devices");
return;
}
}
}
// Checks for joystick disconnection after DBT_DEVICEREMOVECOMPLETE
//
void _glfwDetectJoystickDisconnectionWin32(void)
{
int jid;
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
_GLFWjoystick* js = _glfw.joysticks + jid;
if (js->present)
_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE);
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
{
if (js->win32.device)
{
int i, ai = 0, bi = 0, pi = 0;
HRESULT result;
DIJOYSTATE state;
IDirectInputDevice8_Poll(js->win32.device);
result = IDirectInputDevice8_GetDeviceState(js->win32.device,
sizeof(state),
&state);
if (result == DIERR_NOTACQUIRED || result == DIERR_INPUTLOST)
{
IDirectInputDevice8_Acquire(js->win32.device);
IDirectInputDevice8_Poll(js->win32.device);
result = IDirectInputDevice8_GetDeviceState(js->win32.device,
sizeof(state),
&state);
}
if (FAILED(result))
{
closeJoystick(js);
return GLFW_FALSE;
}
if (mode == _GLFW_POLL_PRESENCE)
return GLFW_TRUE;
for (i = 0; i < js->win32.objectCount; i++)
{
const void* data = (char*) &state + js->win32.objects[i].offset;
switch (js->win32.objects[i].type)
{
case _GLFW_TYPE_AXIS:
case _GLFW_TYPE_SLIDER:
{
const float value = (*((LONG*) data) + 0.5f) / 32767.5f;
_glfwInputJoystickAxis(js, ai, value);
ai++;
break;
}
case _GLFW_TYPE_BUTTON:
{
const char value = (*((BYTE*) data) & 0x80) != 0;
_glfwInputJoystickButton(js, bi, value);
bi++;
break;
}
case _GLFW_TYPE_POV:
{
const int states[9] =
{
GLFW_HAT_UP,
GLFW_HAT_RIGHT_UP,
GLFW_HAT_RIGHT,
GLFW_HAT_RIGHT_DOWN,
GLFW_HAT_DOWN,
GLFW_HAT_LEFT_DOWN,
GLFW_HAT_LEFT,
GLFW_HAT_LEFT_UP,
GLFW_HAT_CENTERED
};
// Screams of horror are appropriate at this point
int state = LOWORD(*(DWORD*) data) / (45 * DI_DEGREES);
if (state < 0 || state > 8)
state = 8;
_glfwInputJoystickHat(js, pi, states[state]);
pi++;
break;
}
}
}
}
else
{
int i, dpad = 0;
DWORD result;
XINPUT_STATE xis;
const WORD buttons[10] =
{
XINPUT_GAMEPAD_A,
XINPUT_GAMEPAD_B,
XINPUT_GAMEPAD_X,
XINPUT_GAMEPAD_Y,
XINPUT_GAMEPAD_LEFT_SHOULDER,
XINPUT_GAMEPAD_RIGHT_SHOULDER,
XINPUT_GAMEPAD_BACK,
XINPUT_GAMEPAD_START,
XINPUT_GAMEPAD_LEFT_THUMB,
XINPUT_GAMEPAD_RIGHT_THUMB
};
result = XInputGetState(js->win32.index, &xis);
if (result != ERROR_SUCCESS)
{
if (result == ERROR_DEVICE_NOT_CONNECTED)
closeJoystick(js);
return GLFW_FALSE;
}
if (mode == _GLFW_POLL_PRESENCE)
return GLFW_TRUE;
_glfwInputJoystickAxis(js, 0, (xis.Gamepad.sThumbLX + 0.5f) / 32767.5f);
_glfwInputJoystickAxis(js, 1, -(xis.Gamepad.sThumbLY + 0.5f) / 32767.5f);
_glfwInputJoystickAxis(js, 2, (xis.Gamepad.sThumbRX + 0.5f) / 32767.5f);
_glfwInputJoystickAxis(js, 3, -(xis.Gamepad.sThumbRY + 0.5f) / 32767.5f);
_glfwInputJoystickAxis(js, 4, xis.Gamepad.bLeftTrigger / 127.5f - 1.f);
_glfwInputJoystickAxis(js, 5, xis.Gamepad.bRightTrigger / 127.5f - 1.f);
for (i = 0; i < 10; i++)
{
const char value = (xis.Gamepad.wButtons & buttons[i]) ? 1 : 0;
_glfwInputJoystickButton(js, i, value);
}
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)
dpad |= GLFW_HAT_UP;
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
dpad |= GLFW_HAT_RIGHT;
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)
dpad |= GLFW_HAT_DOWN;
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
dpad |= GLFW_HAT_LEFT;
_glfwInputJoystickHat(js, 0, dpad);
}
return GLFW_TRUE;
}
void _glfwPlatformUpdateGamepadGUID(char* guid)
{
if (strcmp(guid + 20, "504944564944") == 0)
{
char original[33];
strcpy(original, guid);
sprintf(guid, "03000000%.4s0000%.4s000000000000",
original, original + 4);
}
}

56
glfw/win32_joystick.h vendored
View File

@@ -1,56 +0,0 @@
//========================================================================
// GLFW 3.3 Win32 - www.glfw.org
//------------------------------------------------------------------------
// 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 _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickWin32 win32
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE int dummy
#define _GLFW_PLATFORM_MAPPING_NAME "Windows"
// Joystick element (axis, button or slider)
//
typedef struct _GLFWjoyobjectWin32
{
int offset;
int type;
} _GLFWjoyobjectWin32;
// Win32-specific per-joystick data
//
typedef struct _GLFWjoystickWin32
{
_GLFWjoyobjectWin32* objects;
int objectCount;
IDirectInputDevice8W* device;
DWORD index;
GUID guid;
} _GLFWjoystickWin32;
void _glfwInitJoysticksWin32(void);
void _glfwTerminateJoysticksWin32(void);
void _glfwDetectJoystickConnectionWin32(void);
void _glfwDetectJoystickDisconnectionWin32(void);

513
glfw/win32_monitor.c vendored
View File

@@ -1,513 +0,0 @@
//========================================================================
// GLFW 3.3 Win32 - 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 <string.h>
#include <limits.h>
#include <malloc.h>
// Callback for EnumDisplayMonitors in createMonitor
//
static BOOL CALLBACK monitorCallback(HMONITOR handle,
HDC dc,
RECT* rect,
LPARAM data)
{
MONITORINFOEXW mi;
ZeroMemory(&mi, sizeof(mi));
mi.cbSize = sizeof(mi);
if (GetMonitorInfoW(handle, (MONITORINFO*) &mi))
{
_GLFWmonitor* monitor = (_GLFWmonitor*) data;
if (wcscmp(mi.szDevice, monitor->win32.adapterName) == 0)
monitor->win32.handle = handle;
}
return TRUE;
}
// Create monitor from an adapter and (optionally) a display
//
static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter,
DISPLAY_DEVICEW* display)
{
_GLFWmonitor* monitor;
int widthMM, heightMM;
char* name;
HDC dc;
DEVMODEW dm;
RECT rect;
if (display)
name = _glfwCreateUTF8FromWideStringWin32(display->DeviceString);
else
name = _glfwCreateUTF8FromWideStringWin32(adapter->DeviceString);
if (!name)
return NULL;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
EnumDisplaySettingsW(adapter->DeviceName, ENUM_CURRENT_SETTINGS, &dm);
dc = CreateDCW(L"DISPLAY", adapter->DeviceName, NULL, NULL);
if (IsWindows8Point1OrGreater())
{
widthMM = GetDeviceCaps(dc, HORZSIZE);
heightMM = GetDeviceCaps(dc, VERTSIZE);
}
else
{
widthMM = (int) (dm.dmPelsWidth * 25.4f / GetDeviceCaps(dc, LOGPIXELSX));
heightMM = (int) (dm.dmPelsHeight * 25.4f / GetDeviceCaps(dc, LOGPIXELSY));
}
DeleteDC(dc);
monitor = _glfwAllocMonitor(name, widthMM, heightMM);
free(name);
if (adapter->StateFlags & DISPLAY_DEVICE_MODESPRUNED)
monitor->win32.modesPruned = GLFW_TRUE;
wcscpy(monitor->win32.adapterName, adapter->DeviceName);
WideCharToMultiByte(CP_UTF8, 0,
adapter->DeviceName, -1,
monitor->win32.publicAdapterName,
sizeof(monitor->win32.publicAdapterName),
NULL, NULL);
if (display)
{
wcscpy(monitor->win32.displayName, display->DeviceName);
WideCharToMultiByte(CP_UTF8, 0,
display->DeviceName, -1,
monitor->win32.publicDisplayName,
sizeof(monitor->win32.publicDisplayName),
NULL, NULL);
}
rect.left = dm.dmPosition.x;
rect.top = dm.dmPosition.y;
rect.right = dm.dmPosition.x + dm.dmPelsWidth;
rect.bottom = dm.dmPosition.y + dm.dmPelsHeight;
EnumDisplayMonitors(NULL, &rect, monitorCallback, (LPARAM) monitor);
return monitor;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Poll for changes in the set of connected monitors
//
void _glfwPollMonitorsWin32(void)
{
int i, disconnectedCount;
_GLFWmonitor** disconnected = NULL;
DWORD adapterIndex, displayIndex;
DISPLAY_DEVICEW adapter, display;
_GLFWmonitor* monitor;
disconnectedCount = _glfw.monitorCount;
if (disconnectedCount)
{
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
memcpy(disconnected,
_glfw.monitors,
_glfw.monitorCount * sizeof(_GLFWmonitor*));
}
for (adapterIndex = 0; ; adapterIndex++)
{
int type = _GLFW_INSERT_LAST;
ZeroMemory(&adapter, sizeof(adapter));
adapter.cb = sizeof(adapter);
if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0))
break;
if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
continue;
if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
type = _GLFW_INSERT_FIRST;
for (displayIndex = 0; ; displayIndex++)
{
ZeroMemory(&display, sizeof(display));
display.cb = sizeof(display);
if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0))
break;
if (!(display.StateFlags & DISPLAY_DEVICE_ACTIVE))
continue;
for (i = 0; i < disconnectedCount; i++)
{
if (disconnected[i] &&
wcscmp(disconnected[i]->win32.displayName,
display.DeviceName) == 0)
{
disconnected[i] = NULL;
break;
}
}
if (i < disconnectedCount)
continue;
monitor = createMonitor(&adapter, &display);
if (!monitor)
{
free(disconnected);
return;
}
_glfwInputMonitor(monitor, GLFW_CONNECTED, type);
type = _GLFW_INSERT_LAST;
}
// HACK: If an active adapter does not have any display devices
// (as sometimes happens), add it directly as a monitor
if (displayIndex == 0)
{
for (i = 0; i < disconnectedCount; i++)
{
if (disconnected[i] &&
wcscmp(disconnected[i]->win32.adapterName,
adapter.DeviceName) == 0)
{
disconnected[i] = NULL;
break;
}
}
if (i < disconnectedCount)
continue;
monitor = createMonitor(&adapter, NULL);
if (!monitor)
{
free(disconnected);
return;
}
_glfwInputMonitor(monitor, GLFW_CONNECTED, type);
}
}
for (i = 0; i < disconnectedCount; i++)
{
if (disconnected[i])
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
}
free(disconnected);
}
// Change the current video mode
//
void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired)
{
GLFWvidmode current;
const GLFWvidmode* best;
DEVMODEW dm;
LONG result;
best = _glfwChooseVideoMode(monitor, desired);
_glfwPlatformGetVideoMode(monitor, &current);
if (_glfwCompareVideoModes(&current, best) == 0)
return;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL |
DM_DISPLAYFREQUENCY;
dm.dmPelsWidth = best->width;
dm.dmPelsHeight = best->height;
dm.dmBitsPerPel = best->redBits + best->greenBits + best->blueBits;
dm.dmDisplayFrequency = best->refreshRate;
if (dm.dmBitsPerPel < 15 || dm.dmBitsPerPel >= 24)
dm.dmBitsPerPel = 32;
result = ChangeDisplaySettingsExW(monitor->win32.adapterName,
&dm,
NULL,
CDS_FULLSCREEN,
NULL);
if (result == DISP_CHANGE_SUCCESSFUL)
monitor->win32.modeChanged = GLFW_TRUE;
else
{
const char* description = "Unknown error";
if (result == DISP_CHANGE_BADDUALVIEW)
description = "The system uses DualView";
else if (result == DISP_CHANGE_BADFLAGS)
description = "Invalid flags";
else if (result == DISP_CHANGE_BADMODE)
description = "Graphics mode not supported";
else if (result == DISP_CHANGE_BADPARAM)
description = "Invalid parameter";
else if (result == DISP_CHANGE_FAILED)
description = "Graphics mode failed";
else if (result == DISP_CHANGE_NOTUPDATED)
description = "Failed to write to registry";
else if (result == DISP_CHANGE_RESTART)
description = "Computer restart required";
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to set video mode: %s",
description);
}
}
// Restore the previously saved (original) video mode
//
void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor)
{
if (monitor->win32.modeChanged)
{
ChangeDisplaySettingsExW(monitor->win32.adapterName,
NULL, NULL, CDS_FULLSCREEN, NULL);
monitor->win32.modeChanged = GLFW_FALSE;
}
}
void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* yscale)
{
UINT xdpi, ydpi;
if (IsWindows8Point1OrGreater())
GetDpiForMonitor(handle, MDT_EFFECTIVE_DPI, &xdpi, &ydpi);
else
{
const HDC dc = GetDC(NULL);
xdpi = GetDeviceCaps(dc, LOGPIXELSX);
ydpi = GetDeviceCaps(dc, LOGPIXELSY);
ReleaseDC(NULL, dc);
}
if (xscale)
*xscale = xdpi / (float) USER_DEFAULT_SCREEN_DPI;
if (yscale)
*yscale = ydpi / (float) USER_DEFAULT_SCREEN_DPI;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
{
}
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
{
DEVMODEW dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
EnumDisplaySettingsExW(monitor->win32.adapterName,
ENUM_CURRENT_SETTINGS,
&dm,
EDS_ROTATEDMODE);
if (xpos)
*xpos = dm.dmPosition.x;
if (ypos)
*ypos = dm.dmPosition.y;
}
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
float* xscale, float* yscale)
{
_glfwGetMonitorContentScaleWin32(monitor->win32.handle, xscale, yscale);
}
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
{
int modeIndex = 0, size = 0;
GLFWvidmode* result = NULL;
*count = 0;
for (;;)
{
int i;
GLFWvidmode mode;
DEVMODEW dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
if (!EnumDisplaySettingsW(monitor->win32.adapterName, modeIndex, &dm))
break;
modeIndex++;
// Skip modes with less than 15 BPP
if (dm.dmBitsPerPel < 15)
continue;
mode.width = dm.dmPelsWidth;
mode.height = dm.dmPelsHeight;
mode.refreshRate = dm.dmDisplayFrequency;
_glfwSplitBPP(dm.dmBitsPerPel,
&mode.redBits,
&mode.greenBits,
&mode.blueBits);
for (i = 0; i < *count; i++)
{
if (_glfwCompareVideoModes(result + i, &mode) == 0)
break;
}
// Skip duplicate modes
if (i < *count)
continue;
if (monitor->win32.modesPruned)
{
// Skip modes not supported by the connected displays
if (ChangeDisplaySettingsExW(monitor->win32.adapterName,
&dm,
NULL,
CDS_TEST,
NULL) != DISP_CHANGE_SUCCESSFUL)
{
continue;
}
}
if (*count == size)
{
size += 128;
result = (GLFWvidmode*) realloc(result, size * sizeof(GLFWvidmode));
}
(*count)++;
result[*count - 1] = mode;
}
if (!*count)
{
// HACK: Report the current mode if no valid modes were found
result = calloc(1, sizeof(GLFWvidmode));
_glfwPlatformGetVideoMode(monitor, result);
*count = 1;
}
return result;
}
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
{
DEVMODEW dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
EnumDisplaySettingsW(monitor->win32.adapterName, ENUM_CURRENT_SETTINGS, &dm);
mode->width = dm.dmPelsWidth;
mode->height = dm.dmPelsHeight;
mode->refreshRate = dm.dmDisplayFrequency;
_glfwSplitBPP(dm.dmBitsPerPel,
&mode->redBits,
&mode->greenBits,
&mode->blueBits);
}
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{
HDC dc;
WORD values[768];
dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL);
GetDeviceGammaRamp(dc, values);
DeleteDC(dc);
_glfwAllocGammaArrays(ramp, 256);
memcpy(ramp->red, values + 0, 256 * sizeof(unsigned short));
memcpy(ramp->green, values + 256, 256 * sizeof(unsigned short));
memcpy(ramp->blue, values + 512, 256 * sizeof(unsigned short));
}
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{
HDC dc;
WORD values[768];
if (ramp->size != 256)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Gamma ramp size must be 256");
return;
}
memcpy(values + 0, ramp->red, 256 * sizeof(unsigned short));
memcpy(values + 256, ramp->green, 256 * sizeof(unsigned short));
memcpy(values + 512, ramp->blue, 256 * sizeof(unsigned short));
dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL);
SetDeviceGammaRamp(dc, values);
DeleteDC(dc);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW native API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return monitor->win32.publicAdapterName;
}
GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return monitor->win32.publicDisplayName;
}

449
glfw/win32_platform.h vendored
View File

@@ -1,449 +0,0 @@
//========================================================================
// GLFW 3.3 Win32 - 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.
//
//========================================================================
// We don't need all the fancy stuff
#ifndef NOMINMAX
#define NOMINMAX
#endif
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN
#endif
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
// example to allow applications to correctly declare a GL_ARB_debug_output
// callback) but windows.h assumes no one will define APIENTRY before it does
#undef APIENTRY
// GLFW on Windows is Unicode only and does not work in MBCS mode
#ifndef UNICODE
#define UNICODE
#endif
// GLFW requires Windows XP or later
#if WINVER < 0x0501
#undef WINVER
#define WINVER 0x0501
#endif
#if _WIN32_WINNT < 0x0501
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
// GLFW uses DirectInput8 interfaces
#define DIRECTINPUT_VERSION 0x0800
#include <wctype.h>
#include <windows.h>
#include <dinput.h>
#include <xinput.h>
#include <dbt.h>
// HACK: Define macros that some windows.h variants don't
#ifndef WM_MOUSEHWHEEL
#define WM_MOUSEHWHEEL 0x020E
#endif
#ifndef WM_DWMCOMPOSITIONCHANGED
#define WM_DWMCOMPOSITIONCHANGED 0x031E
#endif
#ifndef WM_COPYGLOBALDATA
#define WM_COPYGLOBALDATA 0x0049
#endif
#ifndef WM_UNICHAR
#define WM_UNICHAR 0x0109
#endif
#ifndef UNICODE_NOCHAR
#define UNICODE_NOCHAR 0xFFFF
#endif
#ifndef WM_DPICHANGED
#define WM_DPICHANGED 0x02E0
#endif
#ifndef GET_XBUTTON_WPARAM
#define GET_XBUTTON_WPARAM(w) (HIWORD(w))
#endif
#ifndef EDS_ROTATEDMODE
#define EDS_ROTATEDMODE 0x00000004
#endif
#ifndef DISPLAY_DEVICE_ACTIVE
#define DISPLAY_DEVICE_ACTIVE 0x00000001
#endif
#ifndef _WIN32_WINNT_WINBLUE
#define _WIN32_WINNT_WINBLUE 0x0602
#endif
#ifndef WM_GETDPISCALEDSIZE
#define WM_GETDPISCALEDSIZE 0x02e4
#endif
#ifndef USER_DEFAULT_SCREEN_DPI
#define USER_DEFAULT_SCREEN_DPI 96
#endif
#if WINVER < 0x0601
typedef struct
{
DWORD cbSize;
DWORD ExtStatus;
} CHANGEFILTERSTRUCT;
#ifndef MSGFLT_ALLOW
#define MSGFLT_ALLOW 1
#endif
#endif /*Windows 7*/
#if WINVER < 0x0600
#define DWM_BB_ENABLE 0x00000001
#define DWM_BB_BLURREGION 0x00000002
typedef struct
{
DWORD dwFlags;
BOOL fEnable;
HRGN hRgnBlur;
BOOL fTransitionOnMaximized;
} DWM_BLURBEHIND;
#else
#include <dwmapi.h>
#endif /*Windows Vista*/
#ifndef DPI_ENUMS_DECLARED
typedef enum
{
PROCESS_DPI_UNAWARE = 0,
PROCESS_SYSTEM_DPI_AWARE = 1,
PROCESS_PER_MONITOR_DPI_AWARE = 2
} PROCESS_DPI_AWARENESS;
typedef enum
{
MDT_EFFECTIVE_DPI = 0,
MDT_ANGULAR_DPI = 1,
MDT_RAW_DPI = 2,
MDT_DEFAULT = MDT_EFFECTIVE_DPI
} MONITOR_DPI_TYPE;
#endif /*DPI_ENUMS_DECLARED*/
#ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT) -4)
#endif /*DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2*/
// HACK: Define versionhelpers.h functions manually as MinGW lacks the header
#define IsWindowsXPOrGreater() \
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINXP), \
LOBYTE(_WIN32_WINNT_WINXP), 0)
#define IsWindowsVistaOrGreater() \
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_VISTA), \
LOBYTE(_WIN32_WINNT_VISTA), 0)
#define IsWindows7OrGreater() \
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN7), \
LOBYTE(_WIN32_WINNT_WIN7), 0)
#define IsWindows8OrGreater() \
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN8), \
LOBYTE(_WIN32_WINNT_WIN8), 0)
#define IsWindows8Point1OrGreater() \
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINBLUE), \
LOBYTE(_WIN32_WINNT_WINBLUE), 0)
#define _glfwIsWindows10AnniversaryUpdateOrGreaterWin32() \
_glfwIsWindows10BuildOrGreaterWin32(14393)
#define _glfwIsWindows10CreatorsUpdateOrGreaterWin32() \
_glfwIsWindows10BuildOrGreaterWin32(15063)
// HACK: Define macros that some xinput.h variants don't
#ifndef XINPUT_CAPS_WIRELESS
#define XINPUT_CAPS_WIRELESS 0x0002
#endif
#ifndef XINPUT_DEVSUBTYPE_WHEEL
#define XINPUT_DEVSUBTYPE_WHEEL 0x02
#endif
#ifndef XINPUT_DEVSUBTYPE_ARCADE_STICK
#define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03
#endif
#ifndef XINPUT_DEVSUBTYPE_FLIGHT_STICK
#define XINPUT_DEVSUBTYPE_FLIGHT_STICK 0x04
#endif
#ifndef XINPUT_DEVSUBTYPE_DANCE_PAD
#define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05
#endif
#ifndef XINPUT_DEVSUBTYPE_GUITAR
#define XINPUT_DEVSUBTYPE_GUITAR 0x06
#endif
#ifndef XINPUT_DEVSUBTYPE_DRUM_KIT
#define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08
#endif
#ifndef XINPUT_DEVSUBTYPE_ARCADE_PAD
#define XINPUT_DEVSUBTYPE_ARCADE_PAD 0x13
#endif
#ifndef XUSER_MAX_COUNT
#define XUSER_MAX_COUNT 4
#endif
// HACK: Define macros that some dinput.h variants don't
#ifndef DIDFT_OPTIONAL
#define DIDFT_OPTIONAL 0x80000000
#endif
// winmm.dll function pointer typedefs
typedef DWORD (WINAPI * PFN_timeGetTime)(void);
#define timeGetTime _glfw.win32.winmm.GetTime
// xinput.dll function pointer typedefs
typedef DWORD (WINAPI * PFN_XInputGetCapabilities)(DWORD,DWORD,XINPUT_CAPABILITIES*);
typedef DWORD (WINAPI * PFN_XInputGetState)(DWORD,XINPUT_STATE*);
#define XInputGetCapabilities _glfw.win32.xinput.GetCapabilities
#define XInputGetState _glfw.win32.xinput.GetState
// dinput8.dll function pointer typedefs
typedef HRESULT (WINAPI * PFN_DirectInput8Create)(HINSTANCE,DWORD,REFIID,LPVOID*,LPUNKNOWN);
#define DirectInput8Create _glfw.win32.dinput8.Create
// user32.dll function pointer typedefs
typedef BOOL (WINAPI * PFN_SetProcessDPIAware)(void);
typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,CHANGEFILTERSTRUCT*);
typedef BOOL (WINAPI * PFN_EnableNonClientDpiScaling)(HWND);
typedef BOOL (WINAPI * PFN_SetProcessDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
typedef UINT (WINAPI * PFN_GetDpiForWindow)(HWND);
typedef BOOL (WINAPI * PFN_AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT);
#define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_
#define ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx_
#define EnableNonClientDpiScaling _glfw.win32.user32.EnableNonClientDpiScaling_
#define SetProcessDpiAwarenessContext _glfw.win32.user32.SetProcessDpiAwarenessContext_
#define GetDpiForWindow _glfw.win32.user32.GetDpiForWindow_
#define AdjustWindowRectExForDpi _glfw.win32.user32.AdjustWindowRectExForDpi_
// dwmapi.dll function pointer typedefs
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
typedef HRESULT(WINAPI * PFN_DwmEnableBlurBehindWindow)(HWND,const DWM_BLURBEHIND*);
#define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
#define DwmFlush _glfw.win32.dwmapi.Flush
#define DwmEnableBlurBehindWindow _glfw.win32.dwmapi.EnableBlurBehindWindow
// shcore.dll function pointer typedefs
typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
typedef HRESULT (WINAPI * PFN_GetDpiForMonitor)(HMONITOR,MONITOR_DPI_TYPE,UINT*,UINT*);
#define SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness_
#define GetDpiForMonitor _glfw.win32.shcore.GetDpiForMonitor_
// ntdll.dll function pointer typedefs
typedef LONG (WINAPI * PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*,ULONG,ULONGLONG);
#define RtlVerifyVersionInfo _glfw.win32.ntdll.RtlVerifyVersionInfo_
typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
typedef struct VkWin32SurfaceCreateInfoKHR
{
VkStructureType sType;
const void* pNext;
VkWin32SurfaceCreateFlagsKHR flags;
HINSTANCE hinstance;
HWND hwnd;
} VkWin32SurfaceCreateInfoKHR;
typedef VkResult (APIENTRY *PFN_vkCreateWin32SurfaceKHR)(VkInstance,const VkWin32SurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice,uint32_t);
#include "win32_joystick.h"
#include "wgl_context.h"
#include "egl_context.h"
#include "osmesa_context.h"
#if !defined(_GLFW_WNDCLASSNAME)
#define _GLFW_WNDCLASSNAME L"GLFW30"
#endif
#define _glfw_dlopen(name) LoadLibraryA(name)
#define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle)
#define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name)
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->win32.handle)
#define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 win32
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32
#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerWin32 win32
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWin32 win32
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorWin32 win32
#define _GLFW_PLATFORM_TLS_STATE _GLFWtlsWin32 win32
#define _GLFW_PLATFORM_MUTEX_STATE _GLFWmutexWin32 win32
// Win32-specific per-window data
//
typedef struct _GLFWwindowWin32
{
HWND handle;
HICON bigIcon;
HICON smallIcon;
GLFWbool cursorTracked;
GLFWbool frameAction;
GLFWbool iconified;
GLFWbool maximized;
// Whether to enable framebuffer transparency on DWM
GLFWbool transparent;
GLFWbool scaleToMonitor;
// The last received cursor position, regardless of source
int lastCursorPosX, lastCursorPosY;
} _GLFWwindowWin32;
// Win32-specific global data
//
typedef struct _GLFWlibraryWin32
{
HWND helperWindowHandle;
HDEVNOTIFY deviceNotificationHandle;
DWORD foregroundLockTimeout;
int acquiredMonitorCount;
char* clipboardString;
short int keycodes[512];
short int scancodes[GLFW_KEY_LAST + 1];
char keynames[GLFW_KEY_LAST + 1][5];
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow;
RAWINPUT* rawInput;
int rawInputSize;
UINT mouseTrailSize;
struct {
HINSTANCE instance;
PFN_timeGetTime GetTime;
} winmm;
struct {
HINSTANCE instance;
PFN_DirectInput8Create Create;
IDirectInput8W* api;
} dinput8;
struct {
HINSTANCE instance;
PFN_XInputGetCapabilities GetCapabilities;
PFN_XInputGetState GetState;
} xinput;
struct {
HINSTANCE instance;
PFN_SetProcessDPIAware SetProcessDPIAware_;
PFN_ChangeWindowMessageFilterEx ChangeWindowMessageFilterEx_;
PFN_EnableNonClientDpiScaling EnableNonClientDpiScaling_;
PFN_SetProcessDpiAwarenessContext SetProcessDpiAwarenessContext_;
PFN_GetDpiForWindow GetDpiForWindow_;
PFN_AdjustWindowRectExForDpi AdjustWindowRectExForDpi_;
} user32;
struct {
HINSTANCE instance;
PFN_DwmIsCompositionEnabled IsCompositionEnabled;
PFN_DwmFlush Flush;
PFN_DwmEnableBlurBehindWindow EnableBlurBehindWindow;
} dwmapi;
struct {
HINSTANCE instance;
PFN_SetProcessDpiAwareness SetProcessDpiAwareness_;
PFN_GetDpiForMonitor GetDpiForMonitor_;
} shcore;
struct {
HINSTANCE instance;
PFN_RtlVerifyVersionInfo RtlVerifyVersionInfo_;
} ntdll;
} _GLFWlibraryWin32;
// Win32-specific per-monitor data
//
typedef struct _GLFWmonitorWin32
{
HMONITOR handle;
// This size matches the static size of DISPLAY_DEVICE.DeviceName
WCHAR adapterName[32];
WCHAR displayName[32];
char publicAdapterName[32];
char publicDisplayName[32];
GLFWbool modesPruned;
GLFWbool modeChanged;
} _GLFWmonitorWin32;
// Win32-specific per-cursor data
//
typedef struct _GLFWcursorWin32
{
HCURSOR handle;
} _GLFWcursorWin32;
// Win32-specific global timer data
//
typedef struct _GLFWtimerWin32
{
GLFWbool hasPC;
uint64_t frequency;
} _GLFWtimerWin32;
// Win32-specific thread local storage data
//
typedef struct _GLFWtlsWin32
{
GLFWbool allocated;
DWORD index;
} _GLFWtlsWin32;
// Win32-specific mutex data
//
typedef struct _GLFWmutexWin32
{
GLFWbool allocated;
CRITICAL_SECTION section;
} _GLFWmutexWin32;
GLFWbool _glfwRegisterWindowClassWin32(void);
void _glfwUnregisterWindowClassWin32(void);
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source);
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source);
BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp);
BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build);
void _glfwInputErrorWin32(int error, const char* description);
void _glfwUpdateKeyNamesWin32(void);
void _glfwInitTimerWin32(void);
void _glfwPollMonitorsWin32(void);
void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired);
void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor);
void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* yscale);

97
glfw/win32_thread.c vendored
View File

@@ -1,97 +0,0 @@
//========================================================================
// GLFW 3.3 Win32 - 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 <assert.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls)
{
assert(tls->win32.allocated == GLFW_FALSE);
tls->win32.index = TlsAlloc();
if (tls->win32.index == TLS_OUT_OF_INDEXES)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to allocate TLS index");
return GLFW_FALSE;
}
tls->win32.allocated = GLFW_TRUE;
return GLFW_TRUE;
}
void _glfwPlatformDestroyTls(_GLFWtls* tls)
{
if (tls->win32.allocated)
TlsFree(tls->win32.index);
memset(tls, 0, sizeof(_GLFWtls));
}
void* _glfwPlatformGetTls(_GLFWtls* tls)
{
assert(tls->win32.allocated == GLFW_TRUE);
return TlsGetValue(tls->win32.index);
}
void _glfwPlatformSetTls(_GLFWtls* tls, void* value)
{
assert(tls->win32.allocated == GLFW_TRUE);
TlsSetValue(tls->win32.index, value);
}
GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex)
{
assert(mutex->win32.allocated == GLFW_FALSE);
InitializeCriticalSection(&mutex->win32.section);
return mutex->win32.allocated = GLFW_TRUE;
}
void _glfwPlatformDestroyMutex(_GLFWmutex* mutex)
{
if (mutex->win32.allocated)
DeleteCriticalSection(&mutex->win32.section);
memset(mutex, 0, sizeof(_GLFWmutex));
}
void _glfwPlatformLockMutex(_GLFWmutex* mutex)
{
assert(mutex->win32.allocated == GLFW_TRUE);
EnterCriticalSection(&mutex->win32.section);
}
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex)
{
assert(mutex->win32.allocated == GLFW_TRUE);
LeaveCriticalSection(&mutex->win32.section);
}

74
glfw/win32_time.c vendored
View File

@@ -1,74 +0,0 @@
//========================================================================
// GLFW 3.3 Win32 - 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"
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Initialise timer
//
void _glfwInitTimerWin32(void)
{
uint64_t frequency;
if (QueryPerformanceFrequency((LARGE_INTEGER*) &frequency))
{
_glfw.timer.win32.hasPC = GLFW_TRUE;
_glfw.timer.win32.frequency = frequency;
}
else
{
_glfw.timer.win32.hasPC = GLFW_FALSE;
_glfw.timer.win32.frequency = 1000;
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
uint64_t _glfwPlatformGetTimerValue(void)
{
if (_glfw.timer.win32.hasPC)
{
uint64_t value;
QueryPerformanceCounter((LARGE_INTEGER*) &value);
return value;
}
else
return (uint64_t) timeGetTime();
}
uint64_t _glfwPlatformGetTimerFrequency(void)
{
return _glfw.timer.win32.frequency;
}

2192
glfw/win32_window.c vendored

File diff suppressed because it is too large Load Diff

178
glfw/window.c vendored
View File

@@ -2,7 +2,7 @@
// GLFW 3.3 - 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,14 +84,22 @@ _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;
}
// Notifies shared code that a window's occlusion state has changed
//
void _glfwInputWindowOcclusion(_GLFWwindow* window, bool occluded)
{
if (window->callbacks.occlusion)
window->callbacks.occlusion((GLFWwindow*) window, occluded);
}
// Notifies shared code that a window has moved
// The position is specified in client-area relative screen coordinates
// The position is specified in content area relative screen coordinates
//
void _glfwInputWindowPos(_GLFWwindow* window, int x, int y)
{
@@ -108,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);
@@ -116,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);
@@ -131,6 +141,14 @@ void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height)
window->callbacks.fbsize((GLFWwindow*) window, width, height);
}
// Notifies shared code that a window live resize is in progress
//
void _glfwInputLiveResize(_GLFWwindow* window, bool started)
{
if (window && window->callbacks.liveResize)
window->callbacks.liveResize((GLFWwindow*) window, started);
}
// Notifies shared code that a window content scale has changed
// The scale is specified as the ratio between the current and default DPI
//
@@ -152,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);
@@ -165,7 +183,6 @@ void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor)
window->monitor = monitor;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
@@ -254,19 +271,17 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
if (window->monitor)
{
if (wndconfig.centerCursor)
{
int width, height;
_glfwPlatformGetWindowSize(window, &width, &height);
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
}
_glfwCenterCursorInContentArea(window);
}
else
{
if (wndconfig.visible)
{
_glfwPlatformShowWindow(window);
#ifndef _GLFW_WAYLAND
if (wndconfig.focused)
_glfwPlatformFocusWindow(window);
#endif
}
}
@@ -286,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
@@ -303,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)
@@ -352,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;
@@ -418,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;
@@ -721,6 +736,15 @@ GLFWAPI void glfwGetWindowContentScale(GLFWwindow* handle,
_glfwPlatformGetWindowContentScale(window, xscale, yscale);
}
GLFWAPI double glfwGetDoubleClickInterval(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(0.5f);
return _glfwPlatformGetDoubleClickInterval(window);
}
GLFWAPI float glfwGetWindowOpacity(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
@@ -792,8 +816,10 @@ GLFWAPI void glfwShowWindow(GLFWwindow* handle)
_glfwPlatformShowWindow(window);
#ifndef _GLFW_WAYLAND
if (window->focusOnShow)
_glfwPlatformFocusWindow(window);
#endif
}
GLFWAPI void glfwRequestWindowAttention(GLFWwindow* handle)
@@ -811,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);
}
@@ -862,6 +888,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
return window->focusOnShow;
case GLFW_TRANSPARENT_FRAMEBUFFER:
return _glfwPlatformFramebufferTransparent(window);
case GLFW_OCCLUDED:
return _glfwPlatformWindowOccluded(window);
case GLFW_RESIZABLE:
return window->resizable;
case GLFW_DECORATED:
@@ -905,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;
@@ -990,6 +1018,12 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* wh,
refreshRate);
}
GLFWAPI bool glfwToggleFullscreen(GLFWwindow* wh, unsigned int flags) {
_GLFWwindow* window = (_GLFWwindow*) wh;
if (window) return _glfwPlatformToggleFullscreen(window, flags);
return false;
}
GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
@@ -1063,6 +1097,17 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* handle,
return cbfun;
}
GLFWAPI GLFWwindowocclusionfun glfwSetWindowOcclusionCallback(GLFWwindow* handle,
GLFWwindowocclusionfun cbfun)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.occlusion, cbfun);
return cbfun;
}
GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle,
GLFWwindowiconifyfun cbfun)
{
@@ -1096,6 +1141,17 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle
return cbfun;
}
GLFWAPI GLFWliveresizefun glfwSetLiveResizeCallback(GLFWwindow* handle,
GLFWliveresizefun cbfun)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.liveResize, cbfun);
return cbfun;
}
GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow* handle,
GLFWwindowcontentscalefun cbfun)
{
@@ -1107,44 +1163,8 @@ GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow*
return cbfun;
}
GLFWAPI void glfwPollEvents(void)
{
_GLFW_REQUIRE_INIT();
_glfwPlatformPollEvents();
}
GLFWAPI void glfwWaitEvents(void)
{
_GLFW_REQUIRE_INIT();
if (!_glfw.windowListHead)
return;
_glfwPlatformWaitEvents();
}
GLFWAPI void glfwWaitEventsTimeout(double timeout)
{
_GLFW_REQUIRE_INIT();
assert(timeout == timeout);
assert(timeout >= 0.0);
assert(timeout <= DBL_MAX);
if (timeout != timeout || timeout < 0.0 || timeout > DBL_MAX)
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid time %f", timeout);
return;
}
_glfwPlatformWaitEventsTimeout(timeout);
}
GLFWAPI void glfwPostEmptyEvent(void)
{
_GLFW_REQUIRE_INIT();
if (!_glfw.windowListHead)
return;
_glfwPlatformPostEmptyEvent();
}

361
glfw/wl_init.c vendored
View File

@@ -23,13 +23,16 @@
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#define _GNU_SOURCE
#include "internal.h"
#include "backend_utils.h"
#include <assert.h>
#include <linux/input.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -37,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)
@@ -44,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;
@@ -77,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)
@@ -101,44 +115,38 @@ 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(const char* name)
static void setCursor(GLFWCursorShape shape)
{
struct wl_buffer* buffer;
struct wl_cursor* cursor;
struct wl_cursor_image* image;
struct wl_surface* surface = _glfw.wl.cursorSurface;
cursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme,
name);
if (!cursor)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Standard cursor not found");
return;
}
cursor = _glfwLoadCursor(shape);
if (!cursor) return;
// TODO: handle animated cursors too.
image = cursor->images[0];
@@ -158,77 +166,71 @@ static void setCursor(const char* name)
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)
{
_GLFWwindow* window = _glfw.wl.pointerFocus;
const char* cursorName = NULL;
GLFWCursorShape cursorShape = GLFW_ARROW_CURSOR;
if (!window)
return;
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)
cursorName = "n-resize";
cursorShape = GLFW_VRESIZE_CURSOR;
else
cursorName = "left_ptr";
cursorShape = GLFW_ARROW_CURSOR;
break;
case leftDecoration:
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
cursorName = "nw-resize";
cursorShape = GLFW_NW_RESIZE_CURSOR;
else
cursorName = "w-resize";
cursorShape = GLFW_HRESIZE_CURSOR;
break;
case rightDecoration:
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
cursorName = "ne-resize";
cursorShape = GLFW_NE_RESIZE_CURSOR;
else
cursorName = "e-resize";
cursorShape = GLFW_HRESIZE_CURSOR;
break;
case bottomDecoration:
if (window->wl.cursorPosX < _GLFW_DECORATION_WIDTH)
cursorName = "sw-resize";
cursorShape = GLFW_SW_RESIZE_CURSOR;
else if (window->wl.cursorPosX > window->wl.width + _GLFW_DECORATION_WIDTH)
cursorName = "se-resize";
cursorShape = GLFW_SE_RESIZE_CURSOR;
else
cursorName = "s-resize";
cursorShape = GLFW_VRESIZE_CURSOR;
break;
default:
assert(0);
}
setCursor(cursorName);
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;
// Both xdg-shell and wl_shell use the same values.
uint32_t edges = WL_SHELL_SURFACE_RESIZE_NONE;
uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE;
if (!window)
return;
@@ -240,46 +242,40 @@ static void pointerHandleButton(void* data,
break;
case topDecoration:
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
edges = WL_SHELL_SURFACE_RESIZE_TOP;
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP;
else
{
if (window->wl.xdg.toplevel)
xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial);
else
wl_shell_surface_move(window->wl.shellSurface, _glfw.wl.seat, serial);
}
break;
case leftDecoration:
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
edges = WL_SHELL_SURFACE_RESIZE_TOP_LEFT;
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT;
else
edges = WL_SHELL_SURFACE_RESIZE_LEFT;
edges = XDG_TOPLEVEL_RESIZE_EDGE_LEFT;
break;
case rightDecoration:
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
edges = WL_SHELL_SURFACE_RESIZE_TOP_RIGHT;
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT;
else
edges = WL_SHELL_SURFACE_RESIZE_RIGHT;
edges = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT;
break;
case bottomDecoration:
if (window->wl.cursorPosX < _GLFW_DECORATION_WIDTH)
edges = WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT;
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
else if (window->wl.cursorPosX > window->wl.width + _GLFW_DECORATION_WIDTH)
edges = WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT;
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT;
else
edges = WL_SHELL_SURFACE_RESIZE_BOTTOM;
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM;
break;
default:
assert(0);
}
if (edges != WL_SHELL_SURFACE_RESIZE_NONE)
if (edges != XDG_TOPLEVEL_RESIZE_EDGE_NONE)
{
if (window->wl.xdg.toplevel)
xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat,
serial, edges);
else
wl_shell_surface_resize(window->wl.shellSurface, _glfw.wl.seat,
serial, edges);
xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat,
serial, edges);
}
}
else if (button == BTN_RIGHT)
@@ -312,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)
{
@@ -342,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)
@@ -367,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)
@@ -386,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;
@@ -400,22 +396,22 @@ 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, ((double)_glfw.wl.keyboardRepeatRate) / 1000.0);
changeTimerInterval(&_glfw.wl.eventLoopData, _glfw.wl.keyRepeatInfo.keyRepeatTimer, (1.0 / (double)_glfw.wl.keyboardRepeatRate));
toggleTimer(&_glfw.wl.eventLoopData, _glfw.wl.keyRepeatInfo.keyRepeatTimer, 1);
}
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)
{
@@ -424,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) {
@@ -438,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,
@@ -449,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)
@@ -470,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)
{
@@ -497,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)
{
}
@@ -508,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)
{
@@ -519,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,
@@ -542,11 +538,6 @@ static void registryHandleGlobal(void* data,
_glfw.wl.shm =
wl_registry_bind(registry, name, &wl_shm_interface, 1);
}
else if (strcmp(interface, "wl_shell") == 0)
{
_glfw.wl.shell =
wl_registry_bind(registry, name, &wl_shell_interface, 1);
}
else if (strcmp(interface, "wl_output") == 0)
{
_glfwAddOutputWayland(name, version);
@@ -561,8 +552,11 @@ static void registryHandleGlobal(void* data,
_glfw.wl.seatVersion);
wl_seat_add_listener(_glfw.wl.seat, &seatListener, NULL);
}
if (_glfw.wl.seat && _glfw.wl.dataDeviceManager && !_glfw.wl.dataDevice) {
_glfwSetupWaylandDataDevice();
if (_glfw.wl.seat) {
if (_glfw.wl.dataDeviceManager && !_glfw.wl.dataDevice) _glfwSetupWaylandDataDevice();
if (_glfw.wl.primarySelectionDeviceManager && !_glfw.wl.primarySelectionDevice) {
_glfwSetupWaylandPrimarySelectionDevice();
}
}
}
else if (strcmp(interface, "xdg_wm_base") == 0)
@@ -571,6 +565,12 @@ static void registryHandleGlobal(void* data,
wl_registry_bind(registry, name, &xdg_wm_base_interface, 1);
xdg_wm_base_add_listener(_glfw.wl.wmBase, &wmBaseListener, NULL);
}
else if (strcmp(interface, "zxdg_decoration_manager_v1") == 0)
{
_glfw.wl.decorationManager =
wl_registry_bind(registry, name,
&zxdg_decoration_manager_v1_interface, 1);
}
else if (strcmp(interface, "wp_viewporter") == 0)
{
_glfw.wl.viewporter =
@@ -607,21 +607,38 @@ static void registryHandleGlobal(void* data,
_glfwSetupWaylandDataDevice();
}
}
else if (strcmp(interface, "zwp_primary_selection_device_manager_v1") == 0 ||
strcmp(interface, "gtk_primary_selection_device_manager") == 0)
{
_glfw.wl.primarySelectionDeviceManager =
wl_registry_bind(registry, name,
&zwp_primary_selection_device_manager_v1_interface,
1);
if (_glfw.wl.seat && _glfw.wl.primarySelectionDeviceManager && !_glfw.wl.primarySelectionDevice) {
_glfwSetupWaylandPrimarySelectionDevice();
}
}
}
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;
}
@@ -635,67 +652,89 @@ 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, dispatchPendingKeyRepeats, NULL);
_glfw.wl.cursorAnimationTimer = addTimer(&_glfw.wl.eventLoopData, "wayland-cursor-animation", 0.5, 0, animateCursorImage, NULL);
_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);
_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);
@@ -706,26 +745,42 @@ int _glfwPlatformInit(void)
#ifdef __linux__
if (_glfw.hints.init.enableJoysticks) {
if (!_glfwInitJoysticksLinux())
return GLFW_FALSE;
return false;
}
#endif
_glfwInitTimerPOSIX();
if (_glfw.wl.pointer && _glfw.wl.shm)
if (!_glfw.wl.wmBase)
{
_glfw.wl.cursorTheme = wl_cursor_theme_load(NULL, 32, _glfw.wl.shm);
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Failed to find xdg-shell in your compositor");
return false;
}
if (_glfw.wl.shm)
{
const char *cursorTheme = getenv("XCURSOR_THEME"), *cursorSizeStr = getenv("XCURSOR_SIZE");
char *cursorSizeEnd;
int cursorSize = 32;
if (cursorSizeStr)
{
errno = 0;
long cursorSizeLong = strtol(cursorSizeStr, &cursorSizeEnd, 10);
if (!*cursorSizeEnd && !errno && cursorSizeLong > 0 && cursorSizeLong <= INT_MAX)
cursorSize = (int)cursorSizeLong;
}
_glfw.wl.cursorTheme = wl_cursor_theme_load(cursorTheme, cursorSize, _glfw.wl.shm);
if (!_glfw.wl.cursorTheme)
{
_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)
@@ -759,10 +814,10 @@ void _glfwPlatformTerminate(void)
wl_compositor_destroy(_glfw.wl.compositor);
if (_glfw.wl.shm)
wl_shm_destroy(_glfw.wl.shm);
if (_glfw.wl.shell)
wl_shell_destroy(_glfw.wl.shell);
if (_glfw.wl.viewporter)
wp_viewporter_destroy(_glfw.wl.viewporter);
if (_glfw.wl.decorationManager)
zxdg_decoration_manager_v1_destroy(_glfw.wl.decorationManager);
if (_glfw.wl.wmBase)
xdg_wm_base_destroy(_glfw.wl.wmBase);
if (_glfw.wl.pointer)
@@ -788,6 +843,10 @@ void _glfwPlatformTerminate(void)
wl_data_device_destroy(_glfw.wl.dataDevice);
if (_glfw.wl.dataDeviceManager)
wl_data_device_manager_destroy(_glfw.wl.dataDeviceManager);
if (_glfw.wl.primarySelectionDevice)
zwp_primary_selection_device_v1_destroy(_glfw.wl.primarySelectionDevice);
if (_glfw.wl.primarySelectionDeviceManager)
zwp_primary_selection_device_manager_v1_destroy(_glfw.wl.primarySelectionDeviceManager);
if (_glfw.wl.registry)
wl_registry_destroy(_glfw.wl.registry);
if (_glfw.wl.display)
@@ -795,15 +854,16 @@ 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.clipboardSourceString); _glfw.wl.clipboardSourceString = NULL;
free(_glfw.wl.primarySelectionString); _glfw.wl.primarySelectionString = NULL;
free(_glfw.wl.pasteString); _glfw.wl.pasteString = NULL;
}
const char* _glfwPlatformGetVersionString(void)
{
return _GLFW_VERSION_NUMBER " Wayland EGL"
return _GLFW_VERSION_NUMBER " Wayland EGL OSMesa"
#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
" clock_gettime"
#else
@@ -815,3 +875,6 @@ const char* _glfwPlatformGetVersionString(void)
#endif
;
}
#define GLFW_LOOP_BACKEND wl
#include "main_loop.h"

87
glfw/wl_monitor.c vendored
View File

@@ -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"
@@ -30,18 +32,19 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <math.h>
static void geometry(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)
static void outputHandleGeometry(void* data,
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];
@@ -55,12 +58,12 @@ static void geometry(void* data,
monitor->name = _glfw_strdup(name);
}
static void mode(void* data,
struct wl_output* output,
uint32_t flags,
int32_t width,
int32_t height,
int32_t refresh)
static void outputHandleMode(void* data,
struct wl_output* output UNUSED,
uint32_t flags,
int32_t width,
int32_t height,
int32_t refresh)
{
struct _GLFWmonitor *monitor = data;
GLFWvidmode mode;
@@ -70,7 +73,7 @@ static void mode(void* data,
mode.redBits = 8;
mode.greenBits = 8;
mode.blueBits = 8;
mode.refreshRate = refresh / 1000;
mode.refreshRate = (int) round(refresh / 1000.0);
monitor->modeCount++;
monitor->modes =
@@ -81,27 +84,30 @@ static void mode(void* data,
monitor->wl.currentMode = monitor->modeCount - 1;
}
static void done(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 scale(void* data,
struct wl_output* output,
int32_t factor)
static void outputHandleScale(void* data,
struct wl_output* output UNUSED,
int32_t factor)
{
struct _GLFWmonitor *monitor = data;
monitor->wl.scale = factor;
if (factor > 0 && factor < 24)
monitor->wl.scale = factor;
}
static const struct wl_output_listener outputListener = {
geometry,
mode,
done,
scale,
outputHandleGeometry,
outputHandleMode,
outputHandleDone,
outputHandleScale,
};
@@ -169,6 +175,20 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
*yscale = (float) monitor->wl.scale;
}
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
int* xpos, int* ypos,
int* width, int* height)
{
if (xpos)
*xpos = monitor->wl.x;
if (ypos)
*ypos = monitor->wl.y;
if (width)
*width = monitor->modes[monitor->wl.currentMode].width;
if (height)
*height = monitor->modes[monitor->wl.currentMode].height;
}
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
{
*found = monitor->modeCount;
@@ -180,18 +200,18 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
*mode = monitor->modes[monitor->wl.currentMode];
}
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor UNUSED, GLFWgammaramp* ramp UNUSED)
{
// TODO
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Gamma ramp getting not supported yet");
"Wayland: Gamma ramp access is not available");
return false;
}
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor UNUSED,
const GLFWgammaramp* ramp UNUSED)
{
// TODO
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Gamma ramp setting not supported yet");
"Wayland: Gamma ramp access is not available");
}
@@ -205,4 +225,3 @@ GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* handle)
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return monitor->wl.output;
}

61
glfw/wl_platform.h vendored
View File

@@ -56,9 +56,11 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
#include "wayland-xdg-shell-client-protocol.h"
#include "wayland-viewporter-client-protocol.h"
#include "wayland-xdg-decoration-unstable-v1-client-protocol.h"
#include "wayland-relative-pointer-unstable-v1-client-protocol.h"
#include "wayland-pointer-constraints-unstable-v1-client-protocol.h"
#include "wayland-idle-inhibit-unstable-v1-client-protocol.h"
#include "wayland-primary-selection-unstable-v1-client-protocol.h"
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
#define _glfw_dlclose(handle) dlclose(handle)
@@ -131,18 +133,18 @@ 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_shell_surface* shellSurface;
struct wl_callback* callback;
struct {
struct xdg_surface* surface;
struct xdg_toplevel* toplevel;
struct zxdg_toplevel_decoration_v1* decoration;
} xdg;
_GLFWcursor* currentCursor;
@@ -165,22 +167,37 @@ typedef struct _GLFWwindowWayland
struct zwp_idle_inhibitor_v1* idleInhibitor;
// This is a hack to prevent auto-iconification on creation.
GLFWbool justCreated;
bool fullscreened;
struct {
bool serverSide;
struct wl_buffer* buffer;
_GLFWdecorationWayland top, left, right, bottom;
int focus;
} decorations;
struct {
unsigned long long id;
void(*callback)(unsigned long long id);
struct wl_callback *current_wl_callback;
} frameCallbackData;
} _GLFWwindowWayland;
typedef enum _GLFWWaylandOfferType
{
EXPIRED,
CLIPBOARD,
DRAG_AND_DROP,
PRIMARY_SELECTION
}_GLFWWaylandOfferType ;
typedef struct _GLFWWaylandDataOffer
{
struct wl_data_offer *id;
const char *mime;
int offer_type;
_GLFWWaylandOfferType offer_type;
size_t idx;
int is_self_offer;
int has_uri_list;
@@ -189,6 +206,17 @@ typedef struct _GLFWWaylandDataOffer
struct wl_surface *surface;
} _GLFWWaylandDataOffer;
typedef struct _GLFWWaylandPrimaryOffer
{
struct zwp_primary_selection_offer_v1 *id;
const char *mime;
_GLFWWaylandOfferType offer_type;
size_t idx;
int is_self_offer;
int has_uri_list;
struct wl_surface *surface;
} _GLFWWaylandPrimaryOffer;
// Wayland-specific global data
//
typedef struct _GLFWlibraryWayland
@@ -197,12 +225,12 @@ typedef struct _GLFWlibraryWayland
struct wl_registry* registry;
struct wl_compositor* compositor;
struct wl_subcompositor* subcompositor;
struct wl_shell* shell;
struct wl_shm* shm;
struct wl_seat* seat;
struct wl_pointer* pointer;
struct wl_keyboard* keyboard;
struct xdg_wm_base* wmBase;
struct zxdg_decoration_manager_v1* decorationManager;
struct wp_viewporter* viewporter;
struct zwp_relative_pointer_manager_v1* relativePointerManager;
struct zwp_pointer_constraints_v1* pointerConstraints;
@@ -210,6 +238,9 @@ typedef struct _GLFWlibraryWayland
struct wl_data_device_manager* dataDeviceManager;
struct wl_data_device* dataDevice;
struct wl_data_source* dataSourceForClipboard;
struct zwp_primary_selection_device_manager_v1* primarySelectionDeviceManager;
struct zwp_primary_selection_device_v1* primarySelectionDevice;
struct zwp_primary_selection_source_v1* dataSourceForPrimarySelection;
int compositorVersion;
int seatVersion;
@@ -250,11 +281,13 @@ typedef struct _GLFWlibraryWayland
} egl;
EventLoopData eventLoopData;
char* pasteString;
char* clipboardString;
char* clipboardSourceString;
struct wl_data_offer* clipboardSourceOffer;
size_t dataOffersCounter;
_GLFWWaylandDataOffer dataOffers[8];
char* primarySelectionString;
size_t primarySelectionOffersCounter;
_GLFWWaylandPrimaryOffer primarySelectionOffers[8];
} _GLFWlibraryWayland;
// Wayland-specific per-monitor data
@@ -262,7 +295,7 @@ typedef struct _GLFWlibraryWayland
typedef struct _GLFWmonitorWayland
{
struct wl_output* output;
int name;
uint32_t name;
int currentMode;
int x;
@@ -284,5 +317,7 @@ typedef struct _GLFWcursorWayland
void _glfwAddOutputWayland(uint32_t name, uint32_t version);
void _glfwSetupWaylandDataDevice();
void _glfwSetupWaylandDataDevice(void);
void _glfwSetupWaylandPrimarySelectionDevice(void);
void animateCursorImage(id_type timer_id, void *data);
struct wl_cursor* _glfwLoadCursor(GLFWCursorShape);

1162
glfw/wl_window.c vendored

File diff suppressed because it is too large Load Diff

221
glfw/x11_init.c vendored
View File

@@ -2,7 +2,7 @@
// GLFW 3.3 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 =
@@ -137,6 +136,10 @@ static void detectEWMH(void)
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE");
_glfw.x11.NET_WM_WINDOW_TYPE_NORMAL =
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE_NORMAL");
_glfw.x11.NET_WORKAREA =
getSupportedAtom(supportedAtoms, atomCount, "_NET_WORKAREA");
_glfw.x11.NET_CURRENT_DESKTOP =
getSupportedAtom(supportedAtoms, atomCount, "_NET_CURRENT_DESKTOP");
_glfw.x11.NET_ACTIVE_WINDOW =
getSupportedAtom(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW");
_glfw.x11.NET_FRAME_EXTENTS =
@@ -144,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,
@@ -177,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",
@@ -195,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;
}
}
}
@@ -207,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,
@@ -254,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
{
@@ -273,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);
@@ -299,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__)
@@ -314,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;
}
}
@@ -337,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,
@@ -352,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;
}
}
}
@@ -369,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);
@@ -429,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 =
@@ -453,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
@@ -532,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;
@@ -607,6 +580,7 @@ Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot)
return cursor;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
@@ -616,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)
{
@@ -638,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);
@@ -650,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();
@@ -661,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);
}
@@ -670,11 +640,12 @@ int _glfwPlatformInit(void)
_glfwInitTimerPOSIX();
_glfwPollMonitorsX11();
return GLFW_TRUE;
return true;
}
void _glfwPlatformTerminate(void)
{
removeAllTimers(&_glfw.x11.eventLoopData);
if (_glfw.x11.helperWindowHandle)
{
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) ==
@@ -749,12 +720,12 @@ 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)
{
return _GLFW_VERSION_NUMBER " X11 GLX EGL"
return _GLFW_VERSION_NUMBER " X11 GLX EGL OSMesa"
#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
" clock_gettime"
#else
@@ -768,3 +739,5 @@ const char* _glfwPlatformGetVersionString(void)
#endif
;
}
#include "main_loop.h"

195
glfw/x11_monitor.c vendored
View File

@@ -2,7 +2,7 @@
// GLFW 3.3 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,17 +24,20 @@
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include "internal.h"
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
// 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;
}
@@ -44,7 +47,7 @@ static GLFWbool modeIsGood(const XRRModeInfo* mi)
static int calculateRefreshRate(const XRRModeInfo* mi)
{
if (mi->hTotal && mi->vTotal)
return (int) ((double) mi->dotClock / ((double) mi->hTotal * (double) mi->vTotal));
return (int) round((double) mi->dotClock / ((double) mi->hTotal * (double) mi->vTotal));
else
return 0;
}
@@ -53,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;
@@ -101,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,
@@ -121,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);
@@ -151,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);
@@ -168,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;
@@ -176,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;
@@ -200,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);
@@ -225,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))
@@ -283,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,
@@ -313,7 +303,7 @@ void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor)
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor UNUSED)
{
}
@@ -321,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)
@@ -339,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)
@@ -348,6 +336,98 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
*yscale = _glfw.x11.contentScaleY;
}
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 = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
areaX = ci->x;
areaY = ci->y;
const XRRModeInfo* mi = getModeInfo(sr, ci->mode);
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
{
areaWidth = mi->height;
areaHeight = mi->width;
}
else
{
areaWidth = mi->width;
areaHeight = mi->height;
}
XRRFreeCrtcInfo(ci);
XRRFreeScreenResources(sr);
}
else
{
areaWidth = DisplayWidth(_glfw.x11.display, _glfw.x11.screen);
areaHeight = DisplayHeight(_glfw.x11.display, _glfw.x11.screen);
}
if (_glfw.x11.NET_WORKAREA && _glfw.x11.NET_CURRENT_DESKTOP)
{
Atom* extents = NULL;
Atom* desktop = NULL;
const unsigned long extentCount =
_glfwGetWindowPropertyX11(_glfw.x11.root,
_glfw.x11.NET_WORKAREA,
XA_CARDINAL,
(unsigned char**) &extents);
if (_glfwGetWindowPropertyX11(_glfw.x11.root,
_glfw.x11.NET_CURRENT_DESKTOP,
XA_CARDINAL,
(unsigned char**) &desktop) > 0)
{
if (extentCount >= 4 && *desktop < extentCount / 4)
{
const int globalX = extents[*desktop * 4 + 0];
const int globalY = extents[*desktop * 4 + 1];
const int globalWidth = extents[*desktop * 4 + 2];
const int globalHeight = extents[*desktop * 4 + 3];
if (areaX < globalX)
{
areaWidth -= globalX - areaX;
areaX = globalX;
}
if (areaY < globalY)
{
areaHeight -= globalY - areaY;
areaY = globalY;
}
if (areaX + areaWidth > globalX + globalWidth)
areaWidth = globalX - areaX + globalWidth;
if (areaY + areaHeight > globalY + globalHeight)
areaHeight = globalY - areaY + globalHeight;
}
}
if (extents)
XFree(extents);
if (desktop)
XFree(desktop);
}
if (xpos)
*xpos = areaX;
if (ypos)
*ypos = areaY;
if (width)
*width = areaWidth;
if (height)
*height = areaHeight;
}
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
{
GLFWvidmode* result;
@@ -356,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++)
{
@@ -407,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);
@@ -433,7 +507,7 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
}
}
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{
if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken)
{
@@ -449,6 +523,7 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
memcpy(ramp->blue, gamma->blue, size * sizeof(unsigned short));
XRRFreeGamma(gamma);
return true;
}
else if (_glfw.x11.vidmode.available)
{
@@ -460,6 +535,13 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
XF86VidModeGetGammaRamp(_glfw.x11.display,
_glfw.x11.screen,
ramp->size, ramp->red, ramp->green, ramp->blue);
return true;
}
else
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Gamma ramp access not supported by server");
return false;
}
}
@@ -467,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");
@@ -492,6 +574,11 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
(unsigned short*) ramp->green,
(unsigned short*) ramp->blue);
}
else
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Gamma ramp access not supported by server");
}
}

35
glfw/x11_platform.h vendored
View File

@@ -2,7 +2,7 @@
// GLFW 3.3 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,12 +182,11 @@ typedef struct _GLFWwindowX11
Colormap colormap;
Window handle;
GLFWbool overrideRedirect;
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;
@@ -198,9 +197,6 @@ typedef struct _GLFWwindowX11
// The last position the cursor was warped to by GLFW
int warpCursorPosX, warpCursorPosY;
// The time of the last KeyPress event
Time lastKeyTime;
} _GLFWwindowX11;
// X11-specific global data
@@ -231,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;
@@ -251,6 +249,8 @@ typedef struct _GLFWlibraryX11
Atom NET_WM_FULLSCREEN_MONITORS;
Atom NET_WM_WINDOW_OPACITY;
Atom NET_WM_CM_Sx;
Atom NET_WORKAREA;
Atom NET_CURRENT_DESKTOP;
Atom NET_ACTIVE_WINDOW;
Atom NET_FRAME_EXTENTS;
Atom NET_REQUEST_FRAME_EXTENTS;
@@ -286,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;
@@ -338,7 +338,7 @@ typedef struct _GLFWlibraryX11
} xcursor;
struct {
GLFWbool available;
bool available;
void* handle;
int major;
int minor;
@@ -348,7 +348,7 @@ typedef struct _GLFWlibraryX11
} xinerama;
struct {
GLFWbool available;
bool available;
void* handle;
int eventBase;
int errorBase;
@@ -359,7 +359,7 @@ typedef struct _GLFWlibraryX11
} vidmode;
struct {
GLFWbool available;
bool available;
void* handle;
int majorOpcode;
int eventBase;
@@ -371,7 +371,7 @@ typedef struct _GLFWlibraryX11
} xi;
struct {
GLFWbool available;
bool available;
void* handle;
int major;
int minor;
@@ -408,6 +408,7 @@ typedef struct _GLFWcursorX11
} _GLFWcursorX11;
void _glfwPollMonitorsX11(void);
void _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired);
void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor);
@@ -418,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);

568
glfw/x11_window.c vendored

File diff suppressed because it is too large Load Diff

57
glfw/xkb_glfw.c vendored
View File

@@ -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__);
@@ -46,6 +47,8 @@
S(bracketleft, LEFT_BRACKET); \
S(backslash, BACKSLASH); \
S(bracketright, RIGHT_BRACKET); \
S(plus, PLUS); \
S(underscore, UNDERSCORE); \
S(grave, GRAVE_ACCENT); \
S(Escape, ESCAPE); \
S(Return, ENTER); \
@@ -99,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);
@@ -113,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) {
@@ -131,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, ...) {\
@@ -165,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); \
}
@@ -173,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
@@ -202,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*
@@ -255,9 +259,10 @@ load_compose_tables(_GLFWXKBData *xkb) {
if (!xkb->states.composeState) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to create XKB compose state");
}
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);
@@ -265,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;
@@ -289,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
@@ -323,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;
@@ -332,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) {
@@ -363,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);
}
@@ -410,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);
@@ -421,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
@@ -434,7 +439,7 @@ glfw_xkb_key_from_ime(KeyEvent *ev, GLFWbool handled_by_ime, GLFWbool failed) {
// 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",
@@ -497,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(

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