Compare commits

...

810 Commits

Author SHA1 Message Date
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
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
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
235 changed files with 48053 additions and 45225 deletions

94
.circleci/config.yml Normal file
View File

@@ -0,0 +1,94 @@
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: python3 test.py
- run: make FAIL_WARN=-W man
- run: make FAIL_WARN=-W html
- 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: ./asan-launcher 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: ./asan-launcher 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: $SW/bin/python3 setup.py build --debug --verbose
- run: $SW/bin/python3 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: python3 test.py
mac-brew:
macos:
xcode: "10.1.0"
environment:
LC_ALL: en_US.UTF-8
LANG: en_US.UTF-8
steps:
- checkout
- run: brew bundle
- run: python3 logo/make.py
- run: python3 setup.py build --debug --verbose
- run: python3 test.py
- run: python3 setup.py macos-bundle
workflows:
version: 2
all_jobs:
jobs:
- mac-bundle
- lin-sys
- lin-35
- lin-37
- 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
# 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)

1
.gitignore vendored
View File

@@ -9,6 +9,7 @@ logo/*.iconset
compile_commands.json
glad/out
asan-launcher
asan-launcher.dSYM
kitty-profile
dev
__pycache__

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

6
Brewfile Normal file
View File

@@ -0,0 +1,6 @@
brew 'pkg-config'
brew 'imagemagick'
brew 'optipng'
brew 'librsvg'
brew 'harfbuzz'
brew 'python'

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

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,5 +1,5 @@
/*
* linux-launcher.c
* asan-launcher.c
* Copyright (C) 2017 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.

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
@@ -28,7 +28,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`` and ``libpython-dev``.
if they are not already installed by your distro.
Install and run from source
@@ -107,7 +107,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,409 @@ Changelog
==============
|kitty| is a feature full, cross-platform, *fast*, GPU based terminal emulator.
To update |kitty|, :doc:`follow the instructions <binary>`.
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]
------------------------------
@@ -142,6 +545,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`)
@@ -351,7 +757,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)

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
@@ -48,25 +48,61 @@ 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>`_
How do I specify command line options for kitty on macOS?
---------------------------------------------------------------

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,14 @@ 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).
Font control
@@ -370,6 +405,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
---------------------------------

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

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.

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:

35
glfw/backend_utils.c vendored
View File

@@ -21,16 +21,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 +55,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 +65,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 +107,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 +116,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 +130,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 +197,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,11 +205,15 @@ 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;

View File

@@ -27,15 +27,18 @@
#pragma once
#include <poll.h>
#include <unistd.h>
#include <stdbool.h>
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,7 +48,9 @@ typedef struct {
double interval, trigger_at;
timer_callback_func callback;
void *callback_data;
GLFWuserdatafreefun free;
const char *name;
bool repeats;
} Timer;
@@ -61,8 +66,9 @@ typedef struct {
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);

View File

@@ -27,7 +27,6 @@
#include "internal.h"
#include <sys/param.h> // For MAXPATHLEN
// Change to our application bundle's resources directory, if present
//
static void changeToResourcesDirectory(void)
@@ -198,7 +197,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 +214,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 +224,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,7 +241,7 @@ static GLFWbool initializeTIS(void)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to load HIToolbox.framework");
return GLFW_FALSE;
return false;
}
CFStringRef* kPropertyUnicodeKeyLayoutData =
@@ -265,7 +264,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,33 +273,112 @@ static GLFWbool initializeTIS(void)
return updateUnicodeDataNS();
}
@interface GLFWLayoutListener : NSObject
@interface GLFWHelper : NSObject
@end
@implementation GLFWLayoutListener
@implementation GLFWHelper
- (void)selectedKeyboardInputSourceChanged:(NSObject* )object
{
updateUnicodeDataNS();
}
- (void)doNothing:(id)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
//////////////////////////////////////////////////////////////////////////
////// 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 +387,32 @@ int _glfwPlatformInit(void)
_glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
if (!_glfw.ns.eventSource)
return GLFW_FALSE;
return false;
CGEventSourceSetLocalEventsSuppressionInterval(_glfw.ns.eventSource, 0.0);
if (!initializeTIS())
return GLFW_FALSE;
return false;
_glfw.ns.displayLinks.lock = [NSLock new];
_glfwInitTimerNS();
_glfwInitJoysticksNS();
_glfwPollMonitorsNS();
return GLFW_TRUE;
}
return true;
}
void _glfwPlatformTerminate(void)
{
@autoreleasepool {
if (_glfw.ns.displayLinks.lock) {
_glfwClearDisplayLinks();
[_glfw.ns.displayLinks.lock release];
_glfw.ns.displayLinks.lock = nil;
}
if (_glfw.ns.inputSource)
{
CFRelease(_glfw.ns.inputSource);
@@ -345,32 +433,139 @@ 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;
}
}
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;
void _glfwDispatchTickCallback() {
if (tick_callback) {
tick_callback_requested = false;
tick_callback(tick_callback_data);
}
}
void _glfwPlatformRequestTickCallback() {
if (!tick_callback_requested) {
tick_callback_requested = true;
[NSApp performSelectorOnMainThread:@selector(tick_callback) withObject:nil waitUntilDone:NO];
}
}
void _glfwPlatformStopMainLoop(void) {
tick_callback = NULL;
[NSApp stop:nil];
_glfwPlatformPostEmptyEvent();
}
void _glfwPlatformRunMainLoop(GLFWtickcallback callback, void* data) {
tick_callback = callback;
tick_callback_data = data;
[NSApp run];
}
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

@@ -220,9 +220,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)
@@ -397,12 +406,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 +426,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 +464,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

@@ -29,6 +29,7 @@
#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include <IOKit/graphics/IOGraphicsLib.h>
#include <CoreVideo/CVBase.h>
@@ -115,16 +116,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 +133,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 +149,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,11 +213,91 @@ static void endFadeReservation(CGDisplayFadeReservationToken token)
}
}
// Finds and caches the NSScreen corresponding to the specified monitor
//
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() {
[_glfw.ns.displayLinks.lock lock];
for (size_t i = 0; i < _glfw.ns.displayLinks.count; i++) {
if (_glfw.ns.displayLinks.entries[i].displayLinkStarted) {
CVDisplayLinkStop(_glfw.ns.displayLinks.entries[i].displayLink);
_glfw.ns.displayLinks.entries[i].displayLinkStarted = false;
}
if (_glfw.ns.displayLinks.entries[i].displayLink) {
CVDisplayLinkRelease(_glfw.ns.displayLinks.entries[i].displayLink);
_glfw.ns.displayLinks.entries[i].displayLink = nil;
}
}
_glfw.ns.displayLinks.count = 0;
[_glfw.ns.displayLinks.lock unlock];
}
static CVReturn displayLinkCallback(
CVDisplayLinkRef displayLink,
const CVTimeStamp* now, const CVTimeStamp* outputTime,
CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* userInfo)
{
CGDirectDisplayID displayID = (CGDirectDisplayID)userInfo;
[_glfw.ns.displayLinks.lock lock];
bool notify = false;
for (size_t i = 0; i < _glfw.ns.displayLinks.count; i++) {
if (_glfw.ns.displayLinks.entries[i].displayID == displayID) {
if (_glfw.ns.displayLinks.entries[i].renderFrameRequested) {
notify = true;
_glfw.ns.displayLinks.entries[i].renderFrameRequested = false;
}
break;
}
}
[_glfw.ns.displayLinks.lock unlock];
if (notify) {
NSNumber *arg = [NSNumber numberWithUnsignedInt:displayID];
[NSApp performSelectorOnMainThread:@selector(render_frame_received:) withObject:arg waitUntilDone:NO];
[arg release];
}
return kCVReturnSuccess;
}
static inline void createDisplayLink(CGDirectDisplayID displayID) {
[_glfw.ns.displayLinks.lock lock];
if (_glfw.ns.displayLinks.count >= sizeof(_glfw.ns.displayLinks.entries)/sizeof(_glfw.ns.displayLinks.entries[0]) - 1) return;
for (size_t i = 0; i < _glfw.ns.displayLinks.count; i++) {
if (_glfw.ns.displayLinks.entries[i].displayID == displayID) return;
}
_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);
[_glfw.ns.displayLinks.lock unlock];
}
// Poll for changes in the set of connected monitors
//
void _glfwPollMonitorsNS(void)
@@ -228,6 +309,7 @@ void _glfwPollMonitorsNS(void)
CGGetOnlineDisplayList(0, NULL, &displayCount);
displays = calloc(displayCount, sizeof(CGDirectDisplayID));
CGGetOnlineDisplayList(displayCount, displays, &displayCount);
_glfwClearDisplayLinks();
for (i = 0; i < _glfw.monitorCount; i++)
_glfw.monitors[i]->ns.screen = nil;
@@ -269,6 +351,7 @@ void _glfwPollMonitorsNS(void)
monitor = _glfwAllocMonitor(name, size.width, size.height);
monitor->ns.displayID = displays[i];
monitor->ns.unitNumber = unitNumber;
createDisplayLink(monitor->ns.displayID);
free(name);
@@ -283,6 +366,7 @@ void _glfwPollMonitorsNS(void)
free(disconnected);
free(displays);
_glfwRestartDisplayLinks();
}
// Change the current video mode
@@ -372,35 +456,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,6 +468,24 @@ 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;
@@ -467,7 +542,7 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode)
CVDisplayLinkRelease(link);
}
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{
uint32_t i, size = CGDisplayGammaTableCapacity(monitor->ns.displayID);
CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue));
@@ -489,6 +564,7 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
}
free(values);
return true;
}
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
@@ -523,4 +599,3 @@ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* handle)
_GLFW_REQUIRE_INIT_OR_RETURN(kCGNullDirectDisplay);
return monitor->ns.displayID;
}

72
glfw/cocoa_platform.h vendored
View File

@@ -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,32 @@ 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;
bool displayLinkStarted;
bool renderFrameRequested;
} _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 +181,12 @@ typedef struct _GLFWlibraryNS
CFStringRef kPropertyUnicodeKeyLayoutData;
} tis;
struct {
_GLFWDisplayLinkNS entries[256];
size_t count;
id lock;
} displayLinks;
} _GLFWlibraryNS;
// Cocoa-specific per-monitor data
@@ -176,3 +222,9 @@ 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 _glfwCocoaPostEmptyEvent(short subtype, long data1, bool at_start);
void _glfwDispatchTickCallback(void);
void _glfwDispatchRenderFrame(CGDirectDisplayID);

File diff suppressed because it is too large Load Diff

69
glfw/context.c vendored
View File

@@ -44,7 +44,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 +52,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 +63,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 +73,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 +92,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 +103,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 +114,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 +123,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 +140,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 +152,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 +164,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 +341,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 +358,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 +369,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 +387,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
}
glfwMakeContextCurrent((GLFWwindow*) previous);
return GLFW_FALSE;
return false;
}
for (i = 0; prefixes[i]; i++)
@@ -419,7 +419,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
}
glfwMakeContextCurrent((GLFWwindow*) previous);
return GLFW_FALSE;
return false;
}
if (window->context.major < ctxconfig->major ||
@@ -449,7 +449,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
}
glfwMakeContextCurrent((GLFWwindow*) previous);
return GLFW_FALSE;
return false;
}
if (window->context.major >= 3)
@@ -465,7 +465,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
_glfwInputError(GLFW_PLATFORM_ERROR,
"Entry point retrieval is broken");
glfwMakeContextCurrent((GLFWwindow*) previous);
return GLFW_FALSE;
return false;
}
}
@@ -478,21 +478,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 +572,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 +588,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 +600,7 @@ GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions
start = terminator;
}
return GLFW_TRUE;
return true;
}
@@ -677,20 +677,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 +710,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 +727,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 +755,3 @@ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
return window->context.getProcAddress(procname);
}

120
glfw/dbus_glfw.c vendored
View File

@@ -43,12 +43,13 @@ 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
@@ -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) {
@@ -135,7 +136,7 @@ toggle_dbus_timeout(DBusTimeout *timeout, void *data) {
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);
@@ -171,12 +172,21 @@ glfw_dbus_dispatch(DBusConnection *conn) {
while(dbus_connection_dispatch(conn) == DBUS_DISPATCH_DATA_REMAINS);
}
void
glfw_dbus_session_bus_dispatch() {
if (session_bus) glfw_dbus_dispatch(session_bus);
}
void
glfw_dbus_terminate(_GLFWDBUSData *dbus) {
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);

62
glfw/egl_context.c vendored
View File

@@ -85,7 +85,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 +98,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 +170,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 +241,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)
@@ -297,7 +297,7 @@ static void destroyContextEGL(_GLFWwindow* window)
// Initialize EGL
//
GLFWbool _glfwInitEGL(void)
bool _glfwInitEGL(void)
{
int i;
const char* sonames[] =
@@ -318,7 +318,7 @@ GLFWbool _glfwInitEGL(void)
};
if (_glfw.egl.handle)
return GLFW_TRUE;
return true;
for (i = 0; sonames[i]; i++)
{
@@ -330,7 +330,7 @@ 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);
@@ -389,7 +389,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 +400,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 +410,7 @@ GLFWbool _glfwInitEGL(void)
getEGLErrorString(eglGetError()));
_glfwTerminateEGL();
return GLFW_FALSE;
return false;
}
_glfw.egl.KHR_create_context =
@@ -424,7 +424,7 @@ GLFWbool _glfwInitEGL(void)
_glfw.egl.KHR_context_flush_control =
extensionSupportedEGL("EGL_KHR_context_flush_control");
return GLFW_TRUE;
return true;
}
// Terminate EGL
@@ -453,7 +453,7 @@ void _glfwTerminateEGL(void)
// Create the OpenGL or OpenGL ES context
//
GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
bool _glfwCreateContextEGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
@@ -465,7 +465,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 +475,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 +485,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 +495,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to bind OpenGL: %s",
getEGLErrorString(eglGetError()));
return GLFW_FALSE;
return false;
}
}
@@ -536,7 +536,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 +581,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 +607,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 +695,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to load client library");
return GLFW_FALSE;
return false;
}
}
@@ -697,7 +706,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
window->context.getProcAddress = getProcAddressEGL;
window->context.destroy = destroyContextEGL;
return GLFW_TRUE;
return true;
}
#undef setAttrib
@@ -705,7 +714,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,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth)
@@ -720,7 +729,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 +743,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 +792,3 @@ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle)
return window->context.egl.surface;
}

41
glfw/egl_context.h vendored
View File

@@ -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,7 +21,7 @@ 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
@@ -32,10 +31,11 @@ def init_env(env, pkg_config, at_least_version, module='x11'):
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,6 +76,14 @@ 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
@@ -94,40 +102,6 @@ def build_wayland_protocols(env, run_tool, emphasis, newer, dest_dir):
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
class Arg:
def __init__(self, decl):
@@ -160,6 +134,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 +155,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
@@ -198,11 +174,16 @@ def generate_wrappers(glfw_header, glfw_native_header):
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))
@@ -218,10 +199,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);
@@ -251,7 +235,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))
@@ -259,53 +243,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__':

509
glfw/glfw3.h vendored
View File

@@ -133,6 +133,8 @@ extern "C" {
*/
#include <stdint.h>
#include <stdbool.h>
/* Include the chosen OpenGL or OpenGL ES headers.
*/
#if defined(GLFW_INCLUDE_ES1)
@@ -269,24 +271,6 @@ extern "C" {
#define GLFW_VERSION_REVISION 0
/*! @} */
/*! @name Boolean values
* @{ */
/*! @brief One.
*
* One. Seriously. You don't _need_ to use this symbol in your code. It's
* semantic sugar for the number 1. You can also use `1` or `true` or `_True`
* or `GL_TRUE` or whatever you want.
*/
#define GLFW_TRUE 1
/*! @brief Zero.
*
* Zero. Seriously. You don't _need_ to use this symbol in your code. It's
* semantic sugar for the number 0. You can also use `0` or `false` or
* `_False` or `GL_FALSE` or whatever you want.
*/
#define GLFW_FALSE 0
/*! @} */
/*! @name Key and button actions
* @{ */
/*! @brief The key or mouse button was released.
@@ -407,6 +391,8 @@ extern "C" {
#define GLFW_KEY_GRAVE_ACCENT 96 /* ` */
#define GLFW_KEY_WORLD_1 161 /* non-US #1 */
#define GLFW_KEY_WORLD_2 162 /* non-US #2 */
#define GLFW_KEY_PLUS 163
#define GLFW_KEY_UNDERSCORE 164
/* Function keys */
#define GLFW_KEY_ESCAPE 256
@@ -825,7 +811,11 @@ extern "C" {
* [window attribute](@ref GLFW_FOCUS_ON_SHOW_attrib).
*/
#define GLFW_FOCUS_ON_SHOW 0x0002000C
/*! @brief Occlusion window attribute
*
* Occlusion [window attribute](@ref GLFW_OCCLUDED_attrib).
*/
#define GLFW_OCCLUDED 0x0002000D
/*! @brief Framebuffer bit depth hint.
*
* Framebuffer bit depth [hint](@ref GLFW_RED_BITS).
@@ -1025,36 +1015,19 @@ extern "C" {
* @ingroup input
* @{ */
/*! @brief The regular arrow cursor shape.
*
* The regular arrow cursor.
*/
#define GLFW_ARROW_CURSOR 0x00036001
/*! @brief The text input I-beam cursor shape.
*
* The text input I-beam cursor shape.
*/
#define GLFW_IBEAM_CURSOR 0x00036002
/*! @brief The crosshair shape.
*
* The crosshair shape.
*/
#define GLFW_CROSSHAIR_CURSOR 0x00036003
/*! @brief The hand shape.
*
* The hand shape.
*/
#define GLFW_HAND_CURSOR 0x00036004
/*! @brief The horizontal resize arrow shape.
*
* The horizontal resize arrow shape.
*/
#define GLFW_HRESIZE_CURSOR 0x00036005
/*! @brief The vertical resize arrow shape.
*
* The vertical resize arrow shape.
*/
#define GLFW_VRESIZE_CURSOR 0x00036006
typedef enum {
GLFW_ARROW_CURSOR,
GLFW_IBEAM_CURSOR,
GLFW_CROSSHAIR_CURSOR,
GLFW_HAND_CURSOR,
GLFW_HRESIZE_CURSOR,
GLFW_VRESIZE_CURSOR,
GLFW_NW_RESIZE_CURSOR,
GLFW_NE_RESIZE_CURSOR,
GLFW_SW_RESIZE_CURSOR,
GLFW_SE_RESIZE_CURSOR,
GLFW_INVALID_CURSOR
} GLFWCursorShape;
/*! @} */
#define GLFW_CONNECTED 0x00040001
@@ -1163,9 +1136,9 @@ typedef void (* GLFWerrorfun)(int,const char*);
*
* @param[in] window The window that was moved.
* @param[in] xpos The new x-coordinate, in screen coordinates, of the
* upper-left corner of the client area of the window.
* upper-left corner of the content area of the window.
* @param[in] ypos The new y-coordinate, in screen coordinates, of the
* upper-left corner of the client area of the window.
* upper-left corner of the content area of the window.
*
* @sa @ref window_pos
* @sa @ref glfwSetWindowPosCallback
@@ -1231,8 +1204,8 @@ typedef void (* GLFWwindowrefreshfun)(GLFWwindow*);
* This is the function signature for window focus callback functions.
*
* @param[in] window The window that gained or lost input focus.
* @param[in] focused `GLFW_TRUE` if the window was given input focus, or
* `GLFW_FALSE` if it lost it.
* @param[in] focused `true` if the window was given input focus, or
* `false` if it lost it.
*
* @sa @ref window_focus
* @sa @ref glfwSetWindowFocusCallback
@@ -1243,14 +1216,32 @@ typedef void (* GLFWwindowrefreshfun)(GLFWwindow*);
*/
typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int);
/*! @brief The function signature for window occlusion callbacks.
*
* This is the function signature for window occlusion callback functions.
*
* @param[in] window The window whose occlusion state changed.
* @param[in] occluded `true` if the window was occluded, or `false`
* if the window is no longer occluded.
*
* @sa @ref window_occlusion
* @sa @ref glfwSetWindowOcclusionCallback
*
* @since Added in version 3.3.
*
* @ingroup window
*/
typedef void (* GLFWwindowocclusionfun)(GLFWwindow*, bool);
/*! @brief The function signature for window iconify/restore callbacks.
*
* This is the function signature for window iconify/restore callback
* functions.
*
* @param[in] window The window that was iconified or restored.
* @param[in] iconified `GLFW_TRUE` if the window was iconified, or
* `GLFW_FALSE` if it was restored.
* @param[in] iconified `true` if the window was iconified, or
* `false` if it was restored.
*
* @sa @ref window_iconify
* @sa @ref glfwSetWindowIconifyCallback
@@ -1267,8 +1258,8 @@ typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int);
* functions.
*
* @param[in] window The window that was maximized or restored.
* @param[in] iconified `GLFW_TRUE` if the window was maximized, or
* `GLFW_FALSE` if it was restored.
* @param[in] iconified `true` if the window was maximized, or
* `false` if it was restored.
*
* @sa @ref window_maximize
* @sa glfwSetWindowMaximizeCallback
@@ -1342,9 +1333,9 @@ typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int);
*
* @param[in] window The window that received the event.
* @param[in] xpos The new cursor x-coordinate, relative to the left edge of
* the client area.
* the content area.
* @param[in] ypos The new cursor y-coordinate, relative to the top edge of the
* client area.
* content area.
*
* @sa @ref cursor_pos
* @sa @ref glfwSetCursorPosCallback
@@ -1360,8 +1351,8 @@ typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double);
* This is the function signature for cursor enter/leave callback functions.
*
* @param[in] window The window that received the event.
* @param[in] entered `GLFW_TRUE` if the cursor entered the window's client
* area, or `GLFW_FALSE` if it left it.
* @param[in] entered `true` if the cursor entered the window's client
* area, or `false` if it left it.
*
* @sa @ref cursor_enter
* @sa @ref glfwSetCursorEnterCallback
@@ -1379,7 +1370,13 @@ typedef void (* GLFWcursorenterfun)(GLFWwindow*,int);
* @param[in] window The window that received the event.
* @param[in] xoffset The scroll offset along the x-axis.
* @param[in] yoffset The scroll offset along the y-axis.
* @param[in] flags A bit-mask providing extra data about the event. flags & 1 will be true if and only if the offset values are "high-precision". Typically pixel values. Otherwise the offset values are number of lines.
* @param[in] flags A bit-mask providing extra data about the event.
* flags & 1 will be true if and only if the offset values are "high-precision".
* Typically pixel values. Otherwise the offset values are number of lines.
* (flags >> 1) & 7 will have value 1 for the start of momentum scrolling,
* value 2 for stationary momentum scrolling, value 3 for momentum scrolling
* in progress, value 4 for momentum scrolling ended, value 5 for momentum
* scrolling cancelled and value 6 if scrolling may begin soon.
*
* @sa @ref scrolling
* @sa @ref glfwSetScrollCallback
@@ -1443,6 +1440,8 @@ typedef void (* GLFWkeyboardfun)(GLFWwindow*, int, int, int, int, const char*, i
*/
typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**);
typedef void (* GLFWliveresizefun)(GLFWwindow*, bool);
/*! @brief The function signature for monitor configuration callbacks.
*
* This is the function signature for monitor configuration callback functions.
@@ -1478,6 +1477,9 @@ typedef void (* GLFWmonitorfun)(GLFWmonitor*,int);
*/
typedef void (* GLFWjoystickfun)(int,int);
typedef void (* GLFWuserdatafun)(unsigned long long, void*);
typedef void (* GLFWtickcallback)(void*);
/*! @brief Video mode type.
*
* This describes a single video mode.
@@ -1602,9 +1604,9 @@ typedef struct GLFWgamepadstate
* succeeds, you should call @ref glfwTerminate before the application exits.
*
* Additional calls to this function after successful initialization but before
* termination will return `GLFW_TRUE` immediately.
* termination will return `true` immediately.
*
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
* @return `true` if successful, or `false` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_PLATFORM_ERROR.
@@ -1624,6 +1626,12 @@ typedef struct GLFWgamepadstate
* @ingroup init
*/
GLFWAPI int glfwInit(void);
GLFWAPI void glfwRunMainLoop(GLFWtickcallback callback, void *callback_data);
GLFWAPI void glfwStopMainLoop(void);
GLFWAPI void glfwRequestTickCallback(void);
GLFWAPI unsigned long long glfwAddTimer(double interval, bool repeats, GLFWuserdatafun callback, void * callback_data, GLFWuserdatafun free_callback);
GLFWAPI void glfwUpdateTimer(unsigned long long timer_id, double interval, bool enabled);
GLFWAPI void glfwRemoveTimer(unsigned long long);
/*! @brief Terminates the GLFW library.
*
@@ -1895,6 +1903,35 @@ GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void);
*/
GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos);
/*! @brief Returns the work area of the monitor.
*
* This function returns the position, in screen coordinates, of the upper-left
* corner of the specified monitor alongwith the work area size in screen co-ordinates.
* The work area is defined as the area of the monitor not occluded by the operating
* system chrome (task bar, global menubar, etc.).
*
* Any or all of the position and size arguments may be `NULL`. If an error occurs, all
* non-`NULL` position and size arguments will be set to zero.
*
* @param[in] monitor The monitor to query.
* @param[out] xpos Where to store the monitor x-coordinate, or `NULL`.
* @param[out] ypos Where to store the monitor y-coordinate, or `NULL`.
* @param[out] width Where to store the monitor width, or `NULL`.
* @param[out] height Where to store the monitor height, or `NULL`.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref monitor_workarea
*
* @since Added in version 3.3.
*
* @ingroup monitor
*/
GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height);
/*! @brief Returns the physical size of the monitor.
*
* This function returns the size, in millimetres, of the display area of the
@@ -2121,9 +2158,9 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);
/*! @brief Generates a gamma ramp and sets it for the specified monitor.
*
* This function generates a 256-element gamma ramp from the specified exponent
* and then calls @ref glfwSetGammaRamp with it. The value must be a finite
* number greater than zero.
* This function generates an appropriately sized gamma ramp from the
* specified exponent and then calls @ref glfwSetGammaRamp with it. The value
* must be a finite number greater than zero.
*
* The software controlled gamma ramp is applied _in addition_ to the hardware
* gamma correction, which today is usually an approximation of sRGB gamma.
@@ -2202,8 +2239,8 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @remark Gamma ramp sizes other than 256 are not supported by all platforms
* or graphics hardware.
* @remark The size of the specified gamma ramp should match the size of the
* current ramp for that monitor.
*
* @remark @win32 The gamma ramp size must be 256.
*
@@ -2417,7 +2454,7 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
* @remark @macos On OS X 10.10 and later the window frame will not be rendered
* at full resolution on Retina displays unless the
* [GLFW_COCOA_RETINA_FRAMEBUFFER](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint)
* hint is `GLFW_TRUE` and the `NSHighResolutionCapable` key is enabled in the
* hint is `true` and the `NSHighResolutionCapable` key is enabled in the
* application bundle's `Info.plist`. For more information, see
* [High Resolution Guidelines for OS X](https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html)
* in the Mac Developer Library. The GLFW test and example programs use
@@ -2443,11 +2480,13 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
* GLFW_X11_CLASS_NAME and @ref GLFW_X11_INSTANCE_NAME window hints to override
* this.
*
* @remark @wayland The window frame is currently very simple, only allowing
* window resize or move. A compositor can still emit close, maximize or
* fullscreen events, using for example a keybind mechanism. Additionally,
* the wp_viewporter protocol is required for this feature, otherwise the
* window will not be decorated.
* @remark @wayland Compositors should implement the xdg-decoration protocol
* for GLFW to decorate the window properly. If this protocol isn't
* supported, or if the compositor prefers client-side decorations, a very
* simple fallback frame will be drawn using the wp_viewporter protocol. A
* compositor can still emit close, maximize or fullscreen events, using for
* instance a keybind mechanism. If neither of these protocols is supported,
* the window won't be decorated.
*
* @remark @wayland A full screen window will not attempt to change the mode,
* no matter what the requested size or refresh rate.
@@ -2465,6 +2504,7 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
* @ingroup window
*/
GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share);
GLFWAPI bool glfwToggleFullscreen(GLFWwindow *window, unsigned int flags);
/*! @brief Destroys the specified window and its context.
*
@@ -2609,19 +2649,19 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
*/
GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images);
/*! @brief Retrieves the position of the client area of the specified window.
/*! @brief Retrieves the position of the content area of the specified window.
*
* This function retrieves the position, in screen coordinates, of the
* upper-left corner of the client area of the specified window.
* upper-left corner of the content area of the specified window.
*
* Any or all of the position arguments may be `NULL`. If an error occurs, all
* non-`NULL` position arguments will be set to zero.
*
* @param[in] window The window to query.
* @param[out] xpos Where to store the x-coordinate of the upper-left corner of
* the client area, or `NULL`.
* the content area, or `NULL`.
* @param[out] ypos Where to store the y-coordinate of the upper-left corner of
* the client area, or `NULL`.
* the content area, or `NULL`.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
@@ -2641,10 +2681,10 @@ GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* i
*/
GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
/*! @brief Sets the position of the client area of the specified window.
/*! @brief Sets the position of the content area of the specified window.
*
* This function sets the position, in screen coordinates, of the upper-left
* corner of the client area of the specified windowed mode window. If the
* corner of the content area of the specified windowed mode window. If the
* window is a full screen window, this function does nothing.
*
* __Do not use this function__ to move an already visible window unless you
@@ -2654,8 +2694,8 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
* cannot and should not override these limits.
*
* @param[in] window The window to query.
* @param[in] xpos The x-coordinate of the upper-left corner of the client area.
* @param[in] ypos The y-coordinate of the upper-left corner of the client area.
* @param[in] xpos The x-coordinate of the upper-left corner of the content area.
* @param[in] ypos The y-coordinate of the upper-left corner of the content area.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
@@ -2676,9 +2716,9 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
*/
GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);
/*! @brief Retrieves the size of the client area of the specified window.
/*! @brief Retrieves the size of the content area of the specified window.
*
* This function retrieves the size, in screen coordinates, of the client area
* This function retrieves the size, in screen coordinates, of the content area
* of the specified window. If you wish to retrieve the size of the
* framebuffer of the window in pixels, see @ref glfwGetFramebufferSize.
*
@@ -2687,9 +2727,9 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);
*
* @param[in] window The window whose size to retrieve.
* @param[out] width Where to store the width, in screen coordinates, of the
* client area, or `NULL`.
* content area, or `NULL`.
* @param[out] height Where to store the height, in screen coordinates, of the
* client area, or `NULL`.
* content area, or `NULL`.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
@@ -2708,7 +2748,7 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);
/*! @brief Sets the size limits of the specified window.
*
* This function sets the size limits of the client area of the specified
* This function sets the size limits of the content area of the specified
* window. If the window is full screen, the size limits only take effect
* once it is made windowed. If the window is not resizable, this function
* does nothing.
@@ -2723,11 +2763,11 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);
* @param[in] minwidth The minimum width, in screen coordinates, of the client
* area, or `GLFW_DONT_CARE`.
* @param[in] minheight The minimum height, in screen coordinates, of the
* client area, or `GLFW_DONT_CARE`.
* content area, or `GLFW_DONT_CARE`.
* @param[in] maxwidth The maximum width, in screen coordinates, of the client
* area, or `GLFW_DONT_CARE`.
* @param[in] maxheight The maximum height, in screen coordinates, of the
* client area, or `GLFW_DONT_CARE`.
* content area, or `GLFW_DONT_CARE`.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
@@ -2751,7 +2791,7 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minhe
/*! @brief Sets the aspect ratio of the specified window.
*
* This function sets the required aspect ratio of the client area of the
* This function sets the required aspect ratio of the content area of the
* specified window. If the window is full screen, the aspect ratio only takes
* effect once it is made windowed. If the window is not resizable, this
* function does nothing.
@@ -2792,9 +2832,9 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minhe
*/
GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom);
/*! @brief Sets the size of the client area of the specified window.
/*! @brief Sets the size of the content area of the specified window.
*
* This function sets the size, in screen coordinates, of the client area of
* This function sets the size, in screen coordinates, of the content area of
* the specified window.
*
* For full screen windows, this function updates the resolution of its desired
@@ -2810,9 +2850,9 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom);
*
* @param[in] window The window to resize.
* @param[in] width The desired width, in screen coordinates, of the window
* client area.
* content area.
* @param[in] height The desired height, in screen coordinates, of the window
* client area.
* content area.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
@@ -2930,6 +2970,32 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int
*/
GLFWAPI void glfwGetWindowContentScale(GLFWwindow* window, float* xscale, float* yscale);
/*! @brief Returns the double click time interval.
*
* This function returns the maximum time between clicks to count as a
* double click.
*
* The double click interval is a positive finite number greater than zero,
* where zero means that no click is ever recognized as a double click. If the
* system does not support a double click interval, this function always returns one half.
*
* @return The double click interval.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref double_click
* @sa @ref click_interval
* @sa @ref double_click_interval
*
* @since Added in version 3.3.
*
* @ingroup window
*/
GLFWAPI double glfwGetDoubleClickInterval(GLFWwindow* window);
/*! @brief Returns the opacity of the whole window.
*
* This function returns the opacity of the window, including any decorations.
@@ -3000,9 +3066,8 @@ GLFWAPI void glfwSetWindowOpacity(GLFWwindow* window, float opacity);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @remark @wayland There is no concept of iconification in wl_shell, this
* function will emit @ref GLFW_PLATFORM_ERROR when using this deprecated
* protocol.
* @remark @wayland Once a window is iconified it cannot be restored
* except by the compositor, this is a design decision of xdg-shell.
*
* @thread_safety This function must only be called from the main thread.
*
@@ -3190,7 +3255,7 @@ GLFWAPI void glfwRequestWindowAttention(GLFWwindow* window);
* supported. Currently (macOS, Windows, X11 and Wayland).
*
* @param[in] window The window with which the bell is associated.
* @return GLFW_TRUE if the bell succeeded otherwise GLFW_FALSE
* @return true if the bell succeeded otherwise false
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
@@ -3239,7 +3304,7 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);
* The window position is ignored when setting a monitor.
*
* When the monitor is `NULL`, the position, width and height are used to
* place the window client area. The refresh rate is ignored when no monitor
* place the window content area. The refresh rate is ignored when no monitor
* is specified.
*
* If you only wish to update the resolution of a full screen window or the
@@ -3252,10 +3317,10 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);
* @param[in] window The window whose monitor, size or video mode to set.
* @param[in] monitor The desired monitor, or `NULL` to set windowed mode.
* @param[in] xpos The desired x-coordinate of the upper-left corner of the
* client area.
* content area.
* @param[in] ypos The desired y-coordinate of the upper-left corner of the
* client area.
* @param[in] width The desired with, in screen coordinates, of the client area
* content area.
* @param[in] width The desired with, in screen coordinates, of the content area
* or video mode.
* @param[in] height The desired height, in screen coordinates, of the client
* area or video mode.
@@ -3340,7 +3405,7 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);
*
* @param[in] window The window to set the attribute for.
* @param[in] attrib A supported window attribute.
* @param[in] value `GLFW_TRUE` or `GLFW_FALSE`.
* @param[in] value `true` or `false`.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
@@ -3407,7 +3472,7 @@ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window);
*
* This function sets the position callback of the specified window, which is
* called when the window is moved. The callback is provided with the
* position, in screen coordinates, of the upper-left corner of the client area
* position, in screen coordinates, of the upper-left corner of the content area
* of the window.
*
* @param[in] window The window whose callback to set.
@@ -3435,7 +3500,7 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindow
*
* This function sets the size callback of the specified window, which is
* called when the window is resized. The callback is provided with the size,
* in screen coordinates, of the client area of the window.
* in screen coordinates, of the content area of the window.
*
* @param[in] window The window whose callback to set.
* @param[in] cbfun The new callback, or `NULL` to remove the currently set
@@ -3492,7 +3557,7 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwi
/*! @brief Sets the refresh callback for the specified window.
*
* This function sets the refresh callback of the specified window, which is
* called when the client area of the window needs to be redrawn, for example
* called when the content area of the window needs to be redrawn, for example
* if the window has been exposed after having been covered by another window.
*
* On compositing window systems such as Aero, Compiz, Aqua or Wayland, where
@@ -3546,6 +3611,31 @@ GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GL
*/
GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwindowfocusfun cbfun);
/*! @brief Sets the occlusion callback for the specified window.
*
* This function sets the occlusion callback of the specified window, which is
* called when the window becomes (fully) occluded by other windows or when (a
* part of) the window becomes visible again because an overlapping window is
* moved away.
*
* @param[in] window The window whose callback to set.
* @param[in] cbfun The new callback, or `NULL` to remove the currently set
* callback.
* @return The previously set callback, or `NULL` if no callback was set or the
* library had not been [initialized](@ref intro_init).
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_occlusion
*
* @since Added in version 3.3.
*
* @ingroup window
*/
GLFWAPI GLFWwindowocclusionfun glfwSetWindowOcclusionCallback(GLFWwindow* window, GLFWwindowocclusionfun cbfun);
/*! @brief Sets the iconify callback for the specified window.
*
* This function sets the iconification callback of the specified window, which
@@ -3559,9 +3649,6 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwi
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @remark @wayland The wl_shell protocol has no concept of iconification,
* this callback will never be called when using this deprecated protocol.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_iconify
@@ -3642,152 +3729,11 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window
*/
GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow* window, GLFWwindowcontentscalefun cbfun);
/*! @brief Processes all pending events.
*
* This function processes only those events that are already in the event
* queue and then returns immediately. Processing events will cause the window
* and input callbacks associated with those events to be called.
*
* On some platforms, a window move, resize or menu operation will cause event
* processing to block. This is due to how event processing is designed on
* those platforms. You can use the
* [window refresh callback](@ref window_refresh) to redraw the contents of
* your window when necessary during such operations.
*
* Do not assume that callbacks you set will _only_ be called in response to
* event processing functions like this one. While it is necessary to poll for
* events, window systems that require GLFW to register callbacks of its own
* can pass events to GLFW in response to many window system function calls.
* GLFW will pass those events on to the application callbacks before
* returning.
*
* Event processing is not required for joystick input to work.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @reentrancy This function must not be called from a callback.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref events
* @sa @ref glfwWaitEvents
* @sa @ref glfwWaitEventsTimeout
*
* @since Added in version 1.0.
*
* @ingroup window
*/
GLFWAPI void glfwPollEvents(void);
/*! @brief Waits until events are queued and processes them.
*
* This function puts the calling thread to sleep until at least one event is
* available in the event queue. Once one or more events are available,
* it behaves exactly like @ref glfwPollEvents, i.e. the events in the queue
* are processed and the function then returns immediately. Processing events
* will cause the window and input callbacks associated with those events to be
* called.
*
* Since not all events are associated with callbacks, this function may return
* without a callback having been called even if you are monitoring all
* callbacks.
*
* On some platforms, a window move, resize or menu operation will cause event
* processing to block. This is due to how event processing is designed on
* those platforms. You can use the
* [window refresh callback](@ref window_refresh) to redraw the contents of
* your window when necessary during such operations.
*
* Do not assume that callbacks you set will _only_ be called in response to
* event processing functions like this one. While it is necessary to poll for
* events, window systems that require GLFW to register callbacks of its own
* can pass events to GLFW in response to many window system function calls.
* GLFW will pass those events on to the application callbacks before
* returning.
*
* If no windows exist, this function returns immediately. For synchronization
* of threads in applications that do not create windows, use your threading
* library of choice.
*
* Event processing is not required for joystick input to work.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @reentrancy This function must not be called from a callback.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref events
* @sa @ref glfwPollEvents
* @sa @ref glfwWaitEventsTimeout
*
* @since Added in version 2.5.
*
* @ingroup window
*/
GLFWAPI void glfwWaitEvents(void);
/*! @brief Waits with timeout until events are queued and processes them.
*
* This function puts the calling thread to sleep until at least one event is
* available in the event queue, or until the specified timeout is reached. If
* one or more events are available, it behaves exactly like @ref
* glfwPollEvents, i.e. the events in the queue are processed and the function
* then returns immediately. Processing events will cause the window and input
* callbacks associated with those events to be called.
*
* The timeout value must be a positive finite number.
*
* Since not all events are associated with callbacks, this function may return
* without a callback having been called even if you are monitoring all
* callbacks.
*
* On some platforms, a window move, resize or menu operation will cause event
* processing to block. This is due to how event processing is designed on
* those platforms. You can use the
* [window refresh callback](@ref window_refresh) to redraw the contents of
* your window when necessary during such operations.
*
* Do not assume that callbacks you set will _only_ be called in response to
* event processing functions like this one. While it is necessary to poll for
* events, window systems that require GLFW to register callbacks of its own
* can pass events to GLFW in response to many window system function calls.
* GLFW will pass those events on to the application callbacks before
* returning.
*
* If no windows exist, this function returns immediately. For synchronization
* of threads in applications that do not create windows, use your threading
* library of choice.
*
* Event processing is not required for joystick input to work.
*
* @param[in] timeout The maximum amount of time, in seconds, to wait.
*
* @reentrancy This function must not be called from a callback.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref events
* @sa @ref glfwPollEvents
* @sa @ref glfwWaitEvents
*
* @since Added in version 3.2.
*
* @ingroup window
*/
GLFWAPI void glfwWaitEventsTimeout(double timeout);
/*! @brief Posts an empty event to the event queue.
*
* This function posts an empty event from the current thread to the event
* queue, causing @ref glfwWaitEvents or @ref glfwWaitEventsTimeout to return.
*
* If no windows exist, this function returns immediately. For synchronization
* of threads in applications that do not create windows, use your threading
* library of choice.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
@@ -3841,23 +3787,23 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
* and unlimited cursor movement. This is useful for implementing for
* example 3D camera controls.
*
* If the mode is `GLFW_STICKY_KEYS`, the value must be either `GLFW_TRUE` to
* enable sticky keys, or `GLFW_FALSE` to disable it. If sticky keys are
* If the mode is `GLFW_STICKY_KEYS`, the value must be either `true` to
* enable sticky keys, or `false` to disable it. If sticky keys are
* enabled, a key press will ensure that @ref glfwGetKey returns `GLFW_PRESS`
* the next time it is called even if the key had been released before the
* call. This is useful when you are only interested in whether keys have been
* pressed but not when or in which order.
*
* If the mode is `GLFW_STICKY_MOUSE_BUTTONS`, the value must be either
* `GLFW_TRUE` to enable sticky mouse buttons, or `GLFW_FALSE` to disable it.
* `true` to enable sticky mouse buttons, or `false` to disable it.
* If sticky mouse buttons are enabled, a mouse button press will ensure that
* @ref glfwGetMouseButton returns `GLFW_PRESS` the next time it is called even
* if the mouse button had been released before the call. This is useful when
* you are only interested in whether mouse buttons have been pressed but not
* when or in which order.
*
* If the mode is `GLFW_LOCK_KEY_MODS`, the value must be either `GLFW_TRUE` to
* enable lock key modifier bits, or `GLFW_FALSE` to disable them. If enabled,
* If the mode is `GLFW_LOCK_KEY_MODS`, the value must be either `true` to
* enable lock key modifier bits, or `false` to disable them. If enabled,
* callbacks that receive modifier bits will also have the @ref
* GLFW_MOD_CAPS_LOCK bit set when the event was generated with Caps Lock on,
* and the @ref GLFW_MOD_NUM_LOCK bit when Num Lock was on.
@@ -4039,11 +3985,11 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
*/
GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button);
/*! @brief Retrieves the position of the cursor relative to the client area of
/*! @brief Retrieves the position of the cursor relative to the content area of
* the window.
*
* This function returns the position of the cursor, in screen coordinates,
* relative to the upper-left corner of the client area of the specified
* relative to the upper-left corner of the content area of the specified
* window.
*
* If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor
@@ -4059,9 +4005,9 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button);
*
* @param[in] window The desired window.
* @param[out] xpos Where to store the cursor x-coordinate, relative to the
* left edge of the client area, or `NULL`.
* left edge of the content area, or `NULL`.
* @param[out] ypos Where to store the cursor y-coordinate, relative to the to
* top edge of the client area, or `NULL`.
* top edge of the content area, or `NULL`.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
@@ -4077,11 +4023,11 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button);
*/
GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
/*! @brief Sets the position of the cursor, relative to the client area of the
/*! @brief Sets the position of the cursor, relative to the content area of the
* window.
*
* This function sets the position, in screen coordinates, of the cursor
* relative to the upper-left corner of the client area of the specified
* relative to the upper-left corner of the content area of the specified
* window. The window must have input focus. If the window does not have
* input focus when this function is called, it fails silently.
*
@@ -4096,9 +4042,9 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
*
* @param[in] window The desired window.
* @param[in] xpos The desired x-coordinate, relative to the left edge of the
* client area.
* content area.
* @param[in] ypos The desired y-coordinate, relative to the top edge of the
* client area.
* content area.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
@@ -4177,7 +4123,7 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot,
*
* @ingroup input
*/
GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape);
GLFWAPI GLFWcursor* glfwCreateStandardCursor(GLFWCursorShape shape);
/*! @brief Destroys a cursor.
*
@@ -4209,7 +4155,7 @@ GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor);
/*! @brief Sets the cursor for the window.
*
* This function sets the cursor image to be used when the cursor is over the
* client area of the specified window. The set cursor will only be visible
* content area of the specified window. The set cursor will only be visible
* when the [cursor mode](@ref cursor_mode) of the window is
* `GLFW_CURSOR_NORMAL`.
*
@@ -4291,7 +4237,7 @@ GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmo
* This function sets the cursor position callback of the specified window,
* which is called when the cursor is moved. The callback is provided with the
* position, in screen coordinates, relative to the upper-left corner of the
* client area of the window.
* content area of the window.
*
* @param[in] window The window whose callback to set.
* @param[in] cbfun The new callback, or `NULL` to remove the currently set
@@ -4314,7 +4260,7 @@ GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursor
/*! @brief Sets the cursor enter/exit callback.
*
* This function sets the cursor boundary crossing callback of the specified
* window, which is called when the cursor enters or leaves the client area of
* window, which is called when the cursor enters or leaves the content area of
* the window.
*
* @param[in] window The window whose callback to set.
@@ -4391,6 +4337,7 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cb
* @ingroup input
*/
GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun);
GLFWAPI GLFWliveresizefun glfwSetLiveResizeCallback(GLFWwindow* window, GLFWliveresizefun cbfun);
/*! @brief Returns whether the specified joystick is present.
*
@@ -4401,7 +4348,7 @@ GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun);
* work.
*
* @param[in] jid The [joystick](@ref joysticks) to query.
* @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise.
* @return `true` if the joystick is present, or `false` otherwise.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
@@ -4675,13 +4622,13 @@ GLFWAPI void* glfwGetJoystickUserPointer(int jid);
* a gamepad mapping.
*
* If the specified joystick is present but does not have a gamepad mapping
* this function will return `GLFW_FALSE` but will not generate an error. Call
* this function will return `false` but will not generate an error. Call
* @ref glfwJoystickPresent to check if a joystick is present regardless of
* whether it has a mapping.
*
* @param[in] jid The [joystick](@ref joysticks) to query.
* @return `GLFW_TRUE` if a joystick is both present and has a gamepad mapping,
* or `GLFW_FALSE` otherwise.
* @return `true` if a joystick is both present and has a gamepad mapping,
* or `false` otherwise.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_INVALID_ENUM.
@@ -4742,7 +4689,7 @@ GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun);
* default.
*
* @param[in] string The string containing the gamepad mappings.
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
* @return `true` if successful, or `false` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
@@ -4796,7 +4743,7 @@ GLFWAPI const char* glfwGetGamepadName(int jid);
* an Xbox-like gamepad.
*
* If the specified joystick is not present or does not have a gamepad mapping
* this function will return `GLFW_FALSE` but will not generate an error. Call
* this function will return `false` but will not generate an error. Call
* @ref glfwJoystickPresent to check whether it is present regardless of
* whether it has a mapping.
*
@@ -4809,7 +4756,7 @@ GLFWAPI const char* glfwGetGamepadName(int jid);
*
* @param[in] jid The [joystick](@ref joysticks) to query.
* @param[out] state The gamepad input state of the joystick.
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if no joystick is
* @return `true` if successful, or `false` if no joystick is
* connected, it has no gamepad mapping or an [error](@ref error_handling)
* occurred.
*
@@ -5142,7 +5089,7 @@ GLFWAPI void glfwSwapInterval(int interval);
* and `vkEnumerateDeviceExtensionProperties` instead.
*
* @param[in] extension The ASCII encoded name of the extension.
* @return `GLFW_TRUE` if the extension is available, or `GLFW_FALSE`
* @return `true` if the extension is available, or `false`
* otherwise.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
@@ -5215,7 +5162,7 @@ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname);
* and @ref glfwGetPhysicalDevicePresentationSupport to check whether a queue
* family of a physical device supports image presentation.
*
* @return `GLFW_TRUE` if Vulkan is minimally available, or `GLFW_FALSE`
* @return `true` if Vulkan is minimally available, or `false`
* otherwise.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
@@ -5327,7 +5274,7 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* p
*
* If Vulkan or the required window surface creation instance extensions are
* not available on the machine, or if the specified instance was not created
* with the required extensions, this function returns `GLFW_FALSE` and
* with the required extensions, this function returns `false` and
* generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported
* to check whether Vulkan is at least minimally available and @ref
* glfwGetRequiredInstanceExtensions to check what instance extensions are
@@ -5336,13 +5283,13 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* p
* @param[in] instance The instance that the physical device belongs to.
* @param[in] device The physical device that the queue family belongs to.
* @param[in] queuefamily The index of the queue family to query.
* @return `GLFW_TRUE` if the queue family supports presentation, or
* `GLFW_FALSE` otherwise.
* @return `true` if the queue family supports presentation, or
* `false` otherwise.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
*
* @remark @macos This function currently always returns `GLFW_TRUE`, as the
* @remark @macos This function currently always returns `true`, as the
* `VK_MVK_macos_surface` extension does not provide
* a `vkGetPhysicalDevice*PresentationSupport` type function.
*

87
glfw/glx_context.c vendored
View File

@@ -47,7 +47,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 +55,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 +116,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);
@@ -210,10 +210,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)
@@ -226,8 +226,6 @@ static GLFWglproc getProcAddressGLX(const char* procname)
return _glfw_dlsym(_glfw.glx.handle, procname);
}
// Destroy the OpenGL context
//
static void destroyContextGLX(_GLFWwindow* window)
{
if (window->context.glx.window)
@@ -250,7 +248,7 @@ static void destroyContextGLX(_GLFWwindow* window)
// Initialize GLX
//
GLFWbool _glfwInitGLX(void)
bool _glfwInitGLX(void)
{
int i;
const char* sonames[] =
@@ -267,7 +265,7 @@ GLFWbool _glfwInitGLX(void)
};
if (_glfw.glx.handle)
return GLFW_TRUE;
return true;
for (i = 0; sonames[i]; i++)
{
@@ -279,7 +277,7 @@ GLFWbool _glfwInitGLX(void)
if (!_glfw.glx.handle)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: Failed to load GLX");
return GLFW_FALSE;
return false;
}
_glfw.glx.GetFBConfigs =
@@ -331,7 +329,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 +337,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 +360,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 +369,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 +378,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 +396,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
@@ -442,7 +440,7 @@ void _glfwTerminateGLX(void)
// Create the OpenGL or OpenGL ES context
//
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
bool _glfwCreateContextGLX(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
@@ -457,7 +455,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 +466,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 +476,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 +487,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 +552,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 +588,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 +606,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 +614,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,14 +624,14 @@ 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,
bool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth)
@@ -645,7 +643,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 +651,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 +693,3 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
return window->context.glx.window;
}

36
glfw/glx_context.h vendored
View File

@@ -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
@@ -153,28 +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);

72
glfw/ibus_glfw.c vendored
View File

@@ -50,13 +50,13 @@ 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
static inline size_t
MIN(size_t a, size_t b) {
return a < b ? a : b;
}
@@ -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

@@ -41,7 +41,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 +50,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 +92,7 @@ static void terminate(void)
_glfwTerminateVulkan();
_glfwPlatformTerminate();
_glfw.initialized = GLFW_FALSE;
_glfw.initialized = false;
while (_glfw.errorListHead)
{
@@ -193,6 +193,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 +215,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 +223,7 @@ GLFWAPI int glfwInit(void)
if (!_glfwPlatformInit())
{
terminate();
return GLFW_FALSE;
return false;
}
if (!_glfwPlatformCreateMutex(&_glfw.errorLock) ||
@@ -217,12 +231,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 +249,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 +334,34 @@ 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 glfwRequestTickCallback(void) {
_glfwPlatformRequestTickCallback();
}
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);
}

110
glfw/input.c vendored
View File

@@ -58,17 +58,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 +110,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 +148,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 +158,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 +168,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 +229,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 +246,7 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
}
_glfwPlatformUpdateGamepadGUID(mapping->guid);
return GLFW_TRUE;
return true;
}
@@ -260,13 +260,13 @@ void _glfwInputKeyboard(_GLFWwindow* window, int key, int scancode, int action,
{
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 +312,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 +328,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,7 +406,7 @@ _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);
@@ -415,7 +415,7 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
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 +487,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 +566,15 @@ const char* _glfwGetKeyName(int key)
}
}
// Center the cursor in the middle of 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 +633,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 +653,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 +672,7 @@ 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 +832,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 +920,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 +988,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 +1190,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 +1240,7 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string)
js->mapping = findValidMapping(js);
}
return GLFW_TRUE;
return true;
}
GLFWAPI int glfwJoystickIsGamepad(int jid)
@@ -1244,20 +1250,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 +1307,23 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
memset(state, 0, sizeof(GLFWgamepadstate));
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
_GLFW_REQUIRE_INIT_OR_RETURN(false);
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
return GLFW_FALSE;
return false;
}
js = _glfw.joysticks + jid;
if (!js->present)
return GLFW_FALSE;
return false;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_ALL))
return GLFW_FALSE;
return false;
if (!js->mapping)
return GLFW_FALSE;
return false;
for (i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++)
{
@@ -1358,7 +1364,7 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
state->axes[i] = (float) js->buttons[e->index];
}
return GLFW_TRUE;
return true;
}
GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
@@ -1375,6 +1381,22 @@ GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle)
return _glfwPlatformGetClipboardString();
}
#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND)
GLFWAPI void glfwSetPrimarySelectionString(GLFWwindow* handle, const char* string)
{
assert(string != NULL);
_GLFW_REQUIRE_INIT();
_glfwPlatformSetPrimarySelectionString(string);
}
GLFWAPI const char* glfwGetPrimarySelectionString(GLFWwindow* handle)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return _glfwPlatformGetPrimarySelectionString();
}
#endif
GLFWAPI double glfwGetTime(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(0.0);

166
glfw/internal.h vendored
View File

@@ -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)
@@ -244,12 +247,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 +267,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 +302,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 +335,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 +350,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;
@@ -378,12 +381,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 +397,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 +414,7 @@ struct _GLFWwindow
GLFWwindowclosefun close;
GLFWwindowrefreshfun refresh;
GLFWwindowfocusfun focus;
GLFWwindowocclusionfun occlusion;
GLFWwindowiconifyfun iconify;
GLFWwindowmaximizefun maximize;
GLFWframebuffersizefun fbsize;
@@ -421,6 +425,7 @@ struct _GLFWwindow
GLFWscrollfun scroll;
GLFWkeyboardfun keyboard;
GLFWdropfun drop;
GLFWliveresizefun liveResize;
} callbacks;
// This is defined in the window API's platform.h
@@ -485,7 +490,7 @@ struct _GLFWmapping
//
struct _GLFWjoystick
{
GLFWbool present;
bool present;
float* axes;
int axisCount;
unsigned char* buttons;
@@ -521,7 +526,7 @@ struct _GLFWmutex
//
struct _GLFWlibrary
{
GLFWbool initialized;
bool initialized;
struct {
_GLFWinitconfig init;
@@ -554,25 +559,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;
@@ -611,7 +614,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 +625,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 +661,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 +679,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 +708,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 +723,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 +740,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 +750,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 +794,18 @@ _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 _glfwPlatformRequestTickCallback(void);
void _glfwPlatformStopMainLoop(void);
unsigned long long _glfwPlatformAddTimer(double interval, bool repeats, GLFWuserdatafun callback, void *callback_data, GLFWuserdatafun free_callback);
void _glfwPlatformUpdateTimer(unsigned long long timer_id, double interval, bool enabled);
void _glfwPlatformRemoveTimer(unsigned long long timer_id);
char* _glfw_strdup(const char* source);

27
glfw/linux_joystick.c vendored
View File

@@ -124,7 +124,7 @@ 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] = "";
@@ -142,12 +142,12 @@ static GLFWbool openJoystickDevice(const char* path)
if (!_glfw.joysticks[jid].present)
continue;
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
return GLFW_FALSE;
return false;
}
linjs.fd = open(path, O_RDONLY | O_NONBLOCK);
if (linjs.fd == -1)
return GLFW_FALSE;
return false;
if (ioctl(linjs.fd, EVIOCGBIT(0, sizeof(evBits)), evBits) < 0 ||
ioctl(linjs.fd, EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits) < 0 ||
@@ -158,14 +158,14 @@ 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;
}
if (ioctl(linjs.fd, EVIOCGNAME(sizeof(name)), name) < 0)
@@ -225,16 +225,16 @@ static GLFWbool openJoystickDevice(const char* path)
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,7 +264,7 @@ static int compareJoysticks(const void* fp, const void* sp)
// Initialize joystick interface
//
GLFWbool _glfwInitJoysticksLinux(void)
bool _glfwInitJoysticksLinux(void)
{
DIR* dir;
int count = 0;
@@ -286,7 +286,7 @@ 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);
@@ -315,7 +315,7 @@ GLFWbool _glfwInitJoysticksLinux(void)
// Continue with no joysticks if enumeration fails
qsort(_glfw.joysticks, count, sizeof(_GLFWjoystick), compareJoysticks);
return GLFW_TRUE;
return true;
}
// Close all opened joystick handles
@@ -408,10 +408,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);
}
}
@@ -431,4 +431,3 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
void _glfwPlatformUpdateGamepadGUID(char* guid)
{
}

View File

@@ -52,11 +52,11 @@ 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);

106
glfw/linux_notify.c vendored Normal file
View File

@@ -0,0 +1,106 @@
/*
* 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, DBusMessage *msg, void *user_data) {
(void)(user_data);
/* 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);

47
glfw/main_loop.h vendored Normal file
View File

@@ -0,0 +1,47 @@
/*
* 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 _glfwPlatformRequestTickCallback() {
}
void _glfwPlatformStopMainLoop(void) {
if (keep_going) {
keep_going = false;
_glfwPlatformPostEmptyEvent();
}
}
void _glfwPlatformRunMainLoop(GLFWtickcallback tick_callback, void* data) {
keep_going = true;
while(keep_going) {
_glfwPlatformWaitEvents();
EVDBG("loop tick");
tick_callback(data);
}
}
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);
}

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

59
glfw/monitor.c vendored
View File

@@ -60,17 +60,17 @@ 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);
@@ -78,7 +78,7 @@ static GLFWbool refreshVideoModes(_GLFWmonitor* monitor)
monitor->modes = modes;
monitor->modeCount = modeCount;
return GLFW_TRUE;
return true;
}
@@ -127,10 +127,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 +327,25 @@ 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,11 +443,11 @@ 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 <= FLT_MAX);
@@ -442,13 +458,18 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
_glfwInputError(GLFW_INVALID_VALUE, "Invalid gamma value %f", gamma);
return;
}
original = glfwGetGammaRamp(handle);
if (!original)
return;
for (i = 0; i < 256; i++)
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;
@@ -462,9 +483,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 +497,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 +524,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);
}

6
glfw/nsgl_context.h vendored
View File

@@ -33,7 +33,7 @@
typedef struct _GLFWcontextNSGL
{
id pixelFormat;
id object;
id object;
} _GLFWcontextNSGL;
@@ -47,9 +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

@@ -45,17 +45,16 @@ static void swapBuffersNSGL(_GLFWwindow* window)
static void swapIntervalNSGL(int interval)
{
_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
(void)(interval);
_glfwInputError(GLFW_API_UNAVAILABLE,
"NSGL: Swap intervals do not work on macOS");
}
static int extensionSupportedNSGL(const char* extension)
{
// There are no NSGL extensions
return GLFW_FALSE;
return false;
}
static GLFWglproc getProcAddressNSGL(const char* procname)
@@ -72,8 +71,6 @@ static GLFWglproc getProcAddressNSGL(const char* procname)
return symbol;
}
// Destroy the OpenGL context
//
static void destroyContextNSGL(_GLFWwindow* window)
{
[window->context.nsgl.pixelFormat release];
@@ -90,10 +87,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 +98,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 +112,7 @@ void _glfwTerminateNSGL(void)
// Create the OpenGL context
//
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
bool _glfwCreateContextNSGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
@@ -123,7 +120,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,15 +129,9 @@ 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;
return 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;
}
}
// Context robustness modes (GL_KHR_robustness) are not yet supported by
@@ -175,9 +166,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 +231,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 +267,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 +282,22 @@ 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 +307,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
window->context.getProcAddress = getProcAddressNSGL;
window->context.destroy = destroyContextNSGL;
return GLFW_TRUE;
return true;
}
@@ -332,4 +328,3 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle)
return window->context.nsgl.object;
}

2
glfw/null_init.c vendored
View File

@@ -35,7 +35,7 @@
int _glfwPlatformInit(void)
{
_glfwInitTimerPOSIX();
return GLFW_TRUE;
return true;
}
void _glfwPlatformTerminate(void)

View File

@@ -33,7 +33,7 @@
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
{
return GLFW_FALSE;
return false;
}
void _glfwPlatformUpdateGamepadGUID(char* guid)

8
glfw/null_monitor.c vendored
View File

@@ -49,6 +49,10 @@ 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,11 +62,11 @@ 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)
{
}

48
glfw/null_window.c vendored
View File

@@ -34,7 +34,7 @@ static int createNativeWindow(_GLFWwindow* window,
window->null.width = wndconfig->width;
window->null.height = wndconfig->height;
return GLFW_TRUE;
return true;
}
@@ -48,7 +48,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 +56,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 +148,11 @@ void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
*yscale = 1.f;
}
double _glfwPlatformGetDoubleClickInterval(_GLFWwindow* window)
{
return 0.5;
}
void _glfwPlatformIconifyWindow(_GLFWwindow* window)
{
}
@@ -162,28 +167,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 +212,7 @@ void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
int _glfwPlatformWindowBell(_GLFWwindow* window)
{
return GLFW_FALSE;
return false;
}
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
@@ -224,17 +229,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 +279,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 +322,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
return GLFW_FALSE;
return false;
}
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,

39
glfw/osmesa_context.c vendored
View File

@@ -100,7 +100,7 @@ static void swapIntervalOSMesa(int interval)
static int extensionSupportedOSMesa(const char* extension)
{
// OSMesa does not have extensions
return GLFW_FALSE;
return false;
}
@@ -108,7 +108,7 @@ static int extensionSupportedOSMesa(const char* extension)
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwInitOSMesa(void)
bool _glfwInitOSMesa(void)
{
int i;
const char* sonames[] =
@@ -130,7 +130,7 @@ GLFWbool _glfwInitOSMesa(void)
};
if (_glfw.osmesa.handle)
return GLFW_TRUE;
return true;
for (i = 0; sonames[i]; i++)
{
@@ -142,7 +142,7 @@ 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)
@@ -171,10 +171,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)
@@ -193,7 +193,7 @@ void _glfwTerminateOSMesa(void)
attribs[index++] = v; \
}
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
bool _glfwCreateContextOSMesa(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
@@ -207,7 +207,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 +240,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 +255,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"OSMesa: OpenGL profiles unavailable");
return GLFW_FALSE;
return false;
}
window->context.osmesa.handle =
@@ -270,7 +270,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 +280,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
window->context.getProcAddress = getProcAddressOSMesa;
window->context.destroy = destroyContextOSMesa;
return GLFW_TRUE;
return true;
}
#undef setAttrib
@@ -298,7 +298,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 +306,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 +318,7 @@ GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width,
if (buffer)
*buffer = mesaBuffer;
return GLFW_TRUE;
return true;
}
GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
@@ -331,7 +331,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 +339,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 +351,7 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
if (buffer)
*buffer = mesaBuffer;
return GLFW_TRUE;
return true;
}
GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle)
@@ -367,4 +367,3 @@ GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle)
return window->context.osmesa.handle;
}

View File

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

26
glfw/posix_thread.c vendored
View File

@@ -35,19 +35,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 +59,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 +91,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);
}

4
glfw/posix_thread.h vendored
View File

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

4
glfw/posix_time.c vendored
View File

@@ -44,13 +44,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;
}
}

2
glfw/posix_time.h vendored
View File

@@ -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"
]
}
}
}

42
glfw/vulkan.c vendored
View File

@@ -39,14 +39,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,7 +63,7 @@ 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)
@@ -74,7 +74,7 @@ GLFWbool _glfwInitVulkan(int mode)
"Vulkan: Loader does not export vkGetInstanceProcAddr");
_glfwTerminateVulkan();
return GLFW_FALSE;
return false;
}
_glfw.vk.EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)
@@ -85,7 +85,7 @@ GLFWbool _glfwInitVulkan(int mode)
"Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties");
_glfwTerminateVulkan();
return GLFW_FALSE;
return false;
}
#endif // _GLFW_VULKAN_STATIC
@@ -101,7 +101,7 @@ GLFWbool _glfwInitVulkan(int mode)
}
_glfwTerminateVulkan();
return GLFW_FALSE;
return false;
}
ep = calloc(count, sizeof(VkExtensionProperties));
@@ -115,40 +115,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 +218,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);
}
@@ -276,16 +273,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 +323,3 @@ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance,
return _glfwPlatformCreateWindowSurface(instance, window, allocator, surface);
}

61
glfw/wgl_context.c vendored
View File

@@ -122,9 +122,9 @@ static int choosePixelFormat(_GLFWwindow* window,
u->auxBuffers = getPixelFormatAttrib(window, n, WGL_AUX_BUFFERS_ARB);
if (getPixelFormatAttrib(window, n, WGL_STEREO_ARB))
u->stereo = GLFW_TRUE;
u->stereo = true;
if (getPixelFormatAttrib(window, n, WGL_DOUBLE_BUFFER_ARB))
u->doublebuffer = GLFW_TRUE;
u->doublebuffer = true;
if (_glfw.wgl.ARB_multisample)
u->samples = getPixelFormatAttrib(window, n, WGL_SAMPLES_ARB);
@@ -135,7 +135,7 @@ static int choosePixelFormat(_GLFWwindow* window,
_glfw.wgl.EXT_framebuffer_sRGB)
{
if (getPixelFormatAttrib(window, n, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB))
u->sRGB = GLFW_TRUE;
u->sRGB = true;
}
}
else
@@ -145,7 +145,7 @@ static int choosePixelFormat(_GLFWwindow* window,
if (getPixelFormatAttrib(window, n, WGL_COLORSPACE_EXT) ==
WGL_COLORSPACE_SRGB_EXT)
{
u->sRGB = GLFW_TRUE;
u->sRGB = true;
}
}
}
@@ -195,9 +195,9 @@ static int choosePixelFormat(_GLFWwindow* window,
u->auxBuffers = pfd.cAuxBuffers;
if (pfd.dwFlags & PFD_STEREO)
u->stereo = GLFW_TRUE;
u->stereo = true;
if (pfd.dwFlags & PFD_DOUBLEBUFFER)
u->doublebuffer = GLFW_TRUE;
u->doublebuffer = true;
}
u->handle = n;
@@ -308,7 +308,7 @@ static int extensionSupportedWGL(const char* extension)
if (extensions)
{
if (_glfwStringInExtensionString(extension, extensions))
return GLFW_TRUE;
return true;
}
}
@@ -318,11 +318,11 @@ static int extensionSupportedWGL(const char* extension)
if (extensions)
{
if (_glfwStringInExtensionString(extension, extensions))
return GLFW_TRUE;
return true;
}
}
return GLFW_FALSE;
return false;
}
static GLFWglproc getProcAddressWGL(const char* procname)
@@ -352,21 +352,21 @@ static void destroyContextWGL(_GLFWwindow* window)
// Initialize WGL
//
GLFWbool _glfwInitWGL(void)
bool _glfwInitWGL(void)
{
PIXELFORMATDESCRIPTOR pfd;
HGLRC prc, rc;
HDC pdc, dc;
if (_glfw.wgl.instance)
return GLFW_TRUE;
return true;
_glfw.wgl.instance = LoadLibraryA("opengl32.dll");
if (!_glfw.wgl.instance)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to load opengl32.dll");
return GLFW_FALSE;
return false;
}
_glfw.wgl.CreateContext = (PFN_wglCreateContext)
@@ -389,7 +389,7 @@ GLFWbool _glfwInitWGL(void)
// NOTE: This code will accept the Microsoft GDI ICD; accelerated context
// creation failure occurs during manual pixel format enumeration
dc = GetDC(_glfw.win32.helperWindowHandle);;
dc = GetDC(_glfw.win32.helperWindowHandle);
ZeroMemory(&pfd, sizeof(pfd));
pfd.nSize = sizeof(pfd);
@@ -402,7 +402,7 @@ GLFWbool _glfwInitWGL(void)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to set pixel format for dummy context");
return GLFW_FALSE;
return false;
}
rc = wglCreateContext(dc);
@@ -410,7 +410,7 @@ GLFWbool _glfwInitWGL(void)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to create dummy context");
return GLFW_FALSE;
return false;
}
pdc = wglGetCurrentDC();
@@ -422,7 +422,7 @@ GLFWbool _glfwInitWGL(void)
"WGL: Failed to make dummy context current");
wglMakeCurrent(pdc, prc);
wglDeleteContext(rc);
return GLFW_FALSE;
return false;
}
// NOTE: Functions must be loaded first as they're needed to retrieve the
@@ -467,7 +467,7 @@ GLFWbool _glfwInitWGL(void)
wglMakeCurrent(pdc, prc);
wglDeleteContext(rc);
return GLFW_TRUE;
return true;
}
// Terminate WGL
@@ -487,7 +487,7 @@ void _glfwTerminateWGL(void)
// Create the OpenGL or OpenGL ES context
//
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
bool _glfwCreateContextWGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
@@ -504,26 +504,26 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"WGL: Failed to retrieve DC for window");
return GLFW_FALSE;
return false;
}
pixelFormat = choosePixelFormat(window, ctxconfig, fbconfig);
if (!pixelFormat)
return GLFW_FALSE;
return 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;
return false;
}
if (!SetPixelFormat(window->context.wgl.dc, pixelFormat, &pfd))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to set selected pixel format");
return GLFW_FALSE;
return false;
}
if (ctxconfig->client == GLFW_OPENGL_API)
@@ -534,7 +534,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: A forward compatible OpenGL context requested but WGL_ARB_create_context is unavailable");
return GLFW_FALSE;
return false;
}
}
@@ -544,7 +544,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: OpenGL profile requested but WGL_ARB_create_context_profile is unavailable");
return GLFW_FALSE;
return false;
}
}
}
@@ -556,7 +556,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"WGL: OpenGL ES requested but WGL_ARB_create_context_es2_profile is unavailable");
return GLFW_FALSE;
return false;
}
}
@@ -619,7 +619,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
if (ctxconfig->noerror)
{
if (_glfw.wgl.ARB_create_context_no_error)
setAttrib(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
setAttrib(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, true);
}
// NOTE: Only request an explicitly versioned context when necessary, as
@@ -687,7 +687,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
}
}
return GLFW_FALSE;
return false;
}
}
else
@@ -697,7 +697,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
{
_glfwInputErrorWin32(GLFW_VERSION_UNAVAILABLE,
"WGL: Failed to create OpenGL context");
return GLFW_FALSE;
return false;
}
if (share)
@@ -706,7 +706,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to enable sharing with specified OpenGL context");
return GLFW_FALSE;
return false;
}
}
}
@@ -718,7 +718,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
window->context.getProcAddress = getProcAddressWGL;
window->context.destroy = destroyContextWGL;
return GLFW_TRUE;
return true;
}
#undef setAttrib
@@ -741,4 +741,3 @@ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle)
return window->context.wgl.handle;
}

28
glfw/wgl_context.h vendored
View File

@@ -135,25 +135,25 @@ typedef struct _GLFWlibraryWGL
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;
bool EXT_swap_control;
bool EXT_colorspace;
bool ARB_multisample;
bool ARB_framebuffer_sRGB;
bool EXT_framebuffer_sRGB;
bool ARB_pixel_format;
bool ARB_create_context;
bool ARB_create_context_profile;
bool EXT_create_context_es2_profile;
bool ARB_create_context_robustness;
bool ARB_create_context_no_error;
bool ARB_context_flush_control;
} _GLFWlibraryWGL;
GLFWbool _glfwInitWGL(void);
bool _glfwInitWGL(void);
void _glfwTerminateWGL(void);
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
bool _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

170
glfw/window.c vendored
View File

@@ -40,7 +40,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);
@@ -88,8 +88,16 @@ _GLFWwindow* _glfwWindowForId(GLFWid id) {
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 +116,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 +124,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 +139,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 +168,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);
@@ -254,19 +270,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 +300,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 +317,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 +366,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 +432,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 +735,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 +815,10 @@ GLFWAPI void glfwShowWindow(GLFWwindow* handle)
_glfwPlatformShowWindow(window);
#ifndef _GLFW_WAYLAND
if (window->focusOnShow)
_glfwPlatformFocusWindow(window);
#endif
}
GLFWAPI void glfwRequestWindowAttention(GLFWwindow* handle)
@@ -811,7 +836,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 +887,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 +932,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 +1017,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 +1096,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 +1140,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 +1162,9 @@ 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();
}

226
glfw/wl_init.c vendored
View File

@@ -29,6 +29,8 @@
#include "backend_utils.h"
#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <linux/input.h>
#include <stdio.h>
#include <stdlib.h>
@@ -101,10 +103,10 @@ 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,
@@ -117,28 +119,22 @@ static void pointerHandleLeave(void* data,
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];
@@ -165,56 +161,51 @@ static void pointerHandleMotion(void* data,
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));
_glfwInputCursorPos(window, 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,
@@ -227,8 +218,7 @@ static void pointerHandleButton(void* data,
_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 +230,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)
@@ -386,7 +370,7 @@ static void keyboardHandleEnter(void* data,
}
_glfw.wl.keyboardFocus = window;
_glfwInputWindowFocus(window, GLFW_TRUE);
_glfwInputWindowFocus(window, true);
}
static void keyboardHandleLeave(void* data,
@@ -400,14 +384,14 @@ 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) {
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);
}
@@ -424,12 +408,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) {
@@ -542,11 +526,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 +540,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 +553,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,6 +595,17 @@ 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();
}
}
}
@@ -614,14 +613,20 @@ static void registryHandleGlobalRemove(void *data,
struct wl_registry *registry,
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,6 +640,39 @@ static const struct wl_registry_listener registryListener = {
};
static void registry_handle_global(void* data,
struct wl_registry* registry,
uint32_t name,
const char* interface,
uint32_t version) {
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,
struct wl_registry *registry,
uint32_t name) {}
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 //////
//////////////////////////////////////////////////////////////////////////
@@ -645,7 +683,7 @@ int _glfwPlatformInit(void)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: failed to create self pipe");
return GLFW_FALSE;
return false;
}
_glfw.wl.cursor.handle = _glfw_dlopen("libwayland-cursor.so.0");
@@ -653,7 +691,7 @@ int _glfwPlatformInit(void)
{
_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)
@@ -670,7 +708,7 @@ int _glfwPlatformInit(void)
{
_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)
@@ -685,17 +723,17 @@ int _glfwPlatformInit(void)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Failed to connect to display");
return GLFW_FALSE;
return false;
}
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 +744,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 +813,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 +842,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)
@@ -797,13 +855,14 @@ void _glfwPlatformTerminate(void)
}
closeFds(_glfw.wl.eventLoopData.wakeupFds, sizeof(_glfw.wl.eventLoopData.wakeupFds)/sizeof(_glfw.wl.eventLoopData.wakeupFds[0]));
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 +874,6 @@ const char* _glfwPlatformGetVersionString(void)
#endif
;
}
#define GLFW_LOOP_BACKEND wl
#include "main_loop.h"

80
glfw/wl_monitor.c vendored
View File

@@ -30,18 +30,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,
int32_t x,
int32_t y,
int32_t physicalWidth,
int32_t physicalHeight,
int32_t subpixel,
const char* make,
const char* model,
int32_t transform)
{
struct _GLFWmonitor *monitor = data;
char name[1024];
@@ -55,12 +56,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,
uint32_t flags,
int32_t width,
int32_t height,
int32_t refresh)
{
struct _GLFWmonitor *monitor = data;
GLFWvidmode mode;
@@ -70,7 +71,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 +82,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)
{
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,
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 +173,18 @@ 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 +196,17 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
*mode = monitor->modes[monitor->wl.currentMode];
}
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{
// 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)
{
// TODO
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Gamma ramp setting not supported yet");
"Wayland: Gamma ramp access is not available");
}
@@ -205,4 +220,3 @@ GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* handle)
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return monitor->wl.output;
}

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

1049
glfw/wl_window.c vendored

File diff suppressed because it is too large Load Diff

51
glfw/x11_init.c vendored
View File

@@ -137,6 +137,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 =
@@ -150,7 +154,7 @@ static void detectEWMH(void)
// 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)
@@ -195,7 +199,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;
}
}
}
@@ -254,7 +258,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 +277,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);
@@ -326,7 +330,7 @@ static GLFWbool initExtensions(void)
&_glfw.x11.xinerama.minor))
{
if (XineramaIsActive(_glfw.x11.display))
_glfw.x11.xinerama.available = GLFW_TRUE;
_glfw.x11.xinerama.available = true;
}
}
@@ -352,7 +356,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,19 +373,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;
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;
// Detect whether an EWMH-conformant window manager is running
detectEWMH();
@@ -453,12 +457,12 @@ static GLFWbool initExtensions(void)
_glfw.x11.NET_WM_CM_Sx = XInternAtom(_glfw.x11.display, name, False);
}
return GLFW_TRUE;
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
@@ -620,7 +624,7 @@ int _glfwPlatformInit(void)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: failed to create self pipe");
return GLFW_FALSE;
return false;
}
_glfw.x11.display = XOpenDisplay(NULL);
@@ -638,7 +642,7 @@ 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));
@@ -650,10 +654,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 +665,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 +674,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) ==
@@ -754,7 +759,7 @@ void _glfwPlatformTerminate(void)
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 +773,5 @@ const char* _glfwPlatformGetVersionString(void)
#endif
;
}
#include "main_loop.h"

113
glfw/x11_monitor.c vendored
View File

@@ -30,11 +30,12 @@
#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 +45,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;
}
@@ -348,6 +349,100 @@ 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;
XRRCrtcInfo* ci;
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
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;
@@ -433,7 +528,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 +544,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 +556,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;
}
}
@@ -492,6 +595,10 @@ 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");
}
}

30
glfw/x11_platform.h vendored
View File

@@ -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
@@ -251,6 +247,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 +284,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 +336,7 @@ typedef struct _GLFWlibraryX11
} xcursor;
struct {
GLFWbool available;
bool available;
void* handle;
int major;
int minor;
@@ -348,7 +346,7 @@ typedef struct _GLFWlibraryX11
} xinerama;
struct {
GLFWbool available;
bool available;
void* handle;
int eventBase;
int errorBase;
@@ -359,7 +357,7 @@ typedef struct _GLFWlibraryX11
} vidmode;
struct {
GLFWbool available;
bool available;
void* handle;
int majorOpcode;
int eventBase;
@@ -371,7 +369,7 @@ typedef struct _GLFWlibraryX11
} xi;
struct {
GLFWbool available;
bool available;
void* handle;
int major;
int minor;
@@ -418,11 +416,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);

490
glfw/x11_window.c vendored
View File

@@ -28,6 +28,7 @@
#define _GNU_SOURCE
#include "internal.h"
#include "backend_utils.h"
#include "linux_notify.h"
#include <X11/cursorfont.h>
#include <X11/Xmd.h>
@@ -54,32 +55,40 @@
// This avoids blocking other threads via the per-display Xlib lock that also
// covers GLX functions
//
GLFWbool _glfwDispatchX11Events(void);
static unsigned _glfwDispatchX11Events(void);
static void
handleEvents(double timeout) {
EVDBG("starting handleEvents(%.2f)", timeout);
int display_read_ok = pollForEvents(&_glfw.x11.eventLoopData, timeout);
if (display_read_ok) _glfwDispatchX11Events();
EVDBG("display_read_ok: %d", display_read_ok);
if (display_read_ok) {
unsigned dispatched = _glfwDispatchX11Events();
(void)dispatched;
EVDBG("dispatched %u X11 events", dispatched);
}
glfw_ibus_dispatch(&_glfw.x11.xkb.ibus);
glfw_dbus_session_bus_dispatch();
EVDBG("other dispatch done");
}
static GLFWbool
static bool
waitForX11Event(double timeout) {
// returns true iff there is X11 data waiting to be read, does not run watches and timers
double end_time = glfwGetTime() + timeout;
while(GLFW_TRUE) {
while(true) {
if (timeout >= 0) {
const int result = pollWithTimeout(_glfw.x11.eventLoopData.fds, 1, timeout);
if (result > 0) return GLFW_TRUE;
if (result > 0) return true;
timeout = end_time - glfwGetTime();
if (timeout <= 0) return GLFW_FALSE;
if (timeout <= 0) return false;
if (result < 0 && (errno == EINTR || errno == EAGAIN)) continue;
return GLFW_FALSE;
return false;
} else {
const int result = poll(_glfw.x11.eventLoopData.fds, 1, -1);
if (result > 0) return GLFW_TRUE;
if (result > 0) return true;
if (result < 0 && (errno == EINTR || errno == EAGAIN)) continue;
return GLFW_FALSE;
return false;
}
}
}
@@ -87,7 +96,7 @@ waitForX11Event(double timeout) {
// Waits until a VisibilityNotify event arrives for the specified window or the
// timeout period elapses (ICCCM section 4.2.2)
//
static GLFWbool waitForVisibilityNotify(_GLFWwindow* window)
static bool waitForVisibilityNotify(_GLFWwindow* window)
{
XEvent dummy;
@@ -97,10 +106,10 @@ static GLFWbool waitForVisibilityNotify(_GLFWwindow* window)
&dummy))
{
if (!waitForX11Event(0.1))
return GLFW_FALSE;
return false;
}
return GLFW_TRUE;
return true;
}
// Returns whether the window is iconified
@@ -256,6 +265,76 @@ static void updateNormalHints(_GLFWwindow* window, int width, int height)
XFree(hints);
}
static inline bool
is_window_fullscreen(_GLFWwindow* window)
{
Atom* states;
unsigned long i;
bool ans = false;
if (!_glfw.x11.NET_WM_STATE || !_glfw.x11.NET_WM_STATE_FULLSCREEN)
return ans;
const unsigned long count =
_glfwGetWindowPropertyX11(window->x11.handle,
_glfw.x11.NET_WM_STATE,
XA_ATOM,
(unsigned char**) &states);
for (i = 0; i < count; i++)
{
if (states[i] == _glfw.x11.NET_WM_STATE_FULLSCREEN)
{
ans = true;
break;
}
}
if (states)
XFree(states);
return ans;
}
static inline void
set_fullscreen(_GLFWwindow *window, bool on) {
if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN) {
sendEventToWM(window,
_glfw.x11.NET_WM_STATE,
on ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE,
_glfw.x11.NET_WM_STATE_FULLSCREEN,
0, 1, 0);
// Enable compositor bypass
if (!window->x11.transparent)
{
if (on) {
const unsigned long value = 1;
XChangeProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32,
PropModeReplace, (unsigned char*) &value, 1);
} else {
XDeleteProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.NET_WM_BYPASS_COMPOSITOR);
}
}
} else {
static bool warned = false;
if (!warned) {
warned = true;
_glfwInputErrorX11(GLFW_PLATFORM_ERROR,
"X11: Failed to toggle fullscreen, the window manager does not support it");
}
}
}
bool
_glfwPlatformToggleFullscreen(_GLFWwindow *window, unsigned int flags) {
(void) flags;
bool already_fullscreen = is_window_fullscreen(window);
set_fullscreen(window, !already_fullscreen);
return !already_fullscreen;
}
// Updates the full screen status of the window
//
static void updateWindowMode(_GLFWwindow* window)
@@ -274,43 +353,8 @@ static void updateWindowMode(_GLFWwindow* window)
0);
}
if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN)
{
sendEventToWM(window,
_glfw.x11.NET_WM_STATE,
_NET_WM_STATE_ADD,
_glfw.x11.NET_WM_STATE_FULLSCREEN,
0, 1, 0);
}
else
{
// This is the butcher's way of removing window decorations
// Setting the override-redirect attribute on a window makes the
// window manager ignore the window completely (ICCCM, section 4)
// The good thing is that this makes undecorated full screen windows
// easy to do; the bad thing is that we have to do everything
// manually and some things (like iconify/restore) won't work at
// all, as those are tasks usually performed by the window manager
set_fullscreen(window, true);
XSetWindowAttributes attributes;
attributes.override_redirect = True;
XChangeWindowAttributes(_glfw.x11.display,
window->x11.handle,
CWOverrideRedirect,
&attributes);
window->x11.overrideRedirect = GLFW_TRUE;
}
// Enable compositor bypass
if (!window->x11.transparent)
{
const unsigned long value = 1;
XChangeProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32,
PropModeReplace, (unsigned char*) &value, 1);
}
}
else
{
@@ -321,32 +365,8 @@ static void updateWindowMode(_GLFWwindow* window)
_glfw.x11.NET_WM_FULLSCREEN_MONITORS);
}
if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN)
{
sendEventToWM(window,
_glfw.x11.NET_WM_STATE,
_NET_WM_STATE_REMOVE,
_glfw.x11.NET_WM_STATE_FULLSCREEN,
0, 1, 0);
}
else
{
XSetWindowAttributes attributes;
attributes.override_redirect = False;
XChangeWindowAttributes(_glfw.x11.display,
window->x11.handle,
CWOverrideRedirect,
&attributes);
set_fullscreen(window, false);
window->x11.overrideRedirect = GLFW_FALSE;
}
// Disable compositor bypass
if (!window->x11.transparent)
{
XDeleteProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.NET_WM_BYPASS_COMPOSITOR);
}
}
}
@@ -401,15 +421,6 @@ static char* convertLatin1toUTF8(const char* source)
return target;
}
// Centers the cursor over the window client area
//
static void centerCursor(_GLFWwindow* window)
{
int width, height;
_glfwPlatformGetWindowSize(window, &width, &height);
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
}
// Updates the cursor image according to its cursor mode
//
static void updateCursorImage(_GLFWwindow* window)
@@ -453,7 +464,7 @@ static void disableCursor(_GLFWwindow* window)
&_glfw.x11.restoreCursorPosX,
&_glfw.x11.restoreCursorPosY);
updateCursorImage(window);
centerCursor(window);
_glfwCenterCursorInContentArea(window);
XGrabPointer(_glfw.x11.display, window->x11.handle, True,
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
GrabModeAsync, GrabModeAsync,
@@ -488,7 +499,7 @@ static void enableCursor(_GLFWwindow* window)
// Create the X11 window (and its colormap)
//
static GLFWbool createNativeWindow(_GLFWwindow* window,
static bool createNativeWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
Visual* visual, int depth)
{
@@ -540,7 +551,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
{
_glfwInputErrorX11(GLFW_PLATFORM_ERROR,
"X11: Failed to create window");
return GLFW_FALSE;
return false;
}
XSaveContext(_glfw.x11.display,
@@ -550,7 +561,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
}
if (!wndconfig->decorated)
_glfwPlatformSetWindowDecorated(window, GLFW_FALSE);
_glfwPlatformSetWindowDecorated(window, false);
if (_glfw.x11.NET_WM_STATE && !window->monitor)
{
@@ -570,7 +581,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
{
states[count++] = _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT;
states[count++] = _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ;
window->x11.maximized = GLFW_TRUE;
window->x11.maximized = true;
}
}
@@ -619,7 +630,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
{
_glfwInputError(GLFW_OUT_OF_MEMORY,
"X11: Failed to allocate WM hints");
return GLFW_FALSE;
return false;
}
hints->flags = StateHint;
@@ -673,7 +684,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
_glfwPlatformGetWindowPos(window, &window->x11.xpos, &window->x11.ypos);
_glfwPlatformGetWindowSize(window, &window->x11.width, &window->x11.height);
return GLFW_TRUE;
return true;
}
// Set the specified property to the selection converted to the requested target
@@ -873,6 +884,7 @@ static const char* getSelectionString(Atom selection)
Atom actualType;
int actualFormat;
unsigned long itemCount, bytesAfter;
double start = glfwGetTime();
XEvent notification, dummy;
XConvertSelection(_glfw.x11.display,
@@ -887,7 +899,10 @@ static const char* getSelectionString(Atom selection)
SelectionNotify,
&notification))
{
waitForX11Event(-1);
double time = glfwGetTime();
if (time - start > 2)
return "";
waitForX11Event(2.0 - (time - start));
}
if (notification.xselection.property == None)
@@ -918,12 +933,16 @@ static const char* getSelectionString(Atom selection)
for (;;)
{
start = glfwGetTime();
while (!XCheckIfEvent(_glfw.x11.display,
&dummy,
isSelPropNewValueNotify,
(XPointer) &notification))
{
waitForX11Event(-1);
double time = glfwGetTime();
if (time - start > 2)
return "";
waitForX11Event(2.0 - (time - start));
}
XFree(data);
@@ -1008,19 +1027,6 @@ static void acquireMonitor(_GLFWwindow* window)
_glfwSetVideoModeX11(window->monitor, &window->videoMode);
if (window->x11.overrideRedirect)
{
int xpos, ypos;
GLFWvidmode mode;
// Manually position the window over its monitor
_glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos);
_glfwPlatformGetVideoMode(window->monitor, &mode);
XMoveResizeWindow(_glfw.x11.display, window->x11.handle,
xpos, ypos, mode.width, mode.height);
}
_glfwInputMonitorWindow(window->monitor, window);
}
@@ -1047,10 +1053,10 @@ static void releaseMonitor(_GLFWwindow* window)
}
}
static void onConfigChange()
static void onConfigChange(void)
{
float xscale, yscale;
_glfwGetSystemContentScaleX11(&xscale, &yscale, GLFW_TRUE);
_glfwGetSystemContentScaleX11(&xscale, &yscale, true);
if (xscale != _glfw.x11.contentScaleX || yscale != _glfw.x11.contentScaleY)
{
@@ -1070,7 +1076,8 @@ static void onConfigChange()
static void processEvent(XEvent *event)
{
_GLFWwindow* window = NULL;
Bool filtered = False;
static bool keymap_dirty = false;
#define UPDATE_KEYMAP_IF_NEEDED if (keymap_dirty) { keymap_dirty = false; glfw_xkb_compile_keymap(&_glfw.x11.xkb, NULL); }
if (_glfw.x11.randr.available)
{
@@ -1146,11 +1153,12 @@ static void processEvent(XEvent *event)
/* fallthrough */
case XkbMapNotify:
{
glfw_xkb_compile_keymap(&_glfw.x11.xkb, NULL);
keymap_dirty = true;
return;
}
case XkbStateNotify:
{
UPDATE_KEYMAP_IF_NEEDED;
XkbStateNotifyEvent *state_event = (XkbStateNotifyEvent*)kb_event;
glfw_xkb_update_modifiers(
&_glfw.x11.xkb, state_event->base_mods, state_event->latched_mods,
@@ -1175,12 +1183,14 @@ static void processEvent(XEvent *event)
{
case KeyPress:
{
UPDATE_KEYMAP_IF_NEEDED;
glfw_xkb_handle_key_event(window, &_glfw.x11.xkb, event->xkey.keycode, GLFW_PRESS);
return;
}
case KeyRelease:
{
UPDATE_KEYMAP_IF_NEEDED;
if (!_glfw.x11.xkb.detectable)
{
// HACK: Key repeat events will arrive as KeyRelease/KeyPress
@@ -1291,18 +1301,26 @@ static void processEvent(XEvent *event)
case EnterNotify:
{
// XEnterWindowEvent is XCrossingEvent
const int x = event->xcrossing.x;
const int y = event->xcrossing.y;
// HACK: This is a workaround for WMs (KWM, Fluxbox) that otherwise
// ignore the defined cursor for hidden cursor mode
if (window->cursorMode == GLFW_CURSOR_HIDDEN)
updateCursorImage(window);
_glfwInputCursorEnter(window, GLFW_TRUE);
_glfwInputCursorEnter(window, true);
_glfwInputCursorPos(window, x, y);
window->x11.lastCursorPosX = x;
window->x11.lastCursorPosY = y;
return;
}
case LeaveNotify:
{
_glfwInputCursorEnter(window, GLFW_FALSE);
_glfwInputCursorEnter(window, false);
return;
}
@@ -1359,7 +1377,7 @@ static void processEvent(XEvent *event)
if (event->xconfigure.x != window->x11.xpos ||
event->xconfigure.y != window->x11.ypos)
{
if (window->x11.overrideRedirect || event->xany.send_event)
if (event->xany.send_event)
{
_glfwInputWindowPos(window,
event->xconfigure.x,
@@ -1377,9 +1395,6 @@ static void processEvent(XEvent *event)
{
// Custom client message, probably from the window manager
if (filtered)
return;
if (event->xclient.message_type == None)
return;
@@ -1415,7 +1430,7 @@ static void processEvent(XEvent *event)
// A drag operation has entered the window
unsigned long i, count;
Atom* formats = NULL;
const GLFWbool list = event->xclient.data.l[1] & 1;
const bool list = event->xclient.data.l[1] & 1;
_glfw.x11.xdnd.source = event->xclient.data.l[0];
_glfw.x11.xdnd.version = event->xclient.data.l[1] >> 24;
@@ -1597,7 +1612,7 @@ static void processEvent(XEvent *event)
return;
}
_glfwInputWindowFocus(window, GLFW_TRUE);
_glfwInputWindowFocus(window, true);
return;
}
@@ -1617,7 +1632,7 @@ static void processEvent(XEvent *event)
if (window->monitor && window->autoIconify)
_glfwPlatformIconifyWindow(window);
_glfwInputWindowFocus(window, GLFW_FALSE);
_glfwInputWindowFocus(window, false);
return;
}
@@ -1638,7 +1653,7 @@ static void processEvent(XEvent *event)
if (state != IconicState && state != NormalState)
return;
const GLFWbool iconified = (state == IconicState);
const bool iconified = (state == IconicState);
if (window->x11.iconified != iconified)
{
if (window->monitor)
@@ -1655,7 +1670,7 @@ static void processEvent(XEvent *event)
}
else if (event->xproperty.atom == _glfw.x11.NET_WM_STATE)
{
const GLFWbool maximized = _glfwPlatformWindowMaximized(window);
const bool maximized = _glfwPlatformWindowMaximized(window);
if (window->x11.maximized != maximized)
{
window->x11.maximized = maximized;
@@ -1669,6 +1684,7 @@ static void processEvent(XEvent *event)
case DestroyNotify:
return;
}
#undef UPDATE_KEYMAP_IF_NEEDED
}
@@ -1704,10 +1720,10 @@ unsigned long _glfwGetWindowPropertyX11(Window window,
return itemCount;
}
GLFWbool _glfwIsVisualTransparentX11(Visual* visual)
bool _glfwIsVisualTransparentX11(Visual* visual)
{
if (!_glfw.x11.xrender.available)
return GLFW_FALSE;
return false;
XRenderPictFormat* pf = XRenderFindVisualFormat(_glfw.x11.display, visual);
return pf && pf->direct.alphaMask;
@@ -1779,21 +1795,21 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
{
if (!_glfwInitGLX())
return GLFW_FALSE;
return false;
if (!_glfwChooseVisualGLX(wndconfig, ctxconfig, fbconfig, &visual, &depth))
return GLFW_FALSE;
return false;
}
else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
{
if (!_glfwInitEGL())
return GLFW_FALSE;
return false;
if (!_glfwChooseVisualEGL(wndconfig, ctxconfig, fbconfig, &visual, &depth))
return GLFW_FALSE;
return false;
}
else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
{
if (!_glfwInitOSMesa())
return GLFW_FALSE;
return false;
}
}
@@ -1805,24 +1821,24 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
}
if (!createNativeWindow(window, wndconfig, visual, depth))
return GLFW_FALSE;
return false;
if (ctxconfig->client != GLFW_NO_API)
{
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
{
if (!_glfwCreateContextGLX(window, ctxconfig, fbconfig))
return GLFW_FALSE;
return false;
}
else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
{
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
return GLFW_FALSE;
return false;
}
else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
{
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
return GLFW_FALSE;
return false;
}
}
@@ -1834,7 +1850,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
}
XFlush(_glfw.x11.display);
return GLFW_TRUE;
return true;
}
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
@@ -2100,32 +2116,19 @@ void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
*yscale = _glfw.x11.contentScaleY;
}
double _glfwPlatformGetDoubleClickInterval(_GLFWwindow* window)
{
return 0.5;
}
void _glfwPlatformIconifyWindow(_GLFWwindow* window)
{
if (window->x11.overrideRedirect)
{
// Override-redirect windows cannot be iconified or restored, as those
// tasks are performed by the window manager
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Iconification of full screen windows requires a WM that supports EWMH full screen");
return;
}
XIconifyWindow(_glfw.x11.display, window->x11.handle, _glfw.x11.screen);
XFlush(_glfw.x11.display);
}
void _glfwPlatformRestoreWindow(_GLFWwindow* window)
{
if (window->x11.overrideRedirect)
{
// Override-redirect windows cannot be iconified or restored, as those
// tasks are performed by the window manager
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Iconification of full screen windows requires a WM that supports EWMH full screen");
return;
}
if (_glfwPlatformWindowIconified(window))
{
XMapWindow(_glfw.x11.display, window->x11.handle);
@@ -2191,7 +2194,7 @@ void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
int _glfwPlatformWindowBell(_GLFWwindow* window)
{
return XkbBell(_glfw.x11.display, window->x11.handle, 100, (Atom)0) ? GLFW_TRUE : GLFW_FALSE;
return XkbBell(_glfw.x11.display, window->x11.handle, 100, (Atom)0) ? true : false;
}
void _glfwPlatformFocusWindow(_GLFWwindow* window)
@@ -2223,10 +2226,14 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
}
else
{
if (!window->resizable)
updateNormalHints(window, width, height);
XMoveResizeWindow(_glfw.x11.display, window->x11.handle,
xpos, ypos, width, height);
}
XFlush(_glfw.x11.display);
return;
}
@@ -2235,16 +2242,20 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
_glfwInputWindowMonitor(window, monitor);
updateNormalHints(window, width, height);
updateWindowMode(window);
if (window->monitor)
{
XMapRaised(_glfw.x11.display, window->x11.handle);
if (waitForVisibilityNotify(window))
acquireMonitor(window);
if (!_glfwPlatformWindowVisible(window))
{
XMapRaised(_glfw.x11.display, window->x11.handle);
waitForVisibilityNotify(window);
}
updateWindowMode(window);
acquireMonitor(window);
}
else
{
updateWindowMode(window);
XMoveResizeWindow(_glfw.x11.display, window->x11.handle,
xpos, ypos, width, height);
}
@@ -2261,6 +2272,11 @@ int _glfwPlatformWindowFocused(_GLFWwindow* window)
return window->x11.handle == focused;
}
int _glfwPlatformWindowOccluded(_GLFWwindow* window)
{
return false;
}
int _glfwPlatformWindowIconified(_GLFWwindow* window)
{
return getWindowState(window) == IconicState;
@@ -2277,7 +2293,11 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
{
Atom* states;
unsigned long i;
GLFWbool maximized = GLFW_FALSE;
bool maximized = false;
if (!_glfw.x11.NET_WM_STATE ||
!_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT ||
!_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
return maximized;
const unsigned long count =
_glfwGetWindowPropertyX11(window->x11.handle,
_glfw.x11.NET_WM_STATE,
@@ -2289,7 +2309,7 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
if (states[i] == _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT ||
states[i] == _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
{
maximized = GLFW_TRUE;
maximized = true;
break;
}
}
@@ -2312,32 +2332,32 @@ int _glfwPlatformWindowHovered(_GLFWwindow* window)
if (!XQueryPointer(_glfw.x11.display, w,
&root, &w, &rootX, &rootY, &childX, &childY, &mask))
{
return GLFW_FALSE;
return false;
}
if (w == window->x11.handle)
return GLFW_TRUE;
return true;
}
return GLFW_FALSE;
return false;
}
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
{
if (!window->x11.transparent)
return GLFW_FALSE;
return false;
return XGetSelectionOwner(_glfw.x11.display, _glfw.x11.NET_WM_CM_Sx) != None;
}
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, bool enabled)
{
int width, height;
_glfwPlatformGetWindowSize(window, &width, &height);
updateNormalHints(window, width, height);
}
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, bool enabled)
{
if (enabled)
{
@@ -2368,7 +2388,7 @@ void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
}
}
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, bool enabled)
{
if (!_glfw.x11.NET_WM_STATE || !_glfw.x11.NET_WM_STATE_ABOVE)
return;
@@ -2464,23 +2484,29 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
PropModeReplace, (unsigned char*) &value, 1);
}
GLFWbool
static inline unsigned
dispatch_x11_queued_events(void) {
unsigned dispatched = 0;
while (XQLength(_glfw.x11.display) > 0)
{
XEvent event;
XNextEvent(_glfw.x11.display, &event);
processEvent(&event);
dispatched += 1;
}
return dispatched;
}
static unsigned
_glfwDispatchX11Events(void) {
_GLFWwindow* window;
GLFWbool dispatched = GLFW_FALSE;
unsigned dispatched = 0;
#if defined(__linux__)
_glfwDetectJoystickConnectionLinux();
#endif
XPending(_glfw.x11.display);
while (XQLength(_glfw.x11.display))
{
XEvent event;
XNextEvent(_glfw.x11.display, &event);
processEvent(&event);
dispatched = GLFW_TRUE;
}
dispatched += dispatch_x11_queued_events();
window = _glfw.x11.disabledCursorWindow;
if (window)
@@ -2498,6 +2524,8 @@ _glfwDispatchX11Events(void) {
}
XFlush(_glfw.x11.display);
// XFlush can cause events to be queued
dispatched += dispatch_x11_queued_events();
return dispatched;
}
@@ -2521,16 +2549,6 @@ void _glfwPlatformWaitEventsTimeout(double timeout)
void _glfwPlatformPostEmptyEvent(void)
{
XEvent event;
memset(&event, 0, sizeof(event));
event.type = ClientMessage;
event.xclient.window = _glfw.x11.helperWindowHandle;
event.xclient.format = 32; // Data is 32-bit longs
event.xclient.message_type = _glfw.x11.NULL_;
XSendEvent(_glfw.x11.display, _glfw.x11.helperWindowHandle, False, 0, &event);
XFlush(_glfw.x11.display);
while (write(_glfw.x11.eventLoopData.wakeupFds[1], "w", 1) < 0 && errno == EINTR);
}
@@ -2594,39 +2612,40 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
{
cursor->x11.handle = _glfwCreateCursorX11(image, xhot, yhot);
if (!cursor->x11.handle)
return GLFW_FALSE;
return false;
return GLFW_TRUE;
return true;
}
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, GLFWCursorShape shape)
{
int native = 0;
if (shape == GLFW_ARROW_CURSOR)
native = XC_left_ptr;
else if (shape == GLFW_IBEAM_CURSOR)
native = XC_xterm;
else if (shape == GLFW_CROSSHAIR_CURSOR)
native = XC_crosshair;
else if (shape == GLFW_HAND_CURSOR)
native = XC_hand1;
else if (shape == GLFW_HRESIZE_CURSOR)
native = XC_sb_h_double_arrow;
else if (shape == GLFW_VRESIZE_CURSOR)
native = XC_sb_v_double_arrow;
else
return GLFW_FALSE;
#define C(name, val) case name: native = val; break;
switch(shape) {
C(GLFW_ARROW_CURSOR, XC_arrow);
C(GLFW_IBEAM_CURSOR, XC_xterm);
C(GLFW_CROSSHAIR_CURSOR, XC_crosshair);
C(GLFW_HAND_CURSOR, XC_hand2);
C(GLFW_HRESIZE_CURSOR, XC_sb_h_double_arrow);
C(GLFW_VRESIZE_CURSOR, XC_sb_v_double_arrow);
C(GLFW_NW_RESIZE_CURSOR, XC_top_left_corner);
C(GLFW_NE_RESIZE_CURSOR, XC_top_right_corner);
C(GLFW_SW_RESIZE_CURSOR, XC_bottom_left_corner);
C(GLFW_SE_RESIZE_CURSOR, XC_bottom_right_corner);
case GLFW_INVALID_CURSOR:
return false;
}
#undef C
cursor->x11.handle = XCreateFontCursor(_glfw.x11.display, native);
if (!cursor->x11.handle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to create standard cursor");
return GLFW_FALSE;
return false;
}
return GLFW_TRUE;
return true;
}
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
@@ -2667,6 +2686,29 @@ const char* _glfwPlatformGetClipboardString(void)
return getSelectionString(_glfw.x11.CLIPBOARD);
}
void _glfwPlatformSetPrimarySelectionString(const char* string)
{
free(_glfw.x11.primarySelectionString);
_glfw.x11.primarySelectionString = _glfw_strdup(string);
XSetSelectionOwner(_glfw.x11.display,
_glfw.x11.PRIMARY,
_glfw.x11.helperWindowHandle,
CurrentTime);
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.PRIMARY) !=
_glfw.x11.helperWindowHandle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to become owner of primary selection");
}
}
const char* _glfwPlatformGetPrimarySelectionString(void)
{
return getSelectionString(_glfw.x11.PRIMARY);
}
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
{
if (!_glfw.vk.KHR_surface)
@@ -2705,7 +2747,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"X11: Vulkan instance missing VK_KHR_xcb_surface extension");
return GLFW_FALSE;
return false;
}
xcb_connection_t* connection = XGetXCBConnection(_glfw.x11.display);
@@ -2713,7 +2755,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to retrieve XCB connection");
return GLFW_FALSE;
return false;
}
return vkGetPhysicalDeviceXcbPresentationSupportKHR(device,
@@ -2731,7 +2773,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"X11: Vulkan instance missing VK_KHR_xlib_surface extension");
return GLFW_FALSE;
return false;
}
return vkGetPhysicalDeviceXlibPresentationSupportKHR(device,
@@ -2838,32 +2880,14 @@ GLFWAPI Window glfwGetX11Window(GLFWwindow* handle)
return window->x11.handle;
}
GLFWAPI void glfwSetX11SelectionString(const char* string)
{
_GLFW_REQUIRE_INIT();
free(_glfw.x11.primarySelectionString);
_glfw.x11.primarySelectionString = _glfw_strdup(string);
XSetSelectionOwner(_glfw.x11.display,
_glfw.x11.PRIMARY,
_glfw.x11.helperWindowHandle,
CurrentTime);
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.PRIMARY) !=
_glfw.x11.helperWindowHandle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to become owner of primary selection");
}
}
GLFWAPI const char* glfwGetX11SelectionString(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return getSelectionString(_glfw.x11.PRIMARY);
}
GLFWAPI int glfwGetXKBScancode(const char* keyName, GLFWbool caseSensitive) {
GLFWAPI int glfwGetXKBScancode(const char* keyName, bool caseSensitive) {
return glfw_xkb_keysym_from_name(keyName, caseSensitive);
}
GLFWAPI unsigned long long glfwDBusUserNotify(const char *app_name, const char* icon, const char *summary, const char *body, const char *action_name, int32_t timeout, GLFWDBusnotificationcreatedfun callback, void *data) {
return glfw_dbus_send_user_notification(app_name, icon, summary, body, action_name, timeout, callback, data);
}
GLFWAPI void glfwDBusSetUserNotificationHandler(GLFWDBusnotificationactivatedfun handler) {
glfw_dbus_set_user_notification_activated_handler(handler);
}

45
glfw/xkb_glfw.c vendored
View File

@@ -46,6 +46,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); \
@@ -134,30 +136,30 @@ glfw_xkb_sym_for_key(int key) {
#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, ...) {\
@@ -202,17 +204,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 +257,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 +268,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 +292,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 +326,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;
@@ -363,7 +366,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 +413,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 +424,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 +437,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 +500,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(

18
glfw/xkb_glfw.h vendored
View File

@@ -67,8 +67,8 @@ typedef struct {
#ifdef _GLFW_X11
int32_t keyboard_device_id;
GLFWbool available;
GLFWbool detectable;
bool available;
bool detectable;
int majorOpcode;
int eventBase;
int errorBase;
@@ -79,18 +79,18 @@ typedef struct {
} _GLFWXKBData;
#ifdef _GLFW_X11
GLFWbool glfw_xkb_set_x11_events_mask(void);
GLFWbool glfw_xkb_update_x11_keyboard_id(_GLFWXKBData *xkb);
bool glfw_xkb_set_x11_events_mask(void);
bool glfw_xkb_update_x11_keyboard_id(_GLFWXKBData *xkb);
#endif
void glfw_xkb_release(_GLFWXKBData *xkb);
GLFWbool glfw_xkb_create_context(_GLFWXKBData *xkb);
GLFWbool glfw_xkb_compile_keymap(_GLFWXKBData *xkb, const char *map_str);
bool glfw_xkb_create_context(_GLFWXKBData *xkb);
bool glfw_xkb_compile_keymap(_GLFWXKBData *xkb, const char *map_str);
void glfw_xkb_update_modifiers(_GLFWXKBData *xkb, xkb_mod_mask_t depressed, xkb_mod_mask_t latched, xkb_mod_mask_t locked, xkb_layout_index_t base_group, xkb_layout_index_t latched_group, xkb_layout_index_t locked_group);
GLFWbool glfw_xkb_should_repeat(_GLFWXKBData *xkb, xkb_keycode_t scancode);
bool glfw_xkb_should_repeat(_GLFWXKBData *xkb, xkb_keycode_t scancode);
const char* glfw_xkb_keysym_name(xkb_keysym_t sym);
xkb_keysym_t glfw_xkb_sym_for_key(int key);
void glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t scancode, int action);
int glfw_xkb_keysym_from_name(const char *name, GLFWbool case_sensitive);
int glfw_xkb_keysym_from_name(const char *name, bool case_sensitive);
void glfw_xkb_update_ime_state(_GLFWwindow *w, _GLFWXKBData *xkb, int which, int a, int b, int c, int d);
void glfw_xkb_key_from_ime(KeyEvent *ev, GLFWbool handled_by_ime, GLFWbool failed);
void glfw_xkb_key_from_ime(KeyEvent *ev, bool handled_by_ime, bool failed);

View File

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

View File

View File

@@ -0,0 +1,88 @@
/*
* Copyright (C) 2017 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#pragma once
#include "data-types.h"
#if defined(_MSC_VER)
#define ISWINDOWS
#define STDCALL __stdcall
#ifndef ssize_t
#include <BaseTsd.h>
typedef SSIZE_T ssize_t;
#ifndef SSIZE_MAX
#if defined(_WIN64)
#define SSIZE_MAX _I64_MAX
#else
#define SSIZE_MAX LONG_MAX
#endif
#endif
#endif
#else
#define STDCALL
#endif
#include "vector.h"
typedef uint8_t len_t;
typedef uint32_t text_t;
#define LEN_MAX UINT8_MAX
#define UTF8_ACCEPT 0
#define UTF8_REJECT 1
#define IS_LOWERCASE(x) (x) >= 'a' && (x) <= 'z'
#define IS_UPPERCASE(x) (x) >= 'A' && (x) <= 'Z'
#define LOWERCASE(x) ((IS_UPPERCASE(x)) ? (x) + 32 : (x))
#define arraysz(x) (sizeof(x)/sizeof(x[0]))
typedef struct {
text_t* src;
ssize_t src_sz;
len_t haystack_len;
len_t *positions;
double score;
ssize_t idx;
} Candidate;
typedef struct {
Candidate *haystack;
size_t haystack_count;
text_t level1[LEN_MAX], level2[LEN_MAX], level3[LEN_MAX], needle[LEN_MAX];
len_t level1_len, level2_len, level3_len, needle_len;
size_t haystack_size;
text_t *output;
size_t output_sz, output_pos;
int oom;
} GlobalData;
typedef struct {
bool output_positions;
size_t limit;
int num_threads;
text_t mark_before[128], mark_after[128], delimiter[128];
size_t mark_before_sz, mark_after_sz, delimiter_sz;
} Options;
VECTOR_OF(len_t, Positions)
VECTOR_OF(text_t, Chars)
VECTOR_OF(Candidate, Candidates)
void output_results(GlobalData *, Candidate *haystack, size_t count, Options *opts, len_t needle_len);
void* alloc_workspace(len_t max_haystack_len, GlobalData*);
void* free_workspace(void *v);
double score_item(void *v, text_t *haystack, len_t haystack_len, len_t *match_positions);
unsigned int encode_codepoint(text_t ch, char* dest);
size_t unescape(const char *src, char *dest, size_t destlen);
int cpu_count(void);
void* alloc_threads(size_t num_threads);
#ifdef ISWINDOWS
bool start_thread(void* threads, size_t i, unsigned int (STDCALL *start_routine) (void *), void *arg);
ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream);
#else
bool start_thread(void* threads, size_t i, void *(*start_routine) (void *), void *arg);
#endif
void wait_for_thread(void *threads, size_t i);
void free_threads(void *threads);

244
kittens/choose/main.c Normal file
View File

@@ -0,0 +1,244 @@
/*
* main.c
* Copyright (C) 2017 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#include "choose-data-types.h"
#include "charsets.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#ifndef ISWINDOWS
#include <unistd.h>
#endif
typedef struct {
size_t start, count;
void *workspace;
len_t max_haystack_len;
bool started;
GlobalData *global;
} JobData;
static unsigned int STDCALL
run_scoring(JobData *job_data) {
GlobalData *global = job_data->global;
for (size_t i = job_data->start; i < job_data->start + job_data->count; i++) {
global->haystack[i].score = score_item(job_data->workspace, global->haystack[i].src, global->haystack[i].haystack_len, global->haystack[i].positions);
}
return 0;
}
static void*
run_scoring_pthreads(void *job_data) {
run_scoring((JobData*)job_data);
return NULL;
}
#ifdef ISWINDOWS
#define START_FUNC run_scoring
#else
#define START_FUNC run_scoring_pthreads
#endif
static JobData*
create_job(size_t i, size_t blocksz, GlobalData *global) {
JobData *ans = (JobData*)calloc(1, sizeof(JobData));
if (ans == NULL) return NULL;
ans->start = i * blocksz;
if (ans->start >= global->haystack_count) ans->count = 0;
else ans->count = global->haystack_count - ans->start;
ans->max_haystack_len = 0;
for (size_t i = ans->start; i < ans->start + ans->count; i++) ans->max_haystack_len = MAX(ans->max_haystack_len, global->haystack[i].haystack_len);
if (ans->count > 0) {
ans->workspace = alloc_workspace(ans->max_haystack_len, global);
if (!ans->workspace) { free(ans); return NULL; }
}
ans->global = global;
return ans;
}
static JobData*
free_job(JobData *job) {
if (job) {
if (job->workspace) free_workspace(job->workspace);
free(job);
}
return NULL;
}
static int
run_threaded(int num_threads_asked, GlobalData *global) {
int ret = 0;
size_t i, blocksz;
size_t num_threads = MAX(1, num_threads_asked > 0 ? num_threads_asked : cpu_count());
if (global->haystack_size < 10000) num_threads = 1;
/* printf("num_threads: %lu asked: %d sysconf: %ld\n", num_threads, num_threads_asked, sysconf(_SC_NPROCESSORS_ONLN)); */
void *threads = alloc_threads(num_threads);
JobData **job_data = calloc(num_threads, sizeof(JobData*));
if (threads == NULL || job_data == NULL) { ret = 1; goto end; }
blocksz = global->haystack_count / num_threads + global->haystack_count % num_threads;
for (i = 0; i < num_threads; i++) {
job_data[i] = create_job(i, blocksz, global);
if (job_data[i] == NULL) { ret = 1; goto end; }
}
if (num_threads == 1) {
run_scoring(job_data[0]);
} else {
for (i = 0; i < num_threads; i++) {
job_data[i]->started = false;
if (job_data[i]->count > 0) {
if (!start_thread(threads, i, START_FUNC, job_data[i])) ret = 1;
else job_data[i]->started = true;
}
}
}
end:
if (num_threads > 1 && job_data) {
for (i = 0; i < num_threads; i++) {
if (job_data[i] && job_data[i]->started) wait_for_thread(threads, i);
}
}
for (i = 0; i < num_threads; i++) job_data[i] = free_job(job_data[i]);
free(job_data);
free_threads(threads);
return ret;
}
static int
run_search(Options *opts, GlobalData *global, const char * const *lines, const size_t* sizes, size_t num_lines) {
const char *linebuf = NULL;
size_t idx = 0;
ssize_t sz = 0;
int ret = 0;
Candidates candidates = {0};
Chars chars = {0};
ALLOC_VEC(text_t, chars, 8192 * 20);
if (chars.data == NULL) return 1;
ALLOC_VEC(Candidate, candidates, 8192);
if (candidates.data == NULL) { FREE_VEC(chars) return 1; }
for (size_t i = 0; i < num_lines; i++) {
sz = sizes[i];
linebuf = lines[i];
if (sz > 0) {
ENSURE_SPACE(text_t, chars, sz);
ENSURE_SPACE(Candidate, candidates, 1);
sz = decode_utf8_string(linebuf, sz, &(NEXT(chars)));
NEXT(candidates).src_sz = sz;
NEXT(candidates).haystack_len = (len_t)(MIN(LEN_MAX, sz));
global->haystack_size += NEXT(candidates).haystack_len;
NEXT(candidates).idx = idx++;
INC(candidates, 1); INC(chars, sz);
}
}
// Prepare the haystack allocating space for positions arrays and settings
// up the src pointers to point to the correct locations
Candidate *haystack = &ITEM(candidates, 0);
len_t *positions = (len_t*)calloc(SIZE(candidates), sizeof(len_t) * global->needle_len);
if (positions) {
text_t *cdata = &ITEM(chars, 0);
for (size_t i = 0, off = 0; i < SIZE(candidates); i++) {
haystack[i].positions = positions + (i * global->needle_len);
haystack[i].src = cdata + off;
off += haystack[i].src_sz;
}
global->haystack = haystack;
global->haystack_count = SIZE(candidates);
ret = run_threaded(opts->num_threads, global);
if (ret == 0) output_results(global, haystack, SIZE(candidates), opts, global->needle_len);
else { REPORT_OOM; }
} else { ret = 1; REPORT_OOM; }
FREE_VEC(chars); free(positions); FREE_VEC(candidates);
return ret;
}
static size_t
copy_unicode_object(PyObject *src, text_t *dest, size_t dest_sz) {
PyUnicode_READY(src);
int kind = PyUnicode_KIND(src);
void *data = PyUnicode_DATA(src);
size_t len = PyUnicode_GetLength(src);
for (size_t i = 0; i < len && i < dest_sz; i++) {
dest[i] = PyUnicode_READ(kind, data, i);
}
return len;
}
static PyObject*
match(PyObject *self, PyObject *args) {
(void)(self);
int output_positions;
unsigned long limit;
PyObject *lines, *levels, *needle, *mark_before, *mark_after, *delimiter;
Options opts = {0};
GlobalData global = {0};
if (!PyArg_ParseTuple(args, "O!O!UpkiUUU",
&PyList_Type, &lines, &PyTuple_Type, &levels, &needle,
&output_positions, &limit, &opts.num_threads,
&mark_before, &mark_after, &delimiter
)) return NULL;
opts.output_positions = output_positions ? true : false;
opts.limit = limit;
global.level1_len = copy_unicode_object(PyTuple_GET_ITEM(levels, 0), global.level1, arraysz(global.level1));
global.level2_len = copy_unicode_object(PyTuple_GET_ITEM(levels, 1), global.level2, arraysz(global.level2));
global.level3_len = copy_unicode_object(PyTuple_GET_ITEM(levels, 2), global.level3, arraysz(global.level3));
global.needle_len = copy_unicode_object(needle, global.needle, arraysz(global.needle));
opts.mark_before_sz = copy_unicode_object(mark_before, opts.mark_before, arraysz(opts.mark_before));
opts.mark_after_sz = copy_unicode_object(mark_after, opts.mark_after, arraysz(opts.mark_after));
opts.delimiter_sz = copy_unicode_object(delimiter, opts.delimiter, arraysz(opts.delimiter));
size_t num_lines = PyList_GET_SIZE(lines);
char **clines = malloc(sizeof(char*) * num_lines);
if (!clines) { return PyErr_NoMemory(); }
size_t *sizes = malloc(sizeof(size_t) * num_lines);
if (!sizes) { free(clines); clines = NULL; return PyErr_NoMemory(); }
for (size_t i = 0; i < num_lines; i++) {
clines[i] = PyBytes_AS_STRING(PyList_GET_ITEM(lines, i));
sizes[i] = PyBytes_GET_SIZE(PyList_GET_ITEM(lines, i));
}
Py_BEGIN_ALLOW_THREADS;
run_search(&opts, &global, (const char* const *)clines, sizes, num_lines);
Py_END_ALLOW_THREADS;
free(clines); free(sizes);
if (global.oom) { free(global.output); return PyErr_NoMemory(); }
if (global.output) {
PyObject *ans = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, global.output, global.output_pos);
free(global.output);
return ans;
}
Py_RETURN_NONE;
}
static PyMethodDef module_methods[] = {
{"match", match, METH_VARARGS, ""},
{NULL, NULL, 0, NULL} /* Sentinel */
};
static struct PyModuleDef module = {
.m_base = PyModuleDef_HEAD_INIT,
.m_name = "subseq_matcher", /* name of module */
.m_doc = NULL,
.m_size = -1,
.m_methods = module_methods
};
EXPORTED PyMODINIT_FUNC
PyInit_subseq_matcher(void) {
return PyModule_Create(&module);
}

72
kittens/choose/main.py Normal file
View File

@@ -0,0 +1,72 @@
#!/usr/bin/env python3
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
import sys
from ..tui.handler import Handler
from ..tui.loop import Loop
from . import subseq_matcher
def match(
input_data,
query,
threads=0,
positions=False,
level1='/',
level2='-_0123456789',
level3='.',
limit=0,
mark_before='',
mark_after='',
delimiter='\n'
):
if isinstance(input_data, str):
input_data = input_data.encode('utf-8')
if isinstance(input_data, bytes):
input_data = input_data.split(delimiter.encode('utf-8'))
else:
input_data = [x.encode('utf-8') if isinstance(x, str) else x for x in input_data]
query = query.lower()
level1 = level1.lower()
level2 = level2.lower()
level3 = level3.lower()
data = subseq_matcher.match(
input_data, (level1, level2, level3), query,
positions, limit, threads,
mark_before, mark_after, delimiter)
if data is None:
return []
return list(filter(None, data.split(delimiter or '\n')))
class ChooseHandler(Handler):
def initialize(self):
pass
def on_text(self, text, in_bracketed_paste=False):
pass
def on_key(self, key_event):
pass
def on_interrupt(self):
self.quit_loop(1)
def on_eot(self):
self.quit_loop(1)
def main(args):
loop = Loop()
handler = ChooseHandler()
loop.loop(handler)
raise SystemExit(loop.return_code)
if __name__ == '__main__':
main(sys.argv)

105
kittens/choose/output.c Normal file
View File

@@ -0,0 +1,105 @@
/*
* output.c
* Copyright (C) 2017 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#include "choose-data-types.h"
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#ifdef ISWINDOWS
#include <io.h>
#define STDOUT_FILENO 1
static inline ssize_t ms_write(int fd, const void* buf, size_t count) { return _write(fd, buf, (unsigned int)count); }
#define write ms_write
#else
#include <unistd.h>
#endif
#include <errno.h>
#define FIELD(x, which) (((Candidate*)(x))->which)
static inline bool
ensure_space(GlobalData *global, size_t sz) {
if (global->output_sz < sz + global->output_pos) {
size_t before = global->output_sz;
global->output_sz += MAX(sz, (64 * 1024));
global->output = realloc(global->output, sizeof(text_t) * global->output_sz);
if (!global->output) {
global->output_sz = before;
return false;
}
}
return true;
}
static inline void
output_text(GlobalData *global, const text_t *data, size_t sz) {
if (ensure_space(global, sz)) {
memcpy(global->output + global->output_pos, data, sizeof(text_t) * sz);
global->output_pos += sz;
}
}
static int
cmpscore(const void *a, const void *b) {
double sa = FIELD(a, score), sb = FIELD(b, score);
// Sort descending
return (sa > sb) ? -1 : ((sa == sb) ? ((int)FIELD(a, idx) - (int)FIELD(b, idx)) : 1);
}
static void
output_with_marks(GlobalData *global, Options *opts, text_t *src, size_t src_sz, len_t *positions, len_t poslen) {
size_t pos, i = 0;
for (pos = 0; pos < poslen; pos++, i++) {
output_text(global, src + i, MIN(src_sz, positions[pos]) - i);
i = positions[pos];
if (i < src_sz) {
if (opts->mark_before_sz > 0) output_text(global, opts->mark_before, opts->mark_before_sz);
output_text(global, src + i, 1);
if (opts->mark_after_sz > 0) output_text(global, opts->mark_after, opts->mark_after_sz);
}
}
i = positions[poslen - 1];
if (i + 1 < src_sz) output_text(global, src + i + 1, src_sz - i - 1);
}
static void
output_positions(GlobalData *global, len_t *positions, len_t num) {
wchar_t buf[128];
for (len_t i = 0; i < num; i++) {
int num = swprintf(buf, sizeof(buf)/sizeof(buf[0]), L"%u", positions[i]);
if (num > 0 && ensure_space(global, num + 1)) {
for (int i = 0; i < num; i++) global->output[global->output_pos++] = buf[i];
global->output[global->output_pos++] = (i == num - 1) ? ',' : ':';
}
}
}
static void
output_result(GlobalData *global, Candidate *c, Options *opts, len_t needle_len) {
if (opts->output_positions) output_positions(global, c->positions, needle_len);
if (opts->mark_before_sz > 0 || opts->mark_after_sz > 0) {
output_with_marks(global, opts, c->src, c->src_sz, c->positions, needle_len);
} else {
output_text(global, c->src, c->src_sz);
}
output_text(global, opts->delimiter, opts->delimiter_sz);
}
void
output_results(GlobalData *global, Candidate *haystack, size_t count, Options *opts, len_t needle_len) {
Candidate *c;
qsort(haystack, count, sizeof(*haystack), cmpscore);
size_t left = opts->limit > 0 ? opts->limit : count;
for (size_t i = 0; i < left; i++) {
c = haystack + i;
if (c->score > 0) output_result(global, c, opts, needle_len);
}
}

182
kittens/choose/score.c Normal file
View File

@@ -0,0 +1,182 @@
/*
* score.c
* Copyright (C) 2017 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#include "choose-data-types.h"
#include <stdlib.h>
#include <string.h>
#include <float.h>
#include <stdio.h>
typedef struct {
len_t *positions_buf; // buffer to store positions for every char in needle
len_t **positions; // Array of pointers into positions_buf
len_t *positions_count; // Array of counts for positions
len_t needle_len; // Length of the needle
len_t max_haystack_len; // Max length of a string in the haystack
len_t haystack_len; // Length of the current string in the haystack
len_t *address; // Array of offsets into the positions array
double max_score_per_char;
uint8_t *level_factors; // Array of score factors for every character in the current haystack that matches a character in the needle
text_t *level1, *level2, *level3; // The characters in the levels
len_t level1_len, level2_len, level3_len;
text_t *needle; // The current needle
text_t *haystack; //The current haystack
} WorkSpace;
void*
alloc_workspace(len_t max_haystack_len, GlobalData *global) {
WorkSpace *ans = calloc(1, sizeof(WorkSpace));
if (ans == NULL) return NULL;
ans->positions_buf = (len_t*) calloc(global->needle_len, sizeof(len_t) * max_haystack_len);
ans->positions = (len_t**)calloc(global->needle_len, sizeof(len_t*));
ans->positions_count = (len_t*)calloc(2*global->needle_len, sizeof(len_t));
ans->level_factors = (uint8_t*)calloc(max_haystack_len, sizeof(uint8_t));
if (ans->positions == NULL || ans->positions_buf == NULL || ans->positions_count == NULL || ans->level_factors == NULL) { free_workspace(ans); return NULL; }
ans->needle = global->needle;
ans->needle_len = global->needle_len;
ans->max_haystack_len = max_haystack_len;
ans->level1 = global->level1; ans->level2 = global->level2; ans->level3 = global->level3;
ans->level1_len = global->level1_len; ans->level2_len = global->level2_len; ans->level3_len = global->level3_len;
ans->address = ans->positions_count + sizeof(len_t) * global->needle_len;
for (len_t i = 0; i < global->needle_len; i++) ans->positions[i] = ans->positions_buf + i * max_haystack_len;
return ans;
}
#define NUKE(x) free(x); x = NULL;
void*
free_workspace(void *v) {
WorkSpace *w = (WorkSpace*)v;
NUKE(w->positions_buf);
NUKE(w->positions);
NUKE(w->positions_count);
NUKE(w->level_factors);
free(w);
return NULL;
}
static inline bool
has_char(text_t *text, len_t sz, text_t ch) {
for(len_t i = 0; i < sz; i++) {
if(text[i] == ch) return true;
}
return false;
}
static inline uint8_t
level_factor_for(text_t current, text_t last, WorkSpace *w) {
text_t lch = LOWERCASE(last);
if (has_char(w->level1, w->level1_len, lch)) return 90;
if (has_char(w->level2, w->level2_len, lch)) return 80;
if (IS_LOWERCASE(last) && IS_UPPERCASE(current)) return 80; // CamelCase
if (has_char(w->level3, w->level3_len, lch)) return 70;
return 0;
}
static void
init_workspace(WorkSpace *w, text_t *haystack, len_t haystack_len) {
// Calculate the positions and level_factors arrays for the specified haystack
bool level_factor_calculated = false;
memset(w->positions_count, 0, sizeof(*(w->positions_count)) * 2 * w->needle_len);
memset(w->level_factors, 0, sizeof(*(w->level_factors)) * w->max_haystack_len);
for (len_t i = 0; i < haystack_len; i++) {
level_factor_calculated = false;
for (len_t j = 0; j < w->needle_len; j++) {
if (w->needle[j] == LOWERCASE(haystack[i])) {
if (!level_factor_calculated) {
level_factor_calculated = true;
w->level_factors[i] = i > 0 ? level_factor_for(haystack[i], haystack[i-1], w) : 0;
}
w->positions[j][w->positions_count[j]++] = i;
}
}
}
w->haystack = haystack;
w->haystack_len = haystack_len;
w->max_score_per_char = (1.0 / haystack_len + 1.0 / w->needle_len) / 2.0;
}
static inline bool
has_atleast_one_match(WorkSpace *w) {
int p = -1;
bool found;
for (len_t i = 0; i < w->needle_len; i++) {
if (w->positions_count[i] == 0) return false; // All characters of the needle are not present in the haystack
found = false;
for (len_t j = 0; j < w->positions_count[i]; j++) {
if (w->positions[i][j] > p) { p = w->positions[i][j]; found = true; break; }
}
if (!found) return false; // Characters of needle not present in sequence in haystack
}
return true;
}
#define POSITION(x) w->positions[x][w->address[x]]
static inline bool
increment_address(WorkSpace *w) {
len_t pos = w->needle_len - 1;
while(true) {
w->address[pos]++;
if (w->address[pos] < w->positions_count[pos]) return true;
if (pos == 0) break;
w->address[pos--] = 0;
}
return false;
}
static inline bool
address_is_monotonic(WorkSpace *w) {
// Check if the character positions pointed to by the current address are monotonic
for (len_t i = 1; i < w->needle_len; i++) {
if (POSITION(i) <= POSITION(i-1)) return false;
}
return true;
}
static inline double
calc_score(WorkSpace *w) {
double ans = 0;
len_t distance, pos;
for (len_t i = 0; i < w->needle_len; i++) {
pos = POSITION(i);
if (i == 0) distance = pos < LEN_MAX ? pos + 1 : LEN_MAX;
else {
distance = pos - POSITION(i-1);
if (distance < 2) {
ans += w->max_score_per_char; // consecutive characters
continue;
}
}
if (w->level_factors[pos]) ans += (100 * w->max_score_per_char) / w->level_factors[pos]; // at a special location
else ans += (0.75 * w->max_score_per_char) / distance;
}
return ans;
}
static double
process_item(WorkSpace *w, len_t *match_positions) {
double highscore = 0, score;
do {
if (!address_is_monotonic(w)) continue;
score = calc_score(w);
if (score > highscore) {
highscore = score;
for (len_t i = 0; i < w->needle_len; i++) match_positions[i] = POSITION(i);
}
} while(increment_address(w));
return highscore;
}
double
score_item(void *v, text_t *haystack, len_t haystack_len, len_t *match_positions) {
WorkSpace *w = (WorkSpace*)v;
init_workspace(w, haystack, haystack_len);
if (!has_atleast_one_match(w)) return 0;
return process_item(w, match_positions);
}

View File

@@ -0,0 +1,50 @@
/*
* unix_compat.c
* Copyright (C) 2017 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#include "choose-data-types.h"
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#ifdef __APPLE__
#ifndef _SC_NPROCESSORS_ONLN
#define _SC_NPROCESSORS_ONLN 58
#endif
#endif
int
cpu_count() {
return sysconf(_SC_NPROCESSORS_ONLN);
}
void*
alloc_threads(size_t num_threads) {
return calloc(num_threads, sizeof(pthread_t));
}
bool
start_thread(void* threads, size_t i, void *(*start_routine) (void *), void *arg) {
int rc;
if ((rc = pthread_create(((pthread_t*)threads) + i, NULL, start_routine, arg))) {
fprintf(stderr, "Failed to create thread, with error: %s\n", strerror(rc));
return false;
}
return true;
}
void
wait_for_thread(void *threads, size_t i) {
pthread_join(((pthread_t*)(threads))[i], NULL);
}
void
free_threads(void *threads) {
free(threads);
}

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