Compare commits

...

2287 Commits

Author SHA1 Message Date
Kovid Goyal
fbccfb9d0d version 0.13.3 2019-01-19 14:06:53 +05:30
Kovid Goyal
9fdd8e4ae4 macOS: Fix some kittens causing 100% CPU usage 2019-01-19 14:01:36 +05:30
Kovid Goyal
6b6dea5190 ... 2019-01-19 13:51:18 +05:30
Kovid Goyal
5af551c96d macOS: Fix detection of differ
There can be a wrapper git on macOS that complains about command line
tools installation, so check that passing --help to it actually works.
2019-01-19 12:36:34 +05:30
Kovid Goyal
6761fdca1a ... 2019-01-19 12:16:44 +05:30
Kovid Goyal
725da39ecb macOS: Add aliases for lose window and new tab actions that conform to common Apple shortcuts for these actions
Fixes #1313
2019-01-19 09:18:25 +05:30
Kovid Goyal
9005fc359d Merge branch 'unjam' of https://github.com/jacwah/kitty
Fixes #1312
2019-01-18 22:23:12 +05:30
Jacob Wahlgren
33e4a44008 Unjam event loop when adding pending cocoa action
Fixes the problem reported in
https://github.com/kovidgoyal/kitty/issues/1312.
2019-01-18 17:32:22 +01:00
Kovid Goyal
3bddb9d95b Fix an exception when chaging diff context on very small diffs 2019-01-16 21:24:34 +05:30
Kovid Goyal
fa01e0b76f icat kitten: Add a --stdin option to control if image data is read from stdin
See #1308
2019-01-16 16:35:53 +05:30
Kovid Goyal
f8f188ecff Merge branch 'travis-osx' of https://github.com/stephengroat/kitty 2019-01-16 06:26:02 +05:30
Stephen G
07935d9bd3 Use brew for osx 2019-01-15 15:00:29 -08:00
Kovid Goyal
a827f4190c Merge branch 'fix_white_background_transparency' of https://github.com/Luflosi/kitty 2019-01-14 13:10:15 +05:30
Kovid Goyal
18c108ed03 macOS: Fix a regression that broke mapping of ctrl+tab
Fixes #1304
2019-01-14 10:53:31 +05:30
Kovid Goyal
2d70059f47 Document fix for #1299
Fix #1299
2019-01-14 10:12:05 +05:30
Kovid Goyal
63ff3cfb9f Merge branch 'negative_scroll_alternate_mode' of https://github.com/Luflosi/kitty 2019-01-14 10:10:22 +05:30
Kovid Goyal
ca70f22d46 Add a list of user-created kittens to the docs 2019-01-14 10:03:28 +05:30
Kovid Goyal
c247a6c0cc macOS: Ensure that when running from a bundle, the bundle kitty exe is preferred over any kitty in PATH
Fix #1280
2019-01-14 09:32:49 +05:30
Luflosi
7421a0b9e3 Apply negative scroll multiplier in alternate screen mode
Fixes kovidgoyal/kitty#1299
2019-01-14 00:11:19 +01:00
Kovid Goyal
30b5e8bf8f Merge branch 'patch-1' of https://github.com/robbyoconnor/kitty 2019-01-13 09:50:25 +05:30
Robby O'Connor
96475ce3ee Switch travis to Xenial 2019-01-11 20:53:43 -05:00
Kovid Goyal
24669fb6af Port a couple of fixes from upstream
72c3908e14
cde0aaaab1
2019-01-11 14:20:26 +05:30
Kovid Goyal
851885568f macOS: Fix dragging kitty window tabs in traditional full screen mode causing crashes
Fixes #1296
Apparently, macOS reports NaN DPI values in this scenario.

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

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

This makes it possible to configure keys as such:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Fixes:

    Linking kitty/fast_data_types ...
    kitty/freetype.c: In function ‘render_glyphs_in_cells’:
    kitty/freetype.c:514:82: warning: ‘bm.right_edge’ may be used uninitialized in this function [-Wmaybe-uninitialized]
             if (num_cells > 1 && right_edge < canvas_width && (delta = (canvas_width - right_edge) / 2) && delta > 1) {
                                                                                      ^
    kitty/freetype.c:490:21: note: ‘bm.right_edge’ was declared here
         ProcessedBitmap bm;
                         ^
2018-09-29 16:20:10 +02:00
Daniel Hahler
1d50a188c4 render_glyphs_in_cells: skip centering glyph for PUA 2018-09-29 16:19:53 +02:00
Kovid Goyal
b0d34b136f version 0.12.3 2018-09-29 09:15:40 +05:30
Kovid Goyal
7eb234c250 Move kitty.app build instructions from the FAQ to the build page 2018-09-29 08:47:30 +05:30
Daniel Hahler
d52434c0aa fixup! Handle multiple spaces after PUA glyphs
[ci skip]
2018-09-28 23:01:35 +02:00
Daniel Hahler
efc0b830cf Handle multiple spaces after PUA glyphs 2018-09-28 15:34:14 +02:00
Kovid Goyal
4a8c4c4601 Unicode input: Fix an error when searching for the string 'fir'
Fixes #1035
2018-09-28 19:01:20 +05:30
Kovid Goyal
e498cedf56 remove unused import 2018-09-27 08:52:40 +05:30
Kovid Goyal
6c8a52875e Fix #1029 2018-09-27 08:40:16 +05:30
Kovid Goyal
c1397fd366 Merge branch 'unicode_input-reverse' of https://github.com/blueyed/kitty 2018-09-27 08:35:25 +05:30
Daniel Hahler
3323ddcdef unicode_input: use reverse mode for menu selection 2018-09-26 22:50:22 +02:00
Kovid Goyal
1be394cda7 Update CHANGELOG 2018-09-26 19:54:42 +05:30
Kovid Goyal
f292092ffc ... 2018-09-26 19:47:53 +05:30
Kovid Goyal
b82e74f99a Fix for kitty window not being rendered until moved/resized on macOS Mojave
Fixes #887
2018-09-26 19:43:04 +05:30
Kovid Goyal
9b293ad66a Add some more explanation of why TERM is important 2018-09-24 09:28:21 +05:30
Kovid Goyal
3a4420f2d3 version 0.12.2 2018-09-24 05:26:11 +05:30
Kovid Goyal
1eb8d6e845 Merge branch 'doc-fix' of https://github.com/nicoulaj/kitty 2018-09-23 08:49:15 +05:30
Julien Nicoulaud
e2f97dc44a Fix broken links 2018-09-22 20:22:15 +02:00
Kovid Goyal
ea9af96d2b Fix using focus_follows_mouse causing text selection with the mouse to malfunction when using multiple kitty windows
Fixes #1002
2018-09-22 18:15:03 +05:30
Kovid Goyal
e4033d997c Merge branch 'prev_' of https://github.com/Luflosi/kitty 2018-09-22 17:28:53 +05:30
Luflosi
bc38357193 Add prev_tab and prev_window as aliases for previous_tab and previous_window 2018-09-22 13:24:51 +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
Kovid Goyal
62cb035afe Remote control: Fix the `focus_window` command not focusing the top-level OS window of the specified kitty window
Fixes #1003
2018-09-22 12:17:35 +05:30
Kovid Goyal
7a8bc6b5d2 Fix #1001 2018-09-21 12:26:44 +05:30
Kovid Goyal
0d86ac23bb Merge branch 'ime' of https://github.com/martinetd/kitty 2018-09-21 09:28:56 +05:30
Dominique Martinet
897fd9486e glfw/ibus input: use text from ime event instead of global
When a key is pressed, text is generated from xkb and attached to the
global key_event variable.
If another key is pressed before ibus replies, this text in global
variable would be overwritten before the processed reply comes in and
the wrong character would be input, as shown in logs with
--debug-keyboard:

Press scancode: 0x19 clean_sym: w composed_sym: w text: w mods: numlock glfw_key: 87 (W) xkb_key: 119 (w)
↳ to IBUS: keycode: 0x11 keysym: 0x77 (w) mods: numlock
Press scancode: 0x20 clean_sym: o composed_sym: o text: o mods: numlock glfw_key: 79 (O) xkb_key: 111 (o)
↳ to IBUS: keycode: 0x18 keysym: 0x6f (o) mods: numlockIBUS processed scancode: 0x19 release: 0 handled: 0
From IBUS: scancode: 0x19 name: w is_release: 0
↳ to application: glfw_keycode: 0x57 (W) keysym: 0x77 (w) action: PRESS mods: numlock  text: o
on_key_input: glfw key: 87 native_code: 0x77 action: PRESS mods: 0x0 text: 'o' state: 0 sent text to child
IBUS processed scancode: 0x20 release: 0 handled: 0
From IBUS: scancode: 0x20 name: o is_release: 0
↳ to application: glfw_keycode: 0x4f (O) keysym: 0x6f (o) action: PRESS mods: numlock  text: o
on_key_input: glfw key: 79 native_code: 0x6f action: PRESS mods: 0x0 text: 'o' state: 0 sent text to child

Since the whole event is memcpy'd we can just use the text from the
event attached to the reply instead.
2018-09-21 07:34:01 +09:00
Kovid Goyal
39d3d093c4 ... 2018-09-20 09:10:57 +05:30
Kovid Goyal
3f0b52bef4 Workaround for broken editors like nano that cannot handle newlines in pasted text
Fixes #994
2018-09-20 09:08:29 +05:30
Kovid Goyal
4a04f27fde Fix #991 2018-09-19 19:58:23 +05:30
Kovid Goyal
5fb02c0439 When mapping the new_tab action allow specifying that the tab should open next to the current tab instead of at the end of the tabs list
Fixes #979
2018-09-19 19:43:41 +05:30
Kovid Goyal
edfb4ef3f1 Merge branch 'master' of https://github.com/esell/kitty 2018-09-19 18:13:20 +05:30
Kovid Goyal
f037923b00 Document the basic process for creating custom kittens. Fixes #975 2018-09-19 12:55:50 +05:30
Kovid Goyal
424aafb514 Merge branch 'fix_sgr_bold' of https://github.com/martinetd/kitty 2018-09-19 08:07:00 +05:30
Dominique Martinet
1b64167a3e cursor_as_sgr: fix bold/dim
The old code would print "\e[22m" if either bold or dim was unset, which
is the "normal, neither bold nor dim" control sequence.

Print that only if neither are set, and instead print "1" and "2" (bold,
dim) values individually.
2018-09-19 07:04:01 +09:00
esell
a9a86e4604 Add option to enable custom cursor on macos 2018-09-18 10:56:26 -06:00
Kovid Goyal
1dc7c23b2f Merge branch 'bash_completion' of https://github.com/martinetd/kitty 2018-09-18 06:19:24 +05:30
Dominique Martinet
5bdcfbc2ce bash completion: make complete helper start with _
It is standard to start complete helpers with underscore to avoid
clobbering the function namespace ; like other shells do.
It is ironic for a completion helper to make completion less agreable...
2018-09-18 09:10:47 +09:00
Kovid Goyal
74e9bf4f31 Another sentence worth of documentation 2018-09-17 06:42:20 +05:30
Kovid Goyal
0652529839 Remove dead code 2018-09-12 21:44:59 +05:30
Kovid Goyal
772d6597a9 macOS: Add an option :opt:macos_traditional_fullscreen to make full-screening of kitty windows much faster, but less pretty.
See #911
2018-09-12 21:27:49 +05:30
Kovid Goyal
4e99194022 Document platform fullscreen shortcut on macOS 2018-09-12 20:43:22 +05:30
Kovid Goyal
f0ff2f4ea7 Fix a bug causing incorrect line ordering when viewing the scrollback buffer if the scrollback buffer is full
Fixes #960
2018-09-12 20:31:09 +05:30
Kovid Goyal
d583c533c2 Linux: Fix window icon not set on X11 for the first OS window
Fix #961
2018-09-12 18:29:06 +05:30
Kovid Goyal
ec1f219850 macOS: Make full screening of kitty much faster by using the "traditional full screen" mode of cocoa, similar to iTerm and MacVim
Hopefully workaround a bug in glfw that causes crashes when unplugging
monitors with full screen windows.

Fixes #911
Fixes #898
2018-09-12 15:45:08 +05:30
Kovid Goyal
21d586cc86 macOS: Fix resizing semi-transparent windows causing the windows to be invisible during the resize
Fixes #941
Workaround for  https://github.com/glfw/glfw/issues/1251
2018-09-12 10:44:24 +05:30
Kovid Goyal
8f7139d48f Also respond to a terminfo query for "name" in addition to "TN" 2018-09-11 21:41:50 +05:30
Kovid Goyal
cfb6dae04d ... 2018-09-11 17:51:06 +05:30
Kovid Goyal
bceac3ee0b ... 2018-09-11 09:58:26 +05:30
Kovid Goyal
38d6edb0ca Merge branch 'macos-thicken-font' of https://github.com/tbodt/kitty 2018-09-11 09:57:28 +05:30
Kovid Goyal
1b41a3bcee ... 2018-09-11 08:26:31 +05:30
Kovid Goyal
c54f934f6e Merge branch 'patch-1' of https://github.com/tanrax/kitty 2018-09-11 08:25:22 +05:30
Theodore Dubois
94052bb712 Add option to increase font thickness on macOS 2018-09-10 19:30:29 -07:00
Andros Fenollosa
7eb1dcc7ee Fixbug Gnome cache 2018-09-10 18:44:34 +02:00
Andros Fenollosa
626fbe827e Add local icon 2018-09-10 18:41:07 +02:00
Kovid Goyal
28c154ecf0 typo 2018-09-10 21:58:15 +05:30
Kovid Goyal
8176f661ea macOS: Fix small leak in glyph rendering code 2018-09-10 21:41:26 +05:30
Kovid Goyal
0195e7f841 Wayland: Add support for animated cursors 2018-09-10 11:54:22 +05:30
Kovid Goyal
141b8a1481 Update glfw from upstream 2018-09-10 09:51:06 +05:30
Kovid Goyal
be3ab90cff Add a reference to piping to the index page 2018-09-10 08:19:14 +05:30
Kovid Goyal
9782f16635 Support os_window as a destination for the pipe function 2018-09-10 08:10:50 +05:30
Kovid Goyal
6930edfd8a ... 2018-09-10 08:08:16 +05:30
Kovid Goyal
6b1bec6550 Add a FAQ entry about global hotkey access to kitty 2018-09-10 07:57:33 +05:30
Andros Fenollosa
dac0304815 Update binary.rst 2018-09-09 20:08:12 +02:00
Andros Fenollosa
cfcf81b5fb Update binary.rst 2018-09-09 20:06:56 +02:00
Kovid Goyal
f072a02215 ... 2018-09-09 21:08:11 +05:30
Kovid Goyal
5f6e21da9b Fix kitty @set-colors not working for tab backgrounds when using the fade tabbar style
Fixes #937
2018-09-09 19:41:32 +05:30
Kovid Goyal
b9b38a4ec1 A new pipe function that can be used to pipe the contents of the screen and scrollback buffer to any desired program running in a new window, tab or overlay window. 2018-09-09 18:29:59 +05:30
Kovid Goyal
e5a7ba4f22 Allow viewing the current contents of the alternate screen in a new window.
Fixes #933
2018-09-09 15:32:05 +05:30
Kovid Goyal
1dcf3f2afb ... 2018-09-09 14:32:07 +05:30
Kovid Goyal
2ec84969dd Fix drag-scrolling not working when the mouse leaves the window confines
Fixes #917
2018-09-09 14:30:32 +05:30
Kovid Goyal
a08b945124 Forgot to revert test 2018-09-09 14:02:46 +05:30
Kovid Goyal
16f712fbaa Revert the wide-character backspace patch
Fixes #875
2018-09-09 13:51:15 +05:30
Kovid Goyal
1f63ff1d41 Have the kitty --title flag apply to all windows created using kitty --session
Fixes #921
2018-09-09 10:49:20 +05:30
Kovid Goyal
49d8f4689f ... 2018-09-09 10:24:01 +05:30
Kovid Goyal
e1f993938a Add a new kitty --start-as command line flag to start kitty fullscreen/maximized/minimized.
This obsoletes the --start-in-fullscreen flag introduced in the previous release
which has been removed since it has only existed for a few days.

Fixes #935
2018-09-09 10:23:48 +05:30
Kovid Goyal
ab65b9b2fb Do not convert bitmaps when loading a glyph to access its metrics 2018-09-09 09:46:19 +05:30
Kovid Goyal
f7a621f89f Use bitmap pitch to iterate over pixels 2018-09-09 09:42:51 +05:30
Kovid Goyal
b808a05e5e Clean up monochrome bitmap support code 2018-09-09 08:33:32 +05:30
Kovid Goyal
72c37c519d ... 2018-09-09 08:23:59 +05:30
Kovid Goyal
af4b072b29 Merge branch 'master' of https://github.com/isaz/kitty 2018-09-09 08:20:32 +05:30
ismed
739ed906f0 Use the old FT_Bitmap_New for backward compatibility 2018-09-08 21:07:38 +01:00
ismed
9fd462077a Add support for embedded bitmap glyphs 2018-09-08 20:22:48 +01:00
Kovid Goyal
cb3671343e Implement directional movement of windows 2018-09-08 23:51:09 +05:30
Kovid Goyal
b18b705632 Fix overlay window handling when witching to neighboring windows 2018-09-08 23:31:16 +05:30
Kovid Goyal
9963e78636 Linux: Ensure that the python embedded in the kitty binary build always uses UTF-8 mode
Fixes #924
2018-09-08 23:03:36 +05:30
Kovid Goyal
e39635ea16 Add a new `neighboring_window` function to switch to neighboring windows in the current layout, similar to window movement in vim
Fixes #916
2018-09-08 08:59:11 +05:30
Kovid Goyal
9329b2c202 Allow using "all" as "*" for enabled_layouts 2018-09-08 08:22:37 +05:30
Kovid Goyal
791f70e5a2 API to get neighbors from the current layout 2018-09-08 08:09:35 +05:30
Kovid Goyal
8272c4a429 Fix #929 2018-09-08 06:28:30 +05:30
Kovid Goyal
f0357b061e Add a new `last_used_layout` function that can be mapped to a shortcut to switch to the previously used window layout
Fixes #870
2018-09-08 05:56:02 +05:30
Kovid Goyal
7438e0e997 version 0.12.1 2018-09-08 05:22:02 +05:30
Kovid Goyal
cca672e536 typo 2018-09-07 16:24:29 +05:30
Kovid Goyal
0fa12a687d Linux: Turn off IME unless the GLFW_IM_MODULE=ibus env var is set 2018-09-07 16:07:01 +05:30
Kovid Goyal
d2b900c77f Changelog cleanups 2018-09-07 15:38:04 +05:30
Kovid Goyal
21242d9144 ... 2018-09-07 15:30:36 +05:30
Kovid Goyal
03fd138b63 Linux: Fix crash with some nvidia drivers when creating tabs in the first top level-window after creating a second top-level window.
Fixes #873
The wrong window's OpenGL context was current when creating the tabs.
2018-09-07 15:23:10 +05:30
Kovid Goyal
1eeaef6dbb Get rid of extra global variable 2018-09-07 14:53:29 +05:30
Kovid Goyal
b9a93b68c4 ... 2018-09-07 11:37:33 +05:30
Kovid Goyal
e3728942dc Fix a small memory leak when creating a new child process 2018-09-07 11:35:00 +05:30
Kovid Goyal
7f0674ac27 Fix backspacing of wide characters in wide-character unaware programs not working
Fixes #875
2018-09-07 10:08:25 +05:30
Kovid Goyal
60fcf7ab3d Merge branch 'prev_tab_default_macos' of https://github.com/Luflosi/kitty 2018-09-07 06:53:24 +05:30
Luflosi
ee82a6ff18 Make ctrl+shift+tab previous_tab by default on macOS 2018-09-06 22:43:36 +02:00
Kovid Goyal
bac5e402b7 Fix #890 2018-09-06 21:25:29 +05:30
Kovid Goyal
732108109e Nicer error message when sphinx-build is not in PATH 2018-09-06 21:23:03 +05:30
Kovid Goyal
ab3b86d65b Merge branch 'void' of https://github.com/SolitudeSF/kitty 2018-09-06 21:11:03 +05:30
Kovid Goyal
d4d63506e1 Fix pre-allocation of the full history buffer
Also map negative scrollback numbers to (effectively) infinite
scrollback.
2018-09-06 21:06:31 +05:30
SolitudeSF
3ad69f8ba3 Add link for the Void Linux package 2018-09-06 18:36:29 +03:00
Kovid Goyal
9fd50a6ac0 ... 2018-09-06 20:26:51 +05:30
Kovid Goyal
9b5c8a18d4 Merge branch 'master' of https://github.com/eigengrau/kitty 2018-09-06 18:29:06 +05:30
Kovid Goyal
9f3112ca56 Merge branch 'spelling' of https://github.com/EdwardBetts/kitty 2018-09-06 18:27:02 +05:30
Kovid Goyal
aa9de47da3 Support compose sequences with no symbol
Compose sequences can be defined without an associated symbol. To test for
completeness, we now also rely on XKB’s reported compose state.

Fixes #880.
2018-09-06 14:53:16 +02:00
Edward Betts
5eaeda4402 Correct spelling mistakes. 2018-09-06 12:07:09 +01:00
Kovid Goyal
ecb03d7dba ... 2018-09-06 11:58:43 +05:30
Kovid Goyal
88612d3691 Better error message when font size is too large 2018-09-06 11:52:48 +05:30
Kovid Goyal
2c0e70a423 Fix #868 2018-09-06 11:49:30 +05:30
Kovid Goyal
d6b70f10d3 Cross-linking options in the docs 2018-09-06 11:02:53 +05:30
Kovid Goyal
40b01fb702 Add a note about using an alias for icat 2018-09-06 10:27:13 +05:30
Kovid Goyal
89222d93f4 Change legacy kitty icat reference 2018-09-06 10:20:23 +05:30
Kovid Goyal
b3db3e5732 Fix completion of paths with spaces 2018-09-06 09:47:36 +05:30
Kovid Goyal
b45161ecc3 zsh completion: Eliminate common prefix when completing file names 2018-09-06 09:46:04 +05:30
Kovid Goyal
d4fc0af7de Cleanup up path completions 2018-09-06 09:34:25 +05:30
Kovid Goyal
5ef8cce1d7 Fix filenames not being completed for the diff kitten 2018-09-06 07:50:07 +05:30
Kovid Goyal
c98a147f94 Add changelog entry 2018-09-06 07:05:41 +05:30
Kovid Goyal
e9975cb7eb Merge branch 'fish-completion' of https://github.com/scorphus/kitty 2018-09-06 07:04:54 +05:30
Kovid Goyal
33f0ac83c1 Wayland: Allow using the --class to set the app id
Fixes #862
2018-09-06 06:54:38 +05:30
Kovid Goyal
3bd45966c6 diff kitten: Fix spurious traceback on exit when pygments is missing
Fixes #863
2018-09-06 06:05:08 +05:30
Pablo S. Blum de Aguiar
1b7244f3c8 Completion for fish 2018-09-05 22:33:39 +02:00
Kovid Goyal
1949f3c3d5 Wayland fix self copy detection across multiple processes 2018-09-05 21:45:32 +05:30
Kovid Goyal
6a51ce5dc4 Wayland: Work on supporting drop of file paths 2018-09-05 21:41:47 +05:30
Kovid Goyal
c0c8e1ce5e Fill up the rest of the v1 data_source listener struct 2018-09-05 20:04:38 +05:30
Kovid Goyal
6a3d6191bd Implement the rest of the the data_offer listener callbacks 2018-09-05 19:58:55 +05:30
Kovid Goyal
b2aa07d29f Wayland: Fix missing data source canceled listener 2018-09-05 19:37:55 +05:30
Kovid Goyal
c84fb68bf8 Wayland: fix copy/pasting into self 2018-09-05 19:23:42 +05:30
Kovid Goyal
128b9e1cd0 Wayland: Implement support for clipboard copy/paste
Fix #855
2018-09-05 17:54:26 +05:30
Kovid Goyal
bbe8bcb28d Fix a regression that broke layout resizing
Fixes #860
2018-09-05 10:51:08 +05:30
Kovid Goyal
6dc9c22543 Remove unnecessary use of globals 2018-09-05 10:48:23 +05:30
Kovid Goyal
59f5781f19 Merge branch 'patch-1' of https://github.com/skorokithakis/kitty 2018-09-05 10:41:42 +05:30
Stavros Korokithakis
d61fb9cc42 Add sentence about layouts using windows 2018-09-05 08:08:31 +03:00
Kovid Goyal
ace052ee70 Move data device initialization into its own function 2018-09-05 07:51:15 +05:30
Kovid Goyal
1451a8ccc0 Add a new --start-in-fullscreen command line flag
Fixes #856
2018-09-05 07:36:13 +05:30
Kovid Goyal
547959c1ef Linux: Fix numpad arrow keys not working when num lock is off
Fixes #857
2018-09-05 07:31:55 +05:30
Kovid Goyal
b1a5e98630 Update link to Fedora package to a newer one 2018-09-04 22:28:52 +05:30
Kovid Goyal
f3a1ee7b9f Wayland backend: Add support for copy to clipboard 2018-09-04 22:22:43 +05:30
Kovid Goyal
b0a39b127d Remove unused import 2018-09-04 17:54:33 +05:30
Kovid Goyal
e36f1157cc Improve anti-aliasing at small sizes for wavy underlines 2018-09-04 15:48:01 +05:30
Kovid Goyal
053b9a786c Use a cosine instead of sine wave for wavy underlines
Matches other terminals
2018-09-04 15:35:48 +05:30
Kovid Goyal
2561d937da Forgot to remove mac os filter for native shortcut dispatching in one place 2018-09-04 15:00:09 +05:30
Kovid Goyal
55f457caf4 macOS: Fix a character that cannot be rendered in any font causing font fallback for all subsequent characters that cannot be rendered in the main font to fail
Fixes #799
2018-09-04 14:21:36 +05:30
Kovid Goyal
f5cc2fd8ad Update GLFW from upstream 2018-09-04 09:49:18 +05:30
Kovid Goyal
e630b76fac Don't patch glfw when importing since the patch has moved upstream 2018-09-04 09:46:09 +05:30
Kovid Goyal
0b6948cb4f macOS: Fix using open --args not working
Fixes #854
2018-09-03 20:58:31 +05:30
Kovid Goyal
b0a2dea747 Improve rendering of wavy underline at small font sizes
See #853
2018-09-03 10:15:53 +05:30
Kovid Goyal
f8395e36a1 Draw underlines under the text instead of over it 2018-09-03 09:48:53 +05:30
Kovid Goyal
6ec58f58ce Allow mapping shortcuts using the raw key code from the OS
Fixes #848
2018-09-02 18:46:10 +05:30
Kovid Goyal
96cbfe946c Fix legacy form of invoking icat broken in 0.12.0
Fixes #850
2018-09-02 15:59:18 +05:30
Kovid Goyal
ac686a47c1 Fail early when opening tty fails 2018-09-02 14:29:10 +05:30
Kovid Goyal
e05aaf77ce spelling typo 2018-09-01 10:41:35 +05:30
Kovid Goyal
6b371eb8a8 Merge branch 'master' of github.com:kovidgoyal/kitty 2018-09-01 10:32:44 +05:30
Kovid Goyal
f6660a0d55 Require PENV when publishing 2018-09-01 10:32:08 +05:30
Kovid Goyal
3b9f213ea2 ... 2018-09-01 10:00:35 +05:30
Kovid Goyal
4f05024550 version 0.12.0 2018-09-01 09:16:29 +05:30
Kovid Goyal
4d2d9d5574 Do not change wheel event reporting when not using high resolution scroll events 2018-08-31 15:28:48 +05:30
Kovid Goyal
14f44e79f7 Remove debug printf 2018-08-31 07:56:21 +05:30
Kovid Goyal
ab960ea12d Linux: Fix slow startup on some systems caused by GLFW searching for joysticks. Since kitty does not use joysticks, disable joystick support.
Fixes #830
2018-08-31 07:51:19 +05:30
Kovid Goyal
d276317e3a Remote control: Allow changing the current window layout with a new goto-layout command
Fixes #845
2018-08-30 10:23:20 +05:30
Kovid Goyal
8b3b0064a9 ... 2018-08-29 18:57:51 +05:30
Kovid Goyal
66b890bfd3 Merge branch 'alternate_screen_fast_scrolling' of https://github.com/Luflosi/kitty 2018-08-29 17:56:29 +05:30
Luflosi
2454ecd586 Allow for faster scrolling in alternate screen mode 2018-08-29 14:04:12 +02:00
Kovid Goyal
b891f4f874 Better error message for attempts to use CSI codes to resize the window
nvim does this for some odd reason
2018-08-29 10:09:06 +05:30
Kovid Goyal
92d06b3088 title stack should be LIFO not FIFO 2018-08-29 10:00:15 +05:30
Kovid Goyal
3067103b18 Implement window title stack
Used by new versions of vim
2018-08-29 09:56:52 +05:30
Kovid Goyal
0e248b3faa Write escape codes to children atomically
Ensure a partial escape code is never written
2018-08-29 09:01:52 +05:30
Kovid Goyal
d1a76bbcd9 Merge branch 'typo' of https://github.com/Luflosi/kitty 2018-08-29 07:30:01 +05:30
Luflosi
1d91edfb00 dont -> don't 2018-08-29 03:18:25 +02:00
Kovid Goyal
cf7ecd5e66 Do not import fast_data_types at the top level of utility modules 2018-08-28 10:27:06 +05:30
Kovid Goyal
63a2ecb89c Merge branch 'writePlist_deprecation' of https://github.com/Luflosi/kitty 2018-08-28 04:54:17 +05:30
Luflosi
8e6b58b1db Fix deprecation warning on macOS 2018-08-27 23:54:45 +02:00
Kovid Goyal
0f594ef950 Ensure multiplication is not unsigned 2018-08-27 15:47:32 +05:30
Kovid Goyal
0c1b76c17a Fix completion of kitten names not working 2018-08-27 13:23:17 +05:30
Kovid Goyal
1c11ba8dbd ... 2018-08-27 13:11:30 +05:30
Kovid Goyal
529d5b2226 Dont store the options spec at the top level of the module 2018-08-27 13:06:17 +05:30
Kovid Goyal
9fe16867c6 Do not import config_data at the top-level of the cli module
Importing it is slow and it is not needed in many cases, for instance
when used from kittens
2018-08-27 12:59:10 +05:30
Kovid Goyal
1d275c6b35 Only import the ast module on demand 2018-08-27 12:43:20 +05:30
Kovid Goyal
d19b29ced0 Fix incorrect calculation of pending_scroll_pixels 2018-08-27 06:51:25 +05:30
Kovid Goyal
bbefcb2cd2 Fix spaces after file/dir names and config directive names in bash completion
Since bash has no concept of completion groups with customizable
behavior, unlike zsh, we tell it to never add trailing spaces and
add the spaces ourselves.
2018-08-26 18:22:40 +05:30
Kovid Goyal
c864cba4a2 Completion of image names for the icat kitten 2018-08-26 11:49:56 +05:30
Kovid Goyal
42546f4371 Implement completion for the kitty command
Implemented for bash and zsh. Completion scripts are just thin wrappers
around kitty + complete which knows how to complete kitty command lines.
Should make it easy to add completion for other shells in the future.
2018-08-26 10:39:51 +05:30
Kovid Goyal
ff09bdcbf1 Completion for kittens 2018-08-26 09:42:26 +05:30
Kovid Goyal
f36a9fffa3 Completion for bash 2018-08-26 09:16:02 +05:30
Kovid Goyal
933cced76c Implement completion for remote control commands 2018-08-25 14:51:59 +05:30
Kovid Goyal
c51e7d3bde More work on completions 2018-08-25 11:27:22 +05:30
Kovid Goyal
d3b31224cd More work on completions 2018-08-24 12:15:27 +05:30
Kovid Goyal
ec9bb2302c ... 2018-08-24 11:03:30 +05:30
Kovid Goyal
009ef54de7 Implement high precision scrolling with the trackpad on platforms such as macOS and Wayland that implement it.
Fixes #819. Note that I have no idea whether the code works well on
retina screens, might have to multiple the pixel count by the scale
factor on those screens?
2018-08-24 11:00:58 +05:30
Kovid Goyal
0e0e25f986 Avoid double filter for completions in zsh 2018-08-24 08:13:59 +05:30
Kovid Goyal
8b02b89bd6 Add an is_focused field to the output of kitty @ ls 2018-08-23 16:07:26 +05:30
Kovid Goyal
8ba3c4ba50 Group completion matches 2018-08-23 15:34:54 +05:30
Kovid Goyal
16764c79b2 Start work on completion for the kitty command 2018-08-23 15:10:13 +05:30
Kovid Goyal
96c444d041 Workaround for bug in glfw causing crash when hotplugging monitors
Fixes #812
2018-08-21 12:52:16 +05:30
Kovid Goyal
ec1c72e9a3 Fix compiler warning 2018-08-20 10:55:49 +05:30
Kovid Goyal
f9b1f6be5c Fix #809 2018-08-20 10:24:09 +05:30
Kovid Goyal
9201d27875 Document kitty's extension to the OSC 52 protocol 2018-08-13 07:27:08 +05:30
Kovid Goyal
ecbe79e04f Update glfw from upstream 2018-08-12 21:36:19 +05:30
Kovid Goyal
6e34a7559b Fix one-pixel line appearing at window edges at some window sizes when displaying images with background opacity enabled
Fixes #741
2018-08-12 07:22:25 +05:30
Kovid Goyal
ea8b17565d Make ctrl+tab next_tab by default on macOS 2018-08-11 07:55:43 +05:30
Kovid Goyal
a143faaf05 macOS: Fix control+tab key combination not working
Fixes #801
2018-08-11 07:18:24 +05:30
Kovid Goyal
acdb56ad5d ... 2018-08-11 06:52:05 +05:30
Kovid Goyal
1f90238b18 If malloc fails remove timer from queue 2018-08-09 08:52:22 +05:30
Kovid Goyal
89b636376e Possible fix for #784 2018-08-09 08:26:25 +05:30
Kovid Goyal
59f39ae3ab Fix detection of xprop on systems with older xprop
Fixes #798
2018-08-08 15:31:15 +05:30
Kovid Goyal
a92b20f85a Only do manual focus follows mouse on macOS 2018-08-07 07:56:56 +05:30
Kovid Goyal
e71c432b7c ... 2018-08-06 20:13:16 +05:30
Kovid Goyal
b6a5d09d4f Allow enabling remote control in only some kitty windows 2018-08-06 20:04:12 +05:30
Kovid Goyal
9235d2b8e4 ... 2018-08-06 18:38:23 +05:30
Kovid Goyal
605847fd75 Add --no-response to kitty @ focus-window 2018-08-06 18:17:45 +05:30
Kovid Goyal
6222273adc ... 2018-08-06 12:27:20 +05:30
Kovid Goyal
6a759ea7d5 ... 2018-08-06 12:26:57 +05:30
Kovid Goyal
d8a7114dba macOS: Disable the custom mouse cursor. Using a custom cursor fails on dual GPU machines.
I give up, Apple users will just have to live with the limitations of their choice of OS.
See #794
2018-08-06 12:22:01 +05:30
Kovid Goyal
ab818ed89f IBUS: Fix update of pre-edit text not working correctly
Fixes #793
2018-08-06 11:30:33 +05:30
Kovid Goyal
1bb6540b64 Better debug output for pre-edit text 2018-08-06 11:08:12 +05:30
Kovid Goyal
ddd8209c45 Fix crash when pressing enter while using IBUS 2018-08-06 10:35:46 +05:30
Kovid Goyal
1dc3dfe58f Distinguish shifted Pgup and PgDn keys in normal and application mode
Fixes #791
2018-08-05 17:17:15 +05:30
Kovid Goyal
634d262b64 When using the --listen-on option have kitty @ automatically connect to the socket even when --to is not specified
The listen on value is set in the env of the child processes, so kitty @
can read it when run from inside kitty.
2018-08-04 22:06:47 +05:30
Kovid Goyal
d964146f8c Use ctermid() instead of hardcoding /dev/tty 2018-08-04 20:58:01 +05:30
Kovid Goyal
05b817f5f5 Micro-optimization 2018-08-04 20:34:12 +05:30
Kovid Goyal
eb2ec1833c Use a pipe rather than a signal to wait for terminal ready
Simpler code, more robust since there is no longer a race between the
installation of the signal handler and the dispatch of the signal
2018-08-04 20:24:06 +05:30
Kovid Goyal
094ddd9333 Round-trip the zwj unicode character
Rendering of sequences containing zwj is still not implemented, since it
can cause the collapse of an unbounded number of characters into a
single cell. However, kitty at least preserves the zwj by storing it as
a combining character.
2018-08-04 18:29:45 +05:30
Kovid Goyal
e05d48a574 Also prevent long running diff workers from causing a hang on exit 2018-08-04 17:51:33 +05:30
Kovid Goyal
927bfcd37a Use only a single diff executor 2018-08-04 17:46:05 +05:30
Kovid Goyal
42cabace47 Better fix for long running highlight workers 2018-08-04 17:41:37 +05:30
Kovid Goyal
9a1f14d05c diff kitten: Do not highlight extremely large files
python's asyncio module has no way to tell a process executor object to
kill its worker processes, so highlighting very large files cause the
kitten to hang around o exit till the highlighting is done
2018-08-04 17:30:45 +05:30
Kovid Goyal
4189aa8f14 Add a --no-response argument to kitty @ new-window
See #786
2018-08-04 15:57:43 +05:30
Kovid Goyal
5fa5bf8142 Add a test for unicode regional indicator widths 2018-08-04 10:56:35 +05:30
Kovid Goyal
000c1cf306 Implement support for emoji skin tone modifiers
Fixes #787
2018-08-04 10:06:25 +05:30
Kovid Goyal
28447d3389 Only launch child processes after window size is available in the termios structure
The delay is minimal ~ 1ms and there are apparently some applications
such as kakoune that rely on the window size being available on startup.

Since kitty always sizes windows with some size on startup, we can
afford to wait.

Fixes #786
2018-08-04 09:19:11 +05:30
Kovid Goyal
ab7f3310c4 Dont crash if XRRGetCrtcInfo() returns NULL 2018-08-03 16:17:25 +05:30
Kovid Goyal
e5a720c6fa Fix detection of URLs in HTML source code (URLs inside quotes)
Fixes #785
2018-08-03 12:28:23 +05:30
Kovid Goyal
8d20dbe81d Use the ! modifier when resizing images via ImageMagick
Should hopefully make ImageMagick respect the specified width and height
exactly.
2018-08-01 12:03:36 +05:30
Kovid Goyal
1fc666d82c Add an Info.plist key to enable support for dark mode in Mojave
Mojave uses tis key to determine how to draw the titlebar.
See https://developer.apple.com/documentation/appkit/nsappearancecustomization/choosing_a_specific_appearance_for_your_app?language=objc
2018-08-01 03:53:17 +05:30
Kovid Goyal
1b2a1a1e77 Add a check that tic works as expected
Apparently on FreeBSD it exits with no errors but fails to write the
compiled terminfo file.
2018-07-31 09:01:23 +05:30
Kovid Goyal
9af3081f45 The focus_follows_mouse option now also works across top-level kitty OS windows
Fixes #772
2018-07-30 21:26:20 +05:30
Kovid Goyal
78def6e6bf kitty @ new-window: Add a new option --window-type
To create top-level OS windows. Fixes #770
2018-07-30 08:40:26 +05:30
Kovid Goyal
b4269199b4 Fix #771 2018-07-30 07:58:34 +05:30
Kovid Goyal
cb289125ab Use _GNU_SOURCE instead of POSIX_SOURCE for fileno()
Maybe that will work with FreeBSD
2018-07-29 21:43:02 +05:30
Kovid Goyal
a4e3ce31dd Merge branch 'fix_window_decorations' of https://github.com/danbtl/kitty 2018-07-29 20:05:11 +05:30
Daniel Beitler
8a725d3d3e Fix hiding window decorations under X11/Wayland 2018-07-29 10:12:07 -04:00
Kovid Goyal
c48fa0f078 Silence the OpenGL deprecation warnings on macOS 10.14 2018-07-29 19:35:43 +05:30
Kovid Goyal
31aa782362 Update URL to kitty home page in Info.plist 2018-07-29 19:03:41 +05:30
Kovid Goyal
892637683c Fix controlling terminal not being set on BSD
Fixes #764
2018-07-29 13:48:14 +05:30
Kovid Goyal
1cf6f28fe8 When compiling python bytecode for the packages optimize it to level-2 and use relative paths in the pyc files 2018-07-29 13:20:21 +05:30
Kovid Goyal
29f9394257 ... 2018-07-29 13:06:26 +05:30
Kovid Goyal
8fd92df7ae Also fix launcher for netbsd 2018-07-29 12:54:24 +05:30
Kovid Goyal
374f7abb5d Fix package launcher for FreeBSD
Fixes #763
2018-07-29 12:52:24 +05:30
Kovid Goyal
3d1e604a6c Make the glfw strdup implementation more efficient 2018-07-29 12:21:56 +05:30
Kovid Goyal
1ca49b9380 Fix #761 2018-07-29 12:15:21 +05:30
Kovid Goyal
9bd9cf8052 typo 2018-07-29 11:18:12 +05:30
Kovid Goyal
ed934a0206 Fix #758 2018-07-29 11:07:36 +05:30
Kovid Goyal
dc891760ec Fix pthread_setname_np on openbsd as well
openbsd apparently follows freebsd for this function
2018-07-29 10:34:54 +05:30
Kovid Goyal
97401f843a Sigh. Apparently _XOPEN_SOURCE is needed on older linux systems for fileno() 2018-07-28 23:54:23 +05:30
Kovid Goyal
833865cb28 Re-enable brew based build on travis
New harfbuzz release will hopefully work again
2018-07-28 23:54:23 +05:30
Kovid Goyal
02635d506e Dont use _XOPEN_SOURCE when building
Apparently it has exactly opposite semantics for glibc and whatever libcs
are used on BSD. What a clusterfuck.
2018-07-28 22:56:18 +05:30
Kovid Goyal
f018e1a075 Nicer check for is_binary 2018-07-28 14:02:01 +05:30
Kovid Goyal
c79cde43ae ... 2018-07-28 14:00:18 +05:30
Kovid Goyal
8a812c9d02 diff kitten: Fix error when only RHS file is a binary file
Fixes #752
2018-07-28 13:59:32 +05:30
Kovid Goyal
3df78de3f8 Update pending mode escape code parsing to match latest shed color 2018-07-28 10:56:34 +05:30
Kovid Goyal
bd4831e2ee Some explicit includes needed for FreeBSD 2018-07-26 19:50:38 +05:30
Kovid Goyal
341a34ea9e Assume file extensions are up to 7 chars long
See .desktop files
2018-07-26 18:37:13 +05:30
Kovid Goyal
011866a101 Add a keyboard shortcut to reset the terminal
It takes parameters so you can define your own shortcuts to clear the screen/scrollback also. Fixes #747
2018-07-26 17:29:13 +05:30
Kovid Goyal
1486af8770 More debug output when using --debug-keyboard 2018-07-26 08:41:16 +05:30
Kovid Goyal
f06e04ffc5 Fix #745 2018-07-26 07:03:41 +05:30
Kovid Goyal
d72098bdf8 Preserve the mouse selection even when the contents of the screen are scrolled or overwritten provided the new text does not intersect the selected lines.
Requires a small CPU usage overhead when scrolling/drawing characters
even in the absence of a selection. I couldn't isolate the overhead from
statistical noise in my testing.
2018-07-25 16:16:57 +05:30
Kovid Goyal
57871e1983 Restore sys.path after importing custom kitten 2018-07-25 09:51:04 +05:30
Kovid Goyal
21dbb0e820 Improve the help message for the kitten remote control cmd 2018-07-25 09:49:01 +05:30
Kovid Goyal
007f377f16 Allow running kitten via the remote control system
Fixes #738
2018-07-25 09:45:11 +05:30
Kovid Goyal
da15477aaf Make the choice of default editor a bit more robust 2018-07-25 08:57:44 +05:30
Kovid Goyal
4f34ad0a8d ... 2018-07-24 14:14:34 +05:30
Kovid Goyal
6ed9dccde2 Remove unused parameter 2018-07-24 13:51:45 +05:30
Kovid Goyal
ce2b3265be Remote control: Allow matching windows by the environment variables of their child process as well 2018-07-24 12:40:59 +05:30
Kovid Goyal
14ea69c9c7 Pass pid of child process as env var to kittens 2018-07-24 11:28:34 +05:30
Kovid Goyal
72e2307c16 Code to get the env vars of a process 2018-07-24 11:27:10 +05:30
Kovid Goyal
0dd3334811 Implement getting cmdline of process on macOS as well 2018-07-24 11:07:53 +05:30
Kovid Goyal
5485436ea1 ... 2018-07-24 10:18:37 +05:30
Kovid Goyal
9e044750ce When running kittens use the cwd of the child process as the kittens' cwd 2018-07-24 10:14:17 +05:30
Kovid Goyal
f84cb2f07a ... 2018-07-24 09:32:21 +05:30
Kovid Goyal
e0ff6bcc5d Implement protocol for atomic screen updates
See https://gitlab.com/gnachman/iterm2/wikis/synchronized-updates-spec
2018-07-23 13:24:49 +05:30
Kovid Goyal
1695f6800c Expand links to kitty docs in sample kitty.conf 2018-07-20 21:21:52 +05:30
Kovid Goyal
810f149501 Fix #731 2018-07-20 21:04:07 +05:30
Kovid Goyal
05d51d8693 Fix #730 2018-07-20 15:55:39 +05:30
Kovid Goyal
ac4c819f57 Add a warning not to edit the apc parsers header files 2018-07-20 09:45:05 +05:30
Kovid Goyal
e7cc654bb4 Make error message when creating glfw window fails a little more useful 2018-07-20 09:36:42 +05:30
Kovid Goyal
bf37e3f77f Format generated header using clang-format 2018-07-19 18:56:10 +05:30
Kovid Goyal
af9f7bb0d2 Generate the code to parse APC escape codes
Allows it to be re-used for other APC codes
if needed.
2018-07-19 18:43:26 +05:30
Kovid Goyal
0b7abf5690 Fix test that needed to be changed for new prerendered sprites 2018-07-19 14:21:09 +05:30
Kovid Goyal
490ae248f8 Render all cursor shapes in the cell shader 2018-07-19 14:05:15 +05:30
Kovid Goyal
e552bcb0c6 Prerender cursor sprites 2018-07-19 14:03:39 +05:30
Kovid Goyal
2c27316c4a Get rid of the cursor program
Cursors will now be drawn in the cell program using a sprite
2018-07-19 12:46:25 +05:30
Kovid Goyal
c49dd12855 Pass in cursor shape to cell shader 2018-07-19 12:13:39 +05:30
Kovid Goyal
544f97a3fe ... 2018-07-19 11:18:31 +05:30
Kovid Goyal
6a909e0700 Get rid of the last branch in the cell shader 2018-07-19 10:56:28 +05:30
Kovid Goyal
40a6ad9a1f ... 2018-07-19 06:07:04 +05:30
Kovid Goyal
039f2b49e8 Remove workaround for #654 as it has been upstreamed 2018-07-19 05:11:03 +05:30
Kovid Goyal
5ae2406a03 macOS: Allow scrolling window contents using mouse wheel/trackbar even when the window is not the active window
Fixes #729
2018-07-18 10:34:36 +05:30
Kovid Goyal
2c3235d452 Remove need to call super-class on_resize method 2018-07-15 16:19:54 +05:30
Kovid Goyal
d2ea71a403 Remove unused code 2018-07-15 16:14:40 +05:30
Kovid Goyal
feb97b2313 Use asyncio for jobs in the diff kitten 2018-07-15 16:09:52 +05:30
Kovid Goyal
0b662ecb9a Refactor the kittens tui loop to use asyncio
Gets us timers and various jobs for free, and makes it easier to
integrate with libraries that use asyncio from the larger python
ecosystem.
2018-07-15 15:27:35 +05:30
Kovid Goyal
3d0da77c80 Revert change to set PYTHONIOENCODING on macOS
It is not needed in python 3.7 as the POSIX locale is
now UTF-8 by default
2018-07-15 12:19:48 +05:30
Kovid Goyal
9918397190 Add an option :opt:env to set environment variables in child processes from kitty.conf 2018-07-15 12:16:43 +05:30
Kovid Goyal
b3e2562c00 macOS bundle: Set the PYTHONIOENCODING env var to utf-8
There are apparently still some situations where python ends up with
ascii as its I/O encoding on macOS. See #724
2018-07-15 10:38:40 +05:30
Kovid Goyal
255cacf912 kitty shell prompt: fallback to plain ascii prompt in case of unicode errors 2018-07-14 06:35:43 +05:30
Kovid Goyal
8268f9f612 Add a section about remote control to the main page 2018-07-14 06:06:59 +05:30
Kovid Goyal
92b8798cad Add note about ctrl+alt to select in columns 2018-07-14 06:02:17 +05:30
Kovid Goyal
fbb4db8a83 Allocate talk data on the heap
Most users will talk to 0, 1, 2 peers simultaneously at the most,
so allocate memory for them dynamically.
2018-07-13 17:13:59 +05:30
Kovid Goyal
19a672caf2 Allow kitty to handle talking to more simultaneous peers 2018-07-13 16:46:08 +05:30
Kovid Goyal
5a85c890ba Add a printf annotation of the log_error function 2018-07-13 16:39:47 +05:30
Kovid Goyal
55556aaac4 Ensure queued display events are dispatched when polling/waiting for events 2018-07-13 10:56:12 +05:30
Kovid Goyal
31853ee20c Handle errno better when polling for events 2018-07-13 10:33:18 +05:30
Kovid Goyal
037bfeff82 Give IBUS a maximum of three seconds to respond to a key press
Previously was using the default timeout, which is 25 seconds
2018-07-12 18:18:21 +05:30
Kovid Goyal
bf1c919547 When de-activating overlay line, mark it dirty 2018-07-12 18:18:21 +05:30
Kovid Goyal
202ec17a08 Add a changelog entry for IBus support
Fixes #469
2018-07-12 18:18:21 +05:30
Kovid Goyal
98ede457a0 Do not hand on startup if the ibus daemon is hung 2018-07-12 18:18:21 +05:30
Kovid Goyal
3c772c3576 ... 2018-07-12 18:18:21 +05:30
Kovid Goyal
5b1eaa741c IME input: Show the pre-edit text while the IME is in progress
Text is show in reverse video
2018-07-12 18:18:21 +05:30
Kovid Goyal
1a1aa2d6aa Nicer debug print for key debugging 2018-07-12 18:18:20 +05:30
Kovid Goyal
6e9aecdff3 Fix Shift key not working with IBUS
Fixes #721
2018-07-12 18:18:20 +05:30
Kovid Goyal
95187632bf Allow using GLFW_IM_MODULE to activate ibus 2018-07-12 18:18:20 +05:30
Kovid Goyal
e3e28a023c Fix exporting to glfw 2018-07-12 18:18:20 +05:30
Kovid Goyal
65bb71779a Install dbus on travis 2018-07-12 18:18:20 +05:30
Kovid Goyal
29dd766a67 Fix unused vars warning 2018-07-12 18:18:20 +05:30
Kovid Goyal
851145e69e Add some debug prints for IBUS key handling 2018-07-12 18:18:20 +05:30
Kovid Goyal
b2e300c440 Simplify key round-tripping to IBUS
Only send to IBUS after full xkb processing. This is needed as otherwise
modifier state tracking does not work reliably. If you use alt+tab to
switch away from the window, the window never receives the release event
for the alt modifier.

The downside is that now if the uer has both XCompose and ibus active,
the who knows what will happen.
2018-07-12 18:18:20 +05:30
Kovid Goyal
38998a4869 Notify IBUS when focus is gained/lost 2018-07-12 18:18:19 +05:30
Kovid Goyal
21f1fd55f8 Have the IBUS popup display at the cursor position 2018-07-12 18:18:19 +05:30
Kovid Goyal
c6c6a18375 Handle keys returned by IBUS 2018-07-12 18:18:19 +05:30
Kovid Goyal
56063b283e Implement text commit from the IME system 2018-07-12 18:18:19 +05:30
Kovid Goyal
d27e7ead49 Print an error if too many timers/watches are added 2018-07-12 18:18:19 +05:30
Kovid Goyal
342164ede1 Add API for the application to notify the IME system of state changes 2018-07-12 18:18:19 +05:30
Kovid Goyal
1061e40b98 Bi-directional glfw updates 2018-07-12 18:18:19 +05:30
Kovid Goyal
377115a594 Add a GLFW specific env var to toggle IBUS 2018-07-12 18:18:19 +05:30
Kovid Goyal
e405b68da1 ... 2018-07-12 18:18:18 +05:30
Kovid Goyal
d875d7baed Implement the handler for ibus signals 2018-07-12 18:18:18 +05:30
Kovid Goyal
9c48e4965c Send key events to ibus 2018-07-12 18:18:18 +05:30
Kovid Goyal
8675659fcb Fix remaining sync BUS calls
Also work on IBUS integration
2018-07-12 18:18:18 +05:30
Kovid Goyal
3b226618ad Ensure no ibus comms take place till the connection is fully setup 2018-07-12 18:18:18 +05:30
Kovid Goyal
6879a492dc Give watches and timers names to ease debugging 2018-07-12 18:18:18 +05:30
Kovid Goyal
4070255dde Simplify watch->fd matching 2018-07-12 18:18:18 +05:30
Kovid Goyal
dd9e484336 Make the DBUS APIs async 2018-07-12 18:18:18 +05:30
Kovid Goyal
78cda7aa74 Implement dispatch for the IBUS connection 2018-07-12 18:18:17 +05:30
Kovid Goyal
9ced447fa3 Make timer dispatch more efficient 2018-07-12 18:18:17 +05:30
Kovid Goyal
8e665ffedc Implement DBUS timeout functions 2018-07-12 18:18:17 +05:30
Kovid Goyal
99ea6c08a7 Implement timers for the linux event loops
Needed for dbus integration. Also cleanup the event handling code.
X11 and Wayland now share most of their event polling and dispatch logic.
2018-07-12 18:18:17 +05:30
Kovid Goyal
b0bfa2b2fc ... 2018-07-12 18:18:17 +05:30
Kovid Goyal
3797294838 Use an id for watches 2018-07-12 18:18:17 +05:30
Kovid Goyal
3d6995d1e6 Work on integration of DBUS into event loop 2018-07-12 18:18:17 +05:30
Kovid Goyal
e91eb27e56 Refactor linux backend event loops
Allow waiting for events on an arbitrary number of fds. Needed
for async DBUS integration.
2018-07-12 18:18:17 +05:30
Kovid Goyal
3a4b614ae0 IBUS does not need a connection to the DBUS session bus 2018-07-12 18:18:16 +05:30
Kovid Goyal
26a6d6bef9 Set startup IBUS cursor and focus state 2018-07-12 18:18:16 +05:30
Kovid Goyal
dca81589a7 Finish code to connect to IBUS daemon 2018-07-12 18:18:16 +05:30
Kovid Goyal
5b7c697dfe Connect to IBUS 2018-07-12 18:18:16 +05:30
Kovid Goyal
18d6b8a0ad Code to read the IBUS address 2018-07-12 18:18:16 +05:30
Kovid Goyal
cdee601137 Start work on IBUS support 2018-07-12 18:18:16 +05:30
Kovid Goyal
e74c08ff39 Disable brew based travis build
Building the latest release of harfbuzz is failing
2018-07-12 17:42:33 +05:30
Kovid Goyal
5bfe2fb8d3 Make using a fixed color for the text under the cursor the default 2018-07-12 16:52:38 +05:30
Kovid Goyal
55fc5c4358 Add an option :opt:cursor_text_color to render text under the cursor in a fixed color.
See #126
2018-07-12 12:50:42 +05:30
Kovid Goyal
d6a603d536 Change the default publish action from build+ to all 2018-07-10 22:05:33 +05:30
Kovid Goyal
5c85d915cc ... 2018-07-10 22:00:34 +05:30
Kovid Goyal
57f8519a52 version 0.11.3 2018-07-10 21:42:01 +05:30
Kovid Goyal
056be45dd5 ... 2018-07-10 21:30:30 +05:30
Kovid Goyal
3ee22e545e macOS: Workaround for switching from fullscreen to windowed mode with the titlebar hidden causing window resizing to not work.
Fixes #711
2018-07-10 21:29:30 +05:30
Kovid Goyal
db5aa36f44 Fix deprecation warning from newer versions of wayland-scanner 2018-07-10 19:48:37 +05:30
Kovid Goyal
cc767061cc Linux: Fix compilation with python 3.7
Fixes #714
2018-07-10 18:47:05 +05:30
Kovid Goyal
1d22b75090 Fix a regression in the previous release that caused pasting large amounts of text to be duplicated
Fixes #709
2018-07-08 16:25:08 +05:30
Kovid Goyal
4313531432 macOS: Use a custom mouse cursor that shows up well on both light and dark backgrounds
Fixes #359. Also, update GLFW from upstream for retina cursor setting
support.
2018-07-07 10:43:30 +05:30
Kovid Goyal
1faddeb402 Also return image dimensions when loading PNG 2018-07-07 08:04:11 +05:30
Kovid Goyal
2b035739f8 Make the PNG reader code re-useable 2018-07-07 07:46:15 +05:30
Kovid Goyal
aeed20087e Fix segfault when opening more tabs than would fit with even one character titles on the tab bar. Fixes #706 2018-07-07 05:35:56 +05:30
Kovid Goyal
a239f41495 minimal borders for the grid layout 2018-07-06 20:23:56 +05:30
Kovid Goyal
b36d6967a5 DRYer 2018-07-06 17:54:01 +05:30
Kovid Goyal
7c1d13b7db Minimal borders for vertical and horizontal layouts 2018-07-06 17:46:08 +05:30
Kovid Goyal
3e99949db8 Implement minimal borders in the Fat layout 2018-07-06 17:35:23 +05:30
Kovid Goyal
aa12a65a8f Draw only the minimum borders needed for inactive windows
Fixes #699

Note that currently this is only implemented by the Tall layout.
2018-07-06 17:30:53 +05:30
Kovid Goyal
18804efb7e Let the layout control which window borders are drawn 2018-07-06 17:14:25 +05:30
Kovid Goyal
a5d27196ea Remove unnecessary code 2018-07-06 13:17:51 +05:30
Kovid Goyal
5af6d88ffb Support drawing individual border widths 2018-07-06 13:17:51 +05:30
Kovid Goyal
472a3bc69f Refactor layout dimension to use per window decoration sizes 2018-07-06 13:17:51 +05:30
Kovid Goyal
f0f1c911ea Track window neighbors 2018-07-06 13:17:50 +05:30
Kovid Goyal
fcb0033d25 When drag-scrolling stop the scroll when the mouse button is released. 2018-07-06 13:01:49 +05:30
Kovid Goyal
c8b1e76783 When clicking in the margin/border area of a window map the click to the nearest cell in the window. Avoids selection with the mouse failing when starting the selection just outside the window. 2018-07-06 12:32:08 +05:30
Kovid Goyal
b50f621e61 DRYer 2018-07-06 10:55:03 +05:30
Kovid Goyal
77c4f5fecc When dragging to select with the mouse "grab" the mouse so that if it strays into neighboring windows, the selection is still updated
Fixes #624
2018-07-06 10:33:01 +05:30
Kovid Goyal
e27ea3337a Prevent integer wrap on xlimit 2018-07-06 09:50:34 +05:30
Kovid Goyal
23fbf6f157 Fix triple-click to select line not working when the entire line is filled
Fixes #703
2018-07-06 08:17:48 +05:30
Kovid Goyal
321e5081ed Merge branch 'reproducible-docs' of https://github.com/jamessan/kitty 2018-07-05 20:37:57 +05:30
James McCoy
33cac29f87 seq_as_rst: Sort "Choices" so they are consistently formatted 2018-07-05 11:00:54 -04:00
Kovid Goyal
12be438dea ... 2018-07-05 12:30:11 +05:30
Kovid Goyal
00092db6ad Use an enum for border colors 2018-07-05 11:52:32 +05:30
Kovid Goyal
619c3a0025 macOS: Add an option macos_window_resizable to control if kitty top-level windows are resizable using the mouse or not
Fixes #698
2018-07-03 06:49:28 +05:30
Kovid Goyal
f12697c897 Better error when kitty config dir is a file
See #697
2018-07-03 06:30:29 +05:30
Kovid Goyal
4bf0e0ea23 version 0.11.2 2018-07-01 07:58:46 +05:30
Kovid Goyal
c7879d06c9 Output native key names in --debug-config 2018-06-30 18:48:39 +05:30
Kovid Goyal
05227e7dfb Fix --debug-config failing when native keys present 2018-06-30 18:42:19 +05:30
Kovid Goyal
9805d164d0 Remove unknown flags from brew install for harfbuzz on travis 2018-06-30 18:34:27 +05:30
Kovid Goyal
05384c46e7 ... 2018-06-30 18:25:45 +05:30
Kovid Goyal
c2679eff9a Fix compiler warning
The compiler warning is harmless, since we exec immediately after
using the const char* but since I have a no warning policy...
2018-06-30 18:15:08 +05:30
Kovid Goyal
3ec66c0b9f Fix regression in previous release that caused --debug-config to fail when printing shortcuts
Forgot to adjust the print shortcuts code for native shortcuts.
Fixes #695
2018-06-30 17:48:25 +05:30
Kovid Goyal
9277b80fad Remove unused code 2018-06-30 12:01:56 +05:30
Kovid Goyal
568a4c9b5d Re-raise KeyError idiomatically 2018-06-29 13:49:08 +05:30
Kovid Goyal
4de18688ca Merge branch 'fix/conf-utils-keyparser' of https://github.com/arubertoson/kitty 2018-06-29 13:42:21 +05:30
Marcus Albertsson
12975347ee Fix: Exception in conf utils
The bug was related to trying to split a string with unstript spaces in
the action parameter. It resulted in a unbound error as there was no
previous raise when getting the key from args_funcs. The fix is twofold,
it makes sure that we raise the keyerror if we're trying to grab a non
existing key and we're stripping the spaces from the action before
splitting.

This should fix both the unbound error and the not being able to resolve
correct actions.
2018-06-29 08:56:25 +01:00
Kovid Goyal
e35c3cc913 Add an option single_window_margin_width to allow different margins when only a single window is visible in the layout
Fixes #688
2018-06-29 09:56:05 +05:30
Kovid Goyal
65fef81f29 hints kitten: Add an option to select multiple items
Fixes #687
2018-06-29 06:49:16 +05:30
Kovid Goyal
e3f60e6fa7 Update CHANGELOG 2018-06-28 20:34:56 +05:30
Kovid Goyal
0c88e11cd7 More useful exception when unexpected output encountered from a kitten 2018-06-27 14:13:40 +05:30
Kovid Goyal
d689c21283 Fix pasting large amounts of text very slow.
Fixes #682

Apparently when refactoring child.py I somehow lost the code to make the
child fd non-blocking.
2018-06-26 18:20:46 +05:30
Kovid Goyal
5362d1a7a6 Micro-optimization 2018-06-26 16:02:05 +05:30
Kovid Goyal
3b1490020d ... 2018-06-26 12:35:38 +05:30
Kovid Goyal
b8ba25b81f Add a link to the kitty source code for packagers 2018-06-26 12:03:07 +05:30
Kovid Goyal
8bfdc47998 macOS: Fix an error in remote control when using --listen-on. Fixes #679 2018-06-25 12:33:54 +05:30
Kovid Goyal
2491fafe98 Update glfw from upstream 2018-06-23 14:59:36 +05:30
Kovid Goyal
b5bc466aef Merge branch 'master' of https://github.com/Ma-Shell/kitty 2018-06-23 13:54:47 +05:30
Marcel Schumacher
cfd6ea4301 bugfix for get-text with extent=screen 2018-06-23 10:13:37 +02:00
Kovid Goyal
2cdf41f190 ... 2018-06-23 13:20:53 +05:30
Kovid Goyal
9169d0aa9b ... 2018-06-23 10:34:35 +05:30
Kovid Goyal
05a25e3531 redirect to kitty website 2018-06-23 10:30:34 +05:30
Kovid Goyal
2852ce9a4d Update glfw from upstream 2018-06-23 10:23:21 +05:30
Kovid Goyal
20f8f2c401 Removed unused code
The template is no longer needed since I switched my global
template to py3
2018-06-23 10:03:37 +05:30
Kovid Goyal
0995187080 Remove unused code
linux-installer.sh was accidentally committed to the kitty repo
2018-06-23 09:58:20 +05:30
Kovid Goyal
d10eac1b02 Merge branch 'fix-new_os_window' of https://github.com/blueyed/kitty 2018-06-23 08:28:11 +05:30
Daniel Hahler
2cc2f803f1 create_session: handle args=None
Fixes `new_os_window`:

    scancode: 0x39 release: 0 clean_sym: n composed_sym: N mods: ctrl+shift glfw_key: N
    Traceback (most recent call last):
      File "…/Vcs/kitty/kitty/boss.py", line 431, in dispatch_special_key
        return self.dispatch_action(key_action)
      File "…/Vcs/kitty/kitty/boss.py", line 487, in dispatch_action
        passthrough = f(*key_action.args)
      File "…/Vcs/kitty/kitty/boss.py", line 199, in new_os_window
        self._new_os_window(args)
      File "…/Vcs/kitty/kitty/boss.py", line 195, in _new_os_window
        startup_session = create_session(self.opts, special_window=sw, cwd_from=cwd_from)
      File "…/Vcs/kitty/kitty/session.py", line 127, in create_session
        if args.hold:
2018-06-23 02:57:47 +02:00
Kovid Goyal
66a52ac588 Also ignore failure to read readline history in the ask kitten 2018-06-22 17:23:55 +05:30
Kovid Goyal
32f22e0ada kitty shell: Ignore failure to read readline history file 2018-06-22 17:23:01 +05:30
Kovid Goyal
c037f53534 ... 2018-06-22 15:35:24 +05:30
Kovid Goyal
aba84581f5 When running kitty from within kitty, use a full path
Fixes inability to run kitty from the shell when the users shell scripts
reset PATH. See #668
2018-06-22 15:33:07 +05:30
Kovid Goyal
82f6fbff77 Add a --hold command line option to stay open after the child process exits
Fixes #667
2018-06-22 13:52:03 +05:30
Kovid Goyal
d16215ab6e Initialize glfw for --debug-config as well 2018-06-22 13:30:03 +05:30
Kovid Goyal
45b0233f60 Update GLFW from upstream
Use the new init hint for keyboard debugging
2018-06-22 13:26:41 +05:30
Kovid Goyal
1ce4366972 ... 2018-06-22 12:44:08 +05:30
Kovid Goyal
c8fc21d336 Linux: Allow using XKB key names to bind shortcuts to keys not supported by GLFW
Useful to bind keys such as the play/pause or volume buttons. Also can
be used to bind non-ascii keys on international keyboards. Fixes #665
2018-06-22 12:41:50 +05:30
Kovid Goyal
5dd3243674 Update glfw from upstream 2018-06-22 10:21:51 +05:30
Kovid Goyal
815dd99f7c Keep the Debian PC police happy
Fixes #661
2018-06-21 13:12:45 +05:30
Kovid Goyal
bf0dcb1d2e Update version of glad used to generate OpenGL wrapper
Also fix #654
2018-06-20 12:43:26 +05:30
Kovid Goyal
031fc10859 Merge branch 'title-command-line-parameter' of https://github.com/lamby/kitty 2018-06-19 13:48:55 +05:30
Chris Lamb
a644e4c31e Support "-T" as an alias for "--title".
Thank you for developing Kitty.

Currently kitty is not available on the list of "alternatives" for a
terminal emulator on Debian GNU/Linux and derivatives. This is because
Debian Policy states that packages that provide a terminal emulator must
provide, inter alia, support the command-line option -T title, which
creates a new terminal window with the specified window title [0].

This PR therefore adds -T as an alias for --title, thus bringing kitty into
compliance and allowing cleaner integration into the Debian desktop.

This issue was originally filed as #900704.

  [0] https://www.debian.org/doc/debian-policy/#packages-providing-a-terminal-emulator
  [1] https://bugs.debian.org/900704

Signed-off-by: Chris Lamb <lamby@debian.org>
2018-06-19 10:10:43 +02:00
Kovid Goyal
0398dbdcbe Fix extra blank lines when using log_error() 2018-06-19 12:51:54 +05:30
Kovid Goyal
84b2fbba28 --debug-font-fallback also prints out what basic fonts were matched
Fixes #656
2018-06-19 12:48:33 +05:30
Kovid Goyal
491f233d33 diff kitten: When triggering a search scroll to the first match automatically 2018-06-19 10:30:52 +05:30
Kovid Goyal
5e38af6d24 When closing a kitty window reset the mouse cursor to its default shape and ensure it is visible. Fixes #655 2018-06-19 10:19:17 +05:30
Kovid Goyal
4c0f68150a Merge branch 'master' of https://github.com/Luflosi/kitty 2018-06-18 18:41:12 +05:30
Luflosi
3f25f70783 Ignore .DS_Store 2018-06-18 14:39:12 +02:00
Kovid Goyal
d7007f77aa DRYer 2018-06-18 12:18:04 +05:30
Kovid Goyal
94273941ad ... 2018-06-18 12:10:42 +05:30
Kovid Goyal
c09542ea6a Speed up reading of command responses 2018-06-18 11:42:32 +05:30
Kovid Goyal
c5583d380d No need to use select() for TTYIO
Instead make read() block with timeout via termios
2018-06-18 11:10:16 +05:30
Kovid Goyal
f820f72768 Add a kitty @ get-colors command 2018-06-18 10:02:05 +05:30
Kovid Goyal
6db1f8e3e3 Dont read more data than needed in TTYIO 2018-06-18 08:36:47 +05:30
Kovid Goyal
2aba3e249c Linux installer: Workaround for bug in 3.0 <= python <= 3.5 2018-06-18 07:21:44 +05:30
Kovid Goyal
f66db65974 version 0.11.1 2018-06-17 10:57:55 +05:30
Kovid Goyal
5b6038db35 Dont include a literal dump of the conf files
Since all the config options are documented separately on the page in
any case, there is not much need for it. And now that the conf files are
downloadable, it is probably nicer to just view/edit them directly in
the users favorite pager/editor rather than the browser.
2018-06-16 22:31:21 +05:30
Kovid Goyal
9a365b0968 Merge branch 'docs' of https://github.com/blueyed/kitty 2018-06-16 22:26:45 +05:30
Daniel Hahler
8a0cd73821 docs: improve generation of default config files
- config files are placed into `docs/generated/conf/`, using the
  expected name, and without any indentation
- `literalinclude::` is used instead of `include::`
- uses `:download:` instead of `:file:` to allow for downloading the
  generated files easily
2018-06-16 18:35:58 +02:00
Kovid Goyal
49b065cbe7 Use conf_dir instead of cwd as base for session file 2018-06-16 10:22:46 +05:30
Kovid Goyal
77f651cb5d Expand env vars for the start_session config variable 2018-06-16 10:18:48 +05:30
Kovid Goyal
fedde51c12 ... 2018-06-16 10:16:06 +05:30
Kovid Goyal
f710d6906e Add a linkcheck target to check links in the docs 2018-06-16 09:27:39 +05:30
Kovid Goyal
c9a751360e Update CHANGELOG 2018-06-16 09:25:00 +05:30
Kovid Goyal
ad97315925 diff kitten: Misc fixes to msg display in the status line 2018-06-16 08:57:02 +05:30
Kovid Goyal
e8f7a2b345 Dont send on_text events with empty text 2018-06-16 08:55:10 +05:30
Kovid Goyal
5bc8d05f0a ... 2018-06-16 08:49:08 +05:30
Kovid Goyal
3669d4135c diff kitten: Add keybindings to search without regex 2018-06-16 08:45:42 +05:30
Kovid Goyal
73b870bb87 ... 2018-06-16 08:41:19 +05:30
Kovid Goyal
6b4217c12a Use a single build script on Travis
Allows the build to fail faster if any of the intermediate steps fails
2018-06-16 08:33:07 +05:30
Kovid Goyal
8b4fe494cf Format matches count the same as scroll percent 2018-06-16 08:24:32 +05:30
Kovid Goyal
35041e7709 Fix docs links 2018-06-16 08:19:33 +05:30
Kovid Goyal
12cbcf1c17 Add an option to kitty.conf to specify a default startup session
Fixes #641
2018-06-16 08:14:11 +05:30
Kovid Goyal
26f50a451e Add a section on configuration to the main page in the docs 2018-06-16 07:45:24 +05:30
Kovid Goyal
11f3d7e215 ... 2018-06-15 17:53:04 +05:30
Kovid Goyal
a7d533cfe5 Increase contrast of link color with text color in docs 2018-06-15 15:38:30 +05:30
Kovid Goyal
52ec4dc21b Allow cross-linking to @ command documentation 2018-06-15 15:31:05 +05:30
Kovid Goyal
6f7ea49008 Switch to high number OSC codes instead of DCS string codes for dynamic color push/pop 2018-06-15 15:21:46 +05:30
Kovid Goyal
84b99b1b3d diff kitten: Clear the search when pressing Esc 2018-06-15 15:00:09 +05:30
Kovid Goyal
1022d8a0ee diff kitten: Show the number of matches in the status bar when doing a search 2018-06-15 14:57:03 +05:30
Kovid Goyal
cd6a46730a ... 2018-06-15 14:48:59 +05:30
Kovid Goyal
59743fd7a1 diff kitten: Allow theming the selection background/foreground as well 2018-06-15 14:43:39 +05:30
Kovid Goyal
07bd371e21 Re-org diff kitten docs
Move the auto-generated bits to the end
2018-06-15 14:31:13 +05:30
Kovid Goyal
fe3b10a8fb diff kitten: Implement searching for text in the diff
Fixes #574
2018-06-15 14:28:42 +05:30
Kovid Goyal
c994bc1d89 Add more clarification about kitty's performance goals 2018-06-15 13:51:49 +05:30
Kovid Goyal
22cffef7c8 diff kitten: Use a single-width replacement for control chars
Preserves text width better, and conveys the essential message, namely
non-printable characters. Most people wont know what <hex code> is in
any case.
2018-06-15 08:08:21 +05:30
Kovid Goyal
5dfb8b1d80 diff kitten: Display CRLF line endings using the unicode return symbol instead of <d> as it is less intrusive.
Fixes #638
2018-06-15 07:08:57 +05:30
Kovid Goyal
82f9f002bd diff kitten: Fix default foreground/background colors not being restored when kitten quits. Fixes #637 2018-06-14 23:25:13 +05:30
Kovid Goyal
9f51506422 ... 2018-06-14 22:07:34 +05:30
Kovid Goyal
2a8295d71c diff kitten: Better error message when one of the arguments does not exist 2018-06-14 21:53:13 +05:30
Kovid Goyal
7214b66aa5 A new tui API for simple line editing
Handles basic line-editing with the extended keyboard protocol and
support for wide chars.
Currently used by the unicode input kitten.
2018-06-14 13:11:48 +05:30
Kovid Goyal
a7d9c63a4e wcwidth() for not assigned code points should be -4
That way, wcswidth() computes their width as 1, which matches how they
are rendered
2018-06-14 10:27:42 +05:30
Kovid Goyal
61dd52b50f Ignore the non-characters from the unicode standard in addition to ignoring the control characters 2018-06-14 10:20:13 +05:30
Kovid Goyal
a157f3c5e3 Fix kitty @ set-colors --all not working when more than one window present
Fixes #632
2018-06-13 14:21:55 +05:30
Kovid Goyal
fc02246373 ... 2018-06-13 07:46:11 +05:30
Kovid Goyal
adb8a4676c Fix a regression that broke the legacy increase/decrease_font_size actions 2018-06-13 07:42:12 +05:30
Kovid Goyal
f78d05a57f Clear scrollback on reset
Fixes #631
2018-06-13 07:20:19 +05:30
Kovid Goyal
301d34fecf Ignore errors in talk socket shutdown
macOS apparently shuts down the socket before shutdown can be called.
2018-06-12 21:15:43 +05:30
Kovid Goyal
0848816644 ... 2018-06-12 21:03:02 +05:30
Kovid Goyal
ba7f0132f2 Add a command line option to make --single-instance wait for the closing of the newly opened window before quitting. Fixes #630 2018-06-12 20:53:25 +05:30
Kovid Goyal
561fe81d00 Use base instead of cwd when checking for docs 2018-06-12 09:24:36 +05:30
Kovid Goyal
2db83ecf1e Run make docs for linux-package only if docs are not found 2018-06-12 09:20:18 +05:30
Kovid Goyal
1b8c6b23e1 Dont run make docs to build linux-package
The pre-built docs are now included in the official kitty source code
release. This means that building linux-package does not require
sphinx anymore.
2018-06-12 09:15:43 +05:30
Kovid Goyal
b6622b9458 Fix paths to built bundles 2018-06-12 08:53:22 +05:30
Kovid Goyal
d79e943844 Dont build docs when freezing 2018-06-12 08:41:38 +05:30
Kovid Goyal
105959d91b version 0.11.0 2018-06-12 08:36:19 +05:30
Kovid Goyal
ea414945f2 DRYer 2018-06-11 17:52:00 +05:30
Kovid Goyal
4acc692a94 Fix #627 2018-06-11 13:59:40 +05:30
Kovid Goyal
05c475e6ca Update glfw from upstream 2018-06-11 13:08:21 +05:30
Kovid Goyal
c04e1aedb2 Use basenames for default window title 2018-06-11 12:39:13 +05:30
Kovid Goyal
4711746f8f Linux: When using layouts that map the keys to non-ascii characters, map shortcuts using the ascii equivalents, from the default layout.
Fixes #606
2018-06-11 12:21:35 +05:30
Kovid Goyal
7a7262923b Fix a regression in 0.10 that caused incorrect rendering of the status bar in irssi when used inside screen.
Fixes #621. The cursor in margin check was incorrect causing upwards
movement of the cursor when below the bottom margin to be incorrect.
2018-06-11 10:13:21 +05:30
Kovid Goyal
cde60b19e8 Automatically build docs when running linux-pacakge
Fixes #622
2018-06-11 09:57:56 +05:30
Kovid Goyal
59430c1c14 Add missing screen_delete_lines to client 2018-06-11 09:12:30 +05:30
Kovid Goyal
e55cae6192 Fix kitty @ set-colors not working with the window border colors
Fixes #623
2018-06-11 09:03:24 +05:30
Kovid Goyal
ed71e73ca5 Merge branch 'master' of https://github.com/dcolascione/kitty 2018-06-11 07:18:14 +05:30
Kovid Goyal
9ffd0111cc Merge branch 'autodpi-x11' of https://github.com/dcolascione/kitty 2018-06-11 07:16:36 +05:30
Kovid Goyal
93b1919a38 Update glfw from upstream, to allow kitty to react to Xft.dpi changes 2018-06-11 07:12:06 +05:30
Daniel Colascione
535606fadb A DPI change is signaled by either a viewport _or_ a scaling factor change
Before this change, kitty considered only changes in viewport size to
signal DPI, and on non-macOS platforms, it's the scaling factor, not
the viewport size, that changes when DPI changes.
2018-06-10 18:31:44 -07:00
Kovid Goyal
7cf7d94bba Add a make docs Makefile target
Fixes #622
2018-06-11 06:31:23 +05:30
Daniel Colascione
136a718453 Avoid spurious selection
If we've previously reset the selection to EMPTY_SELECTION (say,
because we were marked dirty), the selection ends up being 0/0, so if
we click some random place, we suddenly get a non-empty selection
region and highlight random stuff even though all the user did was
left-click once somewhere.
2018-06-10 12:01:18 -07:00
Kovid Goyal
5f6c4c0f6c ... 2018-06-10 06:36:23 +05:30
Kovid Goyal
ddfe7797e5 Fix #620 2018-06-09 23:21:00 +05:30
Kovid Goyal
fc74d22724 Nicer error message when specifying a non-existent kitten 2018-06-09 13:49:33 +05:30
Kovid Goyal
ca41e642fb Nicer error message when no kitten name is specified 2018-06-09 13:47:49 +05:30
Kovid Goyal
83849ab07a Document the clipboard kitten 2018-06-09 13:32:32 +05:30
Kovid Goyal
02ac2336bd DRYer 2018-06-09 12:47:52 +05:30
Kovid Goyal
c094ebce07 Set VMIN to 1 as without it poll() returns immediately even when no data is available to read on macOS 2018-06-09 11:17:12 +05:30
Kovid Goyal
65ed9c759c ... 2018-06-09 11:10:58 +05:30
Kovid Goyal
83fe2438f9 Forgot to port the exception handler loop 2018-06-09 11:08:25 +05:30
Kovid Goyal
caa20aa081 Use the new tty code in tui as well 2018-06-09 09:06:48 +05:30
Kovid Goyal
fd598df1c6 Add a one-time support option 2018-06-08 22:17:07 +05:30
Kovid Goyal
0cc008e737 Use TTYIO for the icat kitten as well 2018-06-08 20:21:05 +05:30
Kovid Goyal
5dbaf9aab0 Clean up usage of TTYIO for remote cmds and the shell 2018-06-08 20:17:27 +05:30
Kovid Goyal
71c1432892 Update glfw from upstream 2018-06-08 18:02:44 +05:30
Kovid Goyal
59ab22c0c8 Merge branch 'master' of https://github.com/dcolascione/kitty 2018-06-08 17:53:08 +05:30
Daniel Colascione
668f6fa257 More robustly strip bracketed paste termination sequence
The previous code performed only one replacement on the bracketed
paste content. This procedure didn't stop someone embedding the
terminating sequence anyway. POC:

1) $ x=$'\033[201~'; printf '%s%s%s\necho hello world\n' "${x:0:1}" "$x" "${x:1}" | xclip
2) paste into kitty
3) see the shell execute a command!

This patch closes this hole.
2018-06-08 04:53:02 -07:00
Kovid Goyal
5701ec4082 Remove duplicate import 2018-06-08 15:42:42 +05:30
Kovid Goyal
04afe969a0 Fix building on macOS with termios.h 2018-06-08 15:41:40 +05:30
Kovid Goyal
19721014d0 Remote control: Fix kitty @ sometimes failing to read the response from kitty.
Fixes #614
2018-06-08 15:35:01 +05:30
Kovid Goyal
44b84ba295 Update glfw from upstream 2018-06-08 14:27:30 +05:30
Kovid Goyal
f80f61f84f ... 2018-06-08 12:54:38 +05:30
Kovid Goyal
6247270011 Build the docs on Travis 2018-06-08 12:03:51 +05:30
Kovid Goyal
68394cebe3 Linux: Include a man page and the HTML docs when building the linux-package 2018-06-08 11:06:41 +05:30
Kovid Goyal
a386277df9 Release a source tarball that contains pre-built docs 2018-06-08 10:36:33 +05:30
Kovid Goyal
f88b98ccd9 Generate a simple man page with the output of kitty --help 2018-06-08 10:13:15 +05:30
Kovid Goyal
eecf80469e Update glfw from upstream
Adds glfwpostemptyevent not working fix to wayland backend as well
2018-06-08 09:14:14 +05:30
Kovid Goyal
66dd83027d Use pipe2() on non-Apple platforms 2018-06-08 08:15:12 +05:30
Kovid Goyal
a1355484a6 Use the process name as the default window title rather than "kitty"
Fixes #610
2018-06-07 23:23:10 +05:30
Kovid Goyal
ca17e9b02c ... 2018-06-07 22:23:15 +05:30
Kovid Goyal
dd085a9297 Update glfw from upstream
Fixes https://github.com/glfw/glfw/issues/1281
2018-06-07 21:46:01 +05:30
Kovid Goyal
6c72c93b02 Fix inactive_text_alpha also applying to the tab bar
Fixes #612
2018-06-07 20:19:29 +05:30
Kovid Goyal
223fe85449 Mention the kitty website in kitty --help 2018-06-07 18:22:39 +05:30
Kovid Goyal
365c992f80 Fix only one the two fds created by self_pipe having CLOEXEC and NONBLOCK set 2018-06-07 15:48:50 +05:30
Kovid Goyal
1dd489cf0c Add --chop-long-lines to the less invocation as it ensures line numbers are correct even if the scrollback window is narrower 2018-06-07 13:29:31 +05:30
Kovid Goyal
ed0239a556 When viewing the scrollback in less and kitty is currently scrolled, position the scrollback in less to match kitty's scroll position.
Fixes #148
2018-06-07 13:25:37 +05:30
Kovid Goyal
dbb94fc1ff Fix wrap markers not being added when getting the history buf as text 2018-06-07 13:12:15 +05:30
Kovid Goyal
b9dd434fab Add an option to control quit on last window behavior 2018-06-07 08:03:47 +05:30
Kovid Goyal
23d089b4be macOS: Add macOS standard shortcuts
For copy, paste and new OS window (⌘+C, ⌘+V, ⌘+N)
Only defined on macOS, not Linux, thanks to the new config
infrastructure.
2018-06-07 07:54:21 +05:30
Kovid Goyal
faa5443d43 macOS: When clicking dock icon with no windows, create a new window 2018-06-07 07:19:39 +05:30
Kovid Goyal
1afa91bbb4 macOS: Keep kitty running when the last window is closed
This is how applications are supposed to behave on macOS. Fixes #543
2018-06-07 06:19:36 +05:30
Kovid Goyal
908823166e NULL check 2018-06-07 05:52:55 +05:30
Kovid Goyal
6845dd115e Add a config option to hide window decorations under X11/Wayland
Fixes #607
2018-06-07 05:48:51 +05:30
Kovid Goyal
ad44e1a515 macOS: Fix crash when triggering some global menu actions with the mouse 2018-06-06 22:53:07 +05:30
Kovid Goyal
2e8d19601b macOS: Fix the new OS window keyboard shortcut not working if no kitty window currently has focus.
Fixes #524
2018-06-06 22:18:33 +05:30
Kovid Goyal
f259c23695 Use the binary install instructions on the front-page
Testing has revealed no problems with the binary installer, so
make it live. Fixes #595
2018-06-06 17:19:05 +05:30
Kovid Goyal
f75957d8c0 ... 2018-06-06 13:31:29 +05:30
Kovid Goyal
53ae5a4f8d A new tab bar style 2018-06-06 13:27:15 +05:30
Kovid Goyal
c76a8242e2 Make the icat kitten work even if stdout/stdin are redirected 2018-06-06 12:04:10 +05:30
Kovid Goyal
8a1a45b067 Allow the diff kitten to work even if stdout/stdin are redirected
Now directly opens /dev/tty
2018-06-06 12:01:47 +05:30
Kovid Goyal
8f433f5ff6 ... 2018-06-06 11:27:03 +05:30
Kovid Goyal
97c317b735 Make screen_size handling in tui cleaner
Now screen size is fetched only for output_fd rather than sys.stdout
2018-06-06 11:20:55 +05:30
Kovid Goyal
c8e9199b03 Refactor tab drawing code 2018-06-06 09:17:31 +05:30
Kovid Goyal
351e1a5a15 Tabulate consecutive maps 2018-06-05 14:06:57 +05:30
Kovid Goyal
7b1449ba46 Include sample conf files 2018-06-05 13:57:51 +05:30
Kovid Goyal
3983953e72 Indented blocks should also be doc-commented 2018-06-05 13:54:39 +05:30
Kovid Goyal
84ad0604f4 Wrap generated conf file 2018-06-05 13:22:09 +05:30
Kovid Goyal
c509c5eb0d Add custom syntax highlighting for conf and session files 2018-06-05 12:37:04 +05:30
Kovid Goyal
d39cf5d702 Get rid of the default diff.conf 2018-06-05 10:44:18 +05:30
Kovid Goyal
2b0d8bfe46 Get rid of the default kitty.conf 2018-06-05 09:17:31 +05:30
Kovid Goyal
61fc96b187 ... 2018-06-05 08:48:37 +05:30
Kovid Goyal
070e95b5e1 Make sphinx warnings fatal 2018-06-05 08:47:34 +05:30
Kovid Goyal
727028280a ... 2018-06-05 08:46:40 +05:30
Kovid Goyal
ea4a7136f0 Get rid of the |kitty.conf| substitution 2018-06-05 08:44:51 +05:30
Kovid Goyal
065a2b37c7 Get rid of the |sc_| substitution rules 2018-06-05 08:13:28 +05:30
Kovid Goyal
b5e452942e Port changes from master 2018-06-05 07:56:41 +05:30
Kovid Goyal
4fa8cb562a Finish adding shortcuts to docs 2018-06-05 07:52:31 +05:30
Kovid Goyal
429efd70ff More conf docs 2018-06-05 07:52:31 +05:30
Kovid Goyal
4c636fdeca More conf docs 2018-06-05 07:52:31 +05:30
Kovid Goyal
1168687923 More conf docs 2018-06-05 07:52:30 +05:30
Kovid Goyal
db32079bd8 More conf docs 2018-06-05 07:52:30 +05:30
Kovid Goyal
e7246fd024 Implement shortcuts in the RST docs 2018-06-05 07:52:30 +05:30
Kovid Goyal
1c93e2a94e Show full tracebacks on sphinx failure 2018-06-05 07:52:30 +05:30
Kovid Goyal
e8bd6f4493 Initial stab at adding shortcuts to the docs 2018-06-05 07:52:30 +05:30
Kovid Goyal
cd36e3b314 oops 2018-06-05 07:52:30 +05:30
Kovid Goyal
ad29d7f639 ... 2018-06-05 07:52:30 +05:30
Kovid Goyal
b98fca972f More conf docs
Add a 🔗 role that works nicely in both contexts
2018-06-05 07:52:29 +05:30
Kovid Goyal
c63c3d2844 More conf docs 2018-06-05 07:52:29 +05:30
Kovid Goyal
6c1434ab8a More conf docs
Also dont parse option values unnecessarily
2018-06-05 07:52:29 +05:30
Kovid Goyal
b6d33e2019 More conf docs 2018-06-05 07:52:29 +05:30
Kovid Goyal
97bd8b127f More conf docs 2018-06-05 07:52:29 +05:30
Kovid Goyal
2be45eeca3 More conf docs 2018-06-05 07:52:29 +05:30
Kovid Goyal
485fe0a7fb Allow linking to latter options in a option group 2018-06-05 07:52:29 +05:30
Kovid Goyal
0070e0a58a More conf docs 2018-06-05 07:52:29 +05:30
Kovid Goyal
f7fe59dfbe Allow multiple conf files to be processed for cross-references 2018-06-05 07:52:28 +05:30
Kovid Goyal
fd731feacc Warn about missing opt references 2018-06-05 07:52:28 +05:30
Kovid Goyal
61194ef1c8 Use a custom sphinx role for the conf file 2018-06-05 07:52:28 +05:30
Kovid Goyal
dadbaf9ab1 More conf docs 2018-06-05 07:52:28 +05:30
Kovid Goyal
ffdb91ffd5 More work on the conf docs 2018-06-05 07:52:28 +05:30
Kovid Goyal
2ae3157d49 Simplify by using the option definition as a title 2018-06-05 07:52:28 +05:30
Kovid Goyal
1c2c98c1a4 More conf docs 2018-06-05 07:52:28 +05:30
Kovid Goyal
8d446d15e8 Add vim header to generated conf file 2018-06-05 07:52:28 +05:30
Kovid Goyal
faddcd34d2 More conf docs 2018-06-05 07:52:27 +05:30
Kovid Goyal
8c7e618324 Implement referring to config options 2018-06-05 07:52:27 +05:30
Kovid Goyal
cdb1fc8602 More work on conf docs 2018-06-05 07:52:27 +05:30
Kovid Goyal
9dc9fb2012 Start work on documenting the conf file 2018-06-05 07:52:27 +05:30
Kovid Goyal
3ce9e1932c Merge branch 'master' of https://github.com/ricci/kitty 2018-06-05 07:41:57 +05:30
Robert Ricci
da6ad5df45 Switch to generic hash instead of sha1 specifically
Suggested by @maximbaz
2018-06-04 15:43:03 -06:00
Robert Ricci
a9f394ce18 Fix stray text 2018-06-04 14:28:35 -06:00
Robert Ricci
093921cb9a Add support for sha1 hashes to the hint kitten
This is specifically intended for git commit hashes, so it allows for
hashes as short as 7 characters (git's default length for abbreviated
hashes) up to the full 40 characters
2018-06-04 14:25:38 -06:00
Kovid Goyal
c9818e7bb1 ... 2018-06-04 15:14:16 +05:30
Kovid Goyal
c8bf7763b6 Merge branch 'foldmethod' of https://github.com/gibfahn/kitty 2018-06-03 23:01:06 +05:30
Gibson Fahnestock
00446fa2c4 Set foldmethod in kitty.conf
As this is copied to other people's computers, it's useful to have this
set so folding always works nicely.
2018-06-03 13:36:37 +01:00
Kovid Goyal
7cf6b8b594 Move the config utils into its own package 2018-06-03 11:54:26 +05:30
Kovid Goyal
088766da72 Build the logo on Travis before running osx-bundle 2018-06-03 09:58:58 +05:30
Kovid Goyal
1c1b04b1d9 Build osx-bundle not linux-package on Travis on macOS 2018-06-03 09:41:02 +05:30
Kovid Goyal
29734563b4 Fix typo in threading.h introduced by FreeBSD commits 2018-06-03 09:29:33 +05:30
Kovid Goyal
b6e330e3e7 Remove trailing whitespace from more files 2018-06-03 09:24:15 +05:30
Kovid Goyal
138b4cf5da Fix build breakage caused by FreeBSD support
Also move the changes to the glfw files to glfw.py
2018-06-03 09:17:18 +05:30
Kovid Goyal
92e86a3b28 Merge branch 'master' of https://github.com/ricci/kitty into t 2018-06-03 08:58:37 +05:30
Robert Ricci
dc48e6c432 Clean up nested ifdefs 2018-06-02 12:48:38 -06:00
Robert Ricci
80da4d1344 Handle pthread_setname_np on FreeBSD
For some reason, the function has a slightly different name and
signature
2018-06-02 12:05:49 -06:00
Robert Ricci
e7ad2637d8 Don't 'hardcode' linux joystick for x11 module
The correct joystick module appears to be inserted in the list in
glfw.py . This fixes the build on FreeBSD 11
2018-06-02 11:46:10 -06:00
Robert Ricci
8e84b21452 Re-order includes for "_POSIX_C_SOURCE"
One FreeBSD, the build was getting errors about _POSIX_C_SOURCE
being redefined. The fix for this is to make sure that Python.h
gets included before any system libraries.
2018-06-02 11:26:02 -06:00
Kovid Goyal
5674dc5bfc ... 2018-06-02 20:24:37 +05:30
Kovid Goyal
1b9c5522fb Move tab bar into its own module 2018-06-02 20:22:27 +05:30
Kovid Goyal
71bdf73884 ... 2018-06-02 15:13:15 +05:30
Kovid Goyal
8d04216c2b Update CHANGELOG 2018-06-02 15:04:45 +05:30
Kovid Goyal
620782aa80 Document the icat kitten 2018-06-02 14:45:46 +05:30
Kovid Goyal
bd9a4e9cd8 Dont hardcode the ssh options 2018-06-02 14:30:05 +05:30
Kovid Goyal
af6ff15ee2 Wayland: Fix wheel/touchpad scrolling in opposite direction
Workaround for glfw bug. Fixes #594
2018-06-02 13:25:33 +05:30
Kovid Goyal
bb8e0e7789 Add CLI docs for the diff kitten 2018-06-02 13:09:18 +05:30
Kovid Goyal
4448d2dc7f ... 2018-06-02 13:06:49 +05:30
Kovid Goyal
7236e0ff21 Add CLI docs for the hints kitten 2018-06-02 13:04:25 +05:30
Kovid Goyal
9a615efa83 Document CLI of panel kitten 2018-06-02 12:24:21 +05:30
Kovid Goyal
f857b1afd3 Add a --debug-keyboard command line option
It's a little more discoverable than the env var.
2018-06-02 12:08:13 +05:30
Kovid Goyal
5cd9af6c37 ... 2018-06-02 11:29:07 +05:30
Kovid Goyal
ec0edd6f45 A new kitten to draw dock panels on X11 desktops showing the output from running arbitrary terminal programs 2018-06-02 11:27:01 +05:30
Kovid Goyal
0f82f90968 ... 2018-06-02 09:29:53 +05:30
Kovid Goyal
06237b85f5 Only add to server_args unconditionally if two non-option args have been seen 2018-06-01 22:55:13 +05:30
Kovid Goyal
d319180e88 ... 2018-06-01 22:48:19 +05:30
Kovid Goyal
d8f5dc958d ssh kitten: Handle combined single character options 2018-06-01 22:47:07 +05:30
Kovid Goyal
5b31b237e3 ... 2018-06-01 21:44:28 +05:30
Kovid Goyal
e211589f9f Binary install instructions 2018-06-01 21:42:49 +05:30
Kovid Goyal
cd80a85d2d ssh kitten: Dont transfer terminfo if any of the -Nnf arguments are passed to ssh 2018-06-01 20:33:57 +05:30
Kovid Goyal
b752d1ca48 Publish installer.sh 2018-06-01 20:04:15 +05:30
Kovid Goyal
091e74d618 Run the linux bundle on Travis 2018-06-01 19:22:08 +05:30
Kovid Goyal
35fb8ea1bf Linux installer 2018-06-01 14:56:05 +05:30
Kovid Goyal
b6c8b4f124 Add an INSTALL file that points to the building from source instructions 2018-06-01 14:49:26 +05:30
Kovid Goyal
9ed703384f Add some command line options to the installer 2018-06-01 11:18:29 +05:30
Kovid Goyal
e259fc5250 macOS installer implemented 2018-06-01 11:04:16 +05:30
Kovid Goyal
8b08182555 Start work on an installer 2018-06-01 10:31:52 +05:30
Kovid Goyal
4e6d929e20 Update glfw from upstream 2018-06-01 09:15:35 +05:30
Kovid Goyal
0d7feb0404 ssh kitten: Allow specifying args to pass to ssh
Uses the same syntax as the ssh command. Note that currently specifying
-N -f or similar will not work (it does not make sense anyway as you
only use this kitten if you plan on an interactive ssh session).
Fixes #591
2018-06-01 07:42:25 +05:30
Kovid Goyal
1dc9adebb4 Add an option to @set-window-title to make the change overridable 2018-06-01 06:49:47 +05:30
Kovid Goyal
d89861f601 Code to support the linux bundle 2018-05-31 23:02:38 +05:30
Kovid Goyal
0354e5b669 Add a PNG load test that does not depend on PIL 2018-05-31 20:15:23 +05:30
Kovid Goyal
98ec3fe18f Documentation work 2018-05-31 16:15:43 +05:30
Kovid Goyal
e12f5209fb Dont install libunistring on travis
No longer needed
2018-05-31 13:43:36 +05:30
Kovid Goyal
77d149518c Documentation work 2018-05-31 08:40:32 +05:30
Kovid Goyal
087f13f293 Documentation work 2018-05-31 08:30:01 +05:30
Kovid Goyal
8d8224812d Use modern GA loading code 2018-05-30 20:28:48 +05:30
Kovid Goyal
489ed6a915 Improve presentation of screenshots 2018-05-30 20:04:49 +05:30
Kovid Goyal
98bcbf8150 Partition dependency list 2018-05-30 19:45:14 +05:30
Kovid Goyal
1fe81872c6 Add the build badge to the build from source page 2018-05-30 19:43:02 +05:30
Kovid Goyal
fb0db2b7df Document kitty @ 2018-05-30 19:35:54 +05:30
Kovid Goyal
28803d9a5a Use rst roles to format cli help text 2018-05-30 19:07:12 +05:30
Kovid Goyal
fba37e73e7 ... 2018-05-30 17:52:55 +05:30
Kovid Goyal
f8fa76d77e Use program directives to namespace options 2018-05-30 15:32:50 +05:30
Kovid Goyal
a3e4c74f5d Add command line API reference 2018-05-30 15:14:07 +05:30
Kovid Goyal
0667027506 ... 2018-05-30 13:45:27 +05:30
Kovid Goyal
0c5c6fcbbe Make the sidebar a little nicer 2018-05-30 13:43:48 +05:30
Kovid Goyal
bf8dfa5ee3 Add a link to the kittens on the front page 2018-05-30 13:11:26 +05:30
Kovid Goyal
f6d0cadcc5 Redirect old asciidoc pages to new website 2018-05-30 12:52:59 +05:30
Kovid Goyal
611d95f0f7 Add the CHANGELOG to the docs 2018-05-30 12:46:00 +05:30
Kovid Goyal
bbc1430420 Add a support page
Also fix a few links flagged by make linkcheck
2018-05-30 12:08:20 +05:30
Kovid Goyal
61f7ce4dee Dont use emoji for search as it does not render well in Chrome 2018-05-30 10:42:25 +05:30
Kovid Goyal
e4163fca6a Add website publish code 2018-05-30 10:41:37 +05:30
Kovid Goyal
21d7cc1a60 Configure the alabaster theme a bit
And remove duplicated FAQ from README
2018-05-30 09:44:53 +05:30
Kovid Goyal
f82b7841c6 Start work on a kitty website
Port the current asciidoc documentation to sphinx
2018-05-29 21:03:50 +05:30
Kovid Goyal
edda0d91bb ... 2018-05-29 08:22:14 +05:30
Kovid Goyal
c70200ada0 ... 2018-05-29 08:20:11 +05:30
Kovid Goyal
adccc8fea4 When closing a tab switch to the last active tab instead of the rightmost tab. Fixes #585 2018-05-29 08:06:33 +05:30
Kovid Goyal
b886b4c6b2 Ensure font data is free'd before other finalizers
Fixes #583
2018-05-29 07:18:07 +05:30
Kovid Goyal
9eb113802d Add a setting to control the margins to the left and right of the tab bar
Fixes #584
2018-05-28 21:59:45 +05:30
Kovid Goyal
dab57f3819 When receiving contiguous non-empty OSC 52 clipboard writes, combine them.
Max combined text is set at 1MB. Allows sending texts larger than the
escape code size limit.
2018-05-28 21:50:42 +05:30
Kovid Goyal
88d0499818 If non-base64 encoded data sent via OSC 52 clear the clipboard as suggested by xterm docs 2018-05-28 21:26:59 +05:30
Kovid Goyal
51706ed195 Fix inverted permission check for write-clipboard 2018-05-28 21:18:39 +05:30
Kovid Goyal
7332561d8e Add in the redundant ctrl+<234578`> key combinations in normal and application mode. They all conflict with other keys but by implementing them the same as other terminals, I can at least avoid having to explain how they Ctrl+number is broken in traditional terminals over and over again. 2018-05-28 20:37:48 +05:30
Kovid Goyal
daafea7f7e Don't add a newline at the end of the size output 2018-05-28 14:19:12 +05:30
Kovid Goyal
5f7bc8bff2 Opening for reading is sufficient 2018-05-28 14:11:10 +05:30
Kovid Goyal
8809b8db56 Make --print-screen-size work when stdout is redirected 2018-05-28 14:09:52 +05:30
Kovid Goyal
686a5f7baf Update some missing shortcut definitions 2018-05-28 14:03:28 +05:30
Kovid Goyal
020b6b582d ... 2018-05-28 14:00:04 +05:30
Kovid Goyal
64ed8daf59 Add clipboard shortcuts to the readme 2018-05-28 13:58:57 +05:30
Kovid Goyal
dd20789249 Add support for the CSI t escape code to query window and cell sizes 2018-05-28 13:47:42 +05:30
Kovid Goyal
6570565e2d Rename --print-screen-size to --print-window-size
We are reporting the size (inner area) of the terminal window, not the
full screen.
2018-05-28 13:14:42 +05:30
Kovid Goyal
345b3437f4 Add a config option to set the EDITOR kitty uses
Useful on systems that make it hard to set system-wide environment
variables. See #580
2018-05-28 12:24:09 +05:30
Kovid Goyal
20611c7c15 Add a convenience option to kitty icat to print the screen size 2018-05-28 10:11:19 +05:30
Kovid Goyal
8dea5b3e3e Reduce data sent to GPU per draw by 30%
Split up the Cell structure into a CPUCell and a GPUCell. Only the
GPUCell part needs to be sent to the GPU. Should make kitty use even
less system resources and make a performance difference on systems where
the GPU bandwidth is constrained.

Also allows adding more CPU only data in the future without affecting
GPU bandwidth. For example, hyperlinks or more combining characters.
2018-05-27 21:25:09 +05:30
Kovid Goyal
c8756612f7 ... 2018-05-27 12:37:50 +05:30
Kovid Goyal
9fe995c7d8 Workaround for GLFW not working with the wlroots wayland compositor 2018-05-27 12:37:50 +05:30
Kovid Goyal
422bcfcb54 ... 2018-05-27 12:37:50 +05:30
Kovid Goyal
3b04776956 Show the window much sooner after creating it
Do not make any OpenGL calls between creation and showing of the window.
Hopefully, that will make the fussy wlroots happy.
2018-05-27 12:37:50 +05:30
Kovid Goyal
1ba76508de More detailed error message when cursor creation fails 2018-05-27 12:37:49 +05:30
Kovid Goyal
4e09a518d5 Don't initialize OpenGL for the temp window as it is not needed
Also dont fail to start if cursor creation fails, since cursor shapes
are not critical.
2018-05-27 12:37:49 +05:30
Kovid Goyal
e056460f0b Split up creation of font group and sending of sprites to GPU 2018-05-27 12:37:49 +05:30
Kovid Goyal
da166aef99 API to control smallest allowed resize from python 2018-05-27 12:37:49 +05:30
Kovid Goyal
a42bc3bf8c oops 2018-05-27 12:37:49 +05:30
Kovid Goyal
997c244664 Allow specifying initial window size in number of cells 2018-05-27 12:37:49 +05:30
Kovid Goyal
fe8cf46d56 Handle window DPI changes 2018-05-27 12:37:49 +05:30
Kovid Goyal
df9eab279a Implement changing the font size for individual top level (OS) windows 2018-05-27 12:37:49 +05:30
Kovid Goyal
b14c9614e0 DRYer 2018-05-27 12:37:05 +05:30
Kovid Goyal
ed44515318 All tests pass 2018-05-27 12:37:05 +05:30
Kovid Goyal
523aadaa3b Refactor font group handling
Allow kitty to manage multiple groups of fonts with different cell
sizes. Will eventually allow kitty to have different font sizes/dpi per
OSWindow
2018-05-27 12:37:05 +05:30
Kovid Goyal
4f18342ea6 Linux: Fix fonts not being correctly read from TrueType Collection (.ttc) files.
kitty was always selecting the first font rather than the
actual matched font. Fixes #577
2018-05-27 12:30:28 +05:30
Kovid Goyal
f36e6f0461 Nicer handling of empty lines 2018-05-26 13:40:43 +05:30
Kovid Goyal
978dc008e2 hints kitten: Fix a regression that caused some blank lines to be not displayed 2018-05-26 13:35:44 +05:30
Kovid Goyal
94f1759b14 Update README 2018-05-24 19:31:08 +05:30
Kovid Goyal
a4af0599cc version 0.10.1 2018-05-24 19:26:12 +05:30
Kovid Goyal
de4384a420 tui: Use correct key names for enter and backspace keys 2018-05-24 15:23:34 +05:30
Kovid Goyal
a33ebce3c9 diff kitten: Add keybindings to scroll by a page 2018-05-24 15:17:03 +05:30
Kovid Goyal
219d3161d9 diff kitten: Fix incorrect syntax highlighting with a few file formats such as yaml 2018-05-24 15:00:26 +05:30
Kovid Goyal
2e07159461 macOS: Fix regression that caused the macos_option_al_alt setting to always be set to no for all os windows ina kitty instance after the first. Fixes #571 2018-05-24 09:14:13 +05:30
Kovid Goyal
23d0f5ce32 Preserve line numbers when adding in shifts to shader 2018-05-23 19:41:54 +05:30
Kovid Goyal
f4792a1e3d Add link to diff kitten in main README 2018-05-23 13:38:44 +05:30
Kovid Goyal
2a5ef628fa DRYer 2018-05-23 13:25:46 +05:30
Kovid Goyal
4b259dd719 diff kitten: Make the keyboard shortcuts configurable
Fixes #563
2018-05-23 13:10:32 +05:30
Kovid Goyal
c127476c4e ... 2018-05-23 09:56:53 +05:30
Kovid Goyal
beded75547 Make ssh kitten work with the execrable dash shell 2018-05-23 09:54:33 +05:30
Kovid Goyal
74a6cdb3bb ... 2018-05-23 09:35:57 +05:30
Kovid Goyal
ba554fb01d ... 2018-05-23 09:35:29 +05:30
Kovid Goyal
39c98e83da Cleanup key action with arguments parsing 2018-05-23 09:32:52 +05:30
Kovid Goyal
73660f7119 ... 2018-05-23 09:15:27 +05:30
Kovid Goyal
46b4f33850 A nice error message when using shortcuts to change background_opacity without setting dynamic_background_opacity
Also change the default shortcuts
2018-05-23 09:14:10 +05:30
Kovid Goyal
ad8e16aac0 ... 2018-05-23 08:50:19 +05:30
Kovid Goyal
ae6e082419 Keyboard shortcuts to control background opacity 2018-05-23 08:48:59 +05:30
Kovid Goyal
f46d3057ba Add an example of setting environment variables in a session file 2018-05-23 08:28:18 +05:30
Kovid Goyal
8e0e4b8fd1 cmds: Check for extra arguments 2018-05-23 08:24:08 +05:30
Kovid Goyal
76da315f81 ... 2018-05-23 08:19:30 +05:30
Kovid Goyal
95de39feb9 Nice error message when dynamic_background_opacity is not set 2018-05-23 08:16:22 +05:30
Kovid Goyal
c0f790c928 Add a remote command to control window opacity
Fixes #569
2018-05-23 08:13:37 +05:30
Kovid Goyal
6fbb953aa4 Add a note about needing a temp file for tic 2018-05-22 23:18:11 +05:30
Kovid Goyal
30b38e9fa0 Drop the requirement for having python on the server when using the ssh kitten 2018-05-22 23:15:24 +05:30
Kovid Goyal
d20e801793 Add a kitten to easily ssh into servers that automatically copies the terminfo files over 2018-05-22 22:32:51 +05:30
Kovid Goyal
fe65b346c1 Fix Ctrl+Alt+Space not working in normal and application keyboard modes.
Fixes #562
2018-05-22 14:52:00 +05:30
Kovid Goyal
c5da1c0f1b Update link to Debian package 2018-05-22 10:44:36 +05:30
Kovid Goyal
3fd2f03f11 Print failure message to standard error 2018-05-21 23:26:57 +05:30
Kovid Goyal
4ad4e28a9c ... 2018-05-21 23:25:59 +05:30
Kovid Goyal
d3edd2e73f Add a kitten to get/set the clipboard via OSC 52 2018-05-21 23:24:27 +05:30
Kovid Goyal
3d37348c2b ... 2018-05-21 23:17:44 +05:30
Kovid Goyal
8a3e81b7ba Send an empty response to clipboard queries if reading from clipboard is not allowed or the clipboard is empty
Prevents utilities from hanging when querying the clipboard. Also fix 52
prefix missing from the OSC response.
2018-05-21 23:17:39 +05:30
Kovid Goyal
a29c317217 Add code to disable terminal echo to non_blocking_read 2018-05-21 22:09:34 +05:30
Kovid Goyal
48847cdaf8 hints kitten: Fix detection of URLs in ReStructuredText 2018-05-21 16:14:49 +05:30
Kovid Goyal
a59cda8b60 ... 2018-05-21 16:02:24 +05:30
Kovid Goyal
e70b5114fb diff kitten: resolve symlinks before passing paths to the diff tool 2018-05-21 15:50:28 +05:30
Kovid Goyal
d2ab7fbb36 Add a ref 2018-05-21 14:17:21 +05:30
Kovid Goyal
70352ca722 kittens: Don't fail on systems that return invalid values for SC_IOV_MAX. Fixes #558 2018-05-21 12:22:46 +05:30
Kovid Goyal
be28e7bf46 Update README 2018-05-21 11:30:19 +05:30
Kovid Goyal
6b2b8e0208 ... 2018-05-21 11:00:24 +05:30
Kovid Goyal
c997dc8ea7 Add a link to the default diff.conf 2018-05-21 10:59:10 +05:30
Kovid Goyal
f52afbb396 Add a reference to kitty-diff as a program that uses the kitty graphics protocol 2018-05-21 10:53:31 +05:30
Kovid Goyal
a20e7e2a6b Add a note about why kitty-diff is kitty only 2018-05-21 10:51:50 +05:30
Kovid Goyal
9903b8e8db version 0.10.0 2018-05-21 09:50:36 +05:30
Kovid Goyal
1d18f63eb5 Update README 2018-05-21 09:06:19 +05:30
Kovid Goyal
a63682b160 ... 2018-05-20 18:35:46 +05:30
Kovid Goyal
812f3e60ca ... 2018-05-20 18:35:15 +05:30
Kovid Goyal
f8f5838ab5 Update CHANGELOG 2018-05-20 18:34:07 +05:30
Kovid Goyal
07782e071a Update CHANGELOG 2018-05-20 18:09:08 +05:30
Kovid Goyal
624dfdf913 Update README 2018-05-20 17:33:09 +05:30
Kovid Goyal
a01dad8c3c Render the shade unicode box characters as per the spec 2018-05-20 16:34:17 +05:30
Kovid Goyal
b6baa99fce diff kitten: Make the representation of tabs configurable 2018-05-20 15:37:52 +05:30
Kovid Goyal
912b395316 diff kitten: Render tabs as four spaces instead of <9> 2018-05-20 15:29:12 +05:30
Kovid Goyal
b1b90d2bf7 Replace tabs in README 2018-05-20 15:17:19 +05:30
Kovid Goyal
37bd964fee Add some notes about integrating with git 2018-05-20 15:12:21 +05:30
Kovid Goyal
fa3e173c18 diff kitten: Report errors converting images 2018-05-20 15:01:25 +05:30
Kovid Goyal
2a9dc23c61 ... 2018-05-20 12:44:16 +05:30
Kovid Goyal
2885f54360 Add README for diff kitten 2018-05-20 12:41:40 +05:30
Kovid Goyal
ac2f4c8ab6 Nicer window title for the diff kitten 2018-05-20 12:26:14 +05:30
Kovid Goyal
7282d8edc1 Add an option to control how much dimming SGR dim does 2018-05-20 11:00:13 +05:30
Kovid Goyal
6f2d63eb87 Implement SGR dim
kitty now supports the SGR DIM escape code, which makes text fade into
the background. It works by alpha blending the text color into the
background color. Fixes #446
2018-05-20 10:43:26 +05:30
Kovid Goyal
9cab8a2de5 diff kitten: Do not specify the default foreground color in formatting codes.
Fixes an issue with foreground color being incorrect after a highlighted
segment if the syntax highlight does not specify a foreground color at
the boundary.
2018-05-20 08:51:41 +05:30
Kovid Goyal
709d19119d Update bundled glfw 2018-05-20 08:03:58 +05:30
Kovid Goyal
029b82807c Ignore \ prefixed lines when parsing patches 2018-05-19 23:02:49 +05:30
Kovid Goyal
67c0942e01 Fix error reporting in the diff kitten 2018-05-19 22:51:02 +05:30
Kovid Goyal
fb57653665 Make debugging kittens a little nicer
Now debug() writes to the stderr of the parent kitty process instead of
a temp file.
2018-05-19 16:32:08 +05:30
Kovid Goyal
646a349d82 ... 2018-05-19 15:11:08 +05:30
Kovid Goyal
ad1109b6fe Hints kitten: Overhaul making it more intelligent
It now uses information about the geometry of the screen.
So URLs that stretch over multiple lines are detected even if there is a
hard line break in between (some programs like mutt generate these).
2018-05-19 14:31:00 +05:30
Kovid Goyal
c2bd6a66d9 ... 2018-05-19 08:49:03 +05:30
Kovid Goyal
ba9af3df8c Fix moving cursor outside a defined page area incorrectly causing the cursor to be placed inside the page area. Caused incorrect rendering in neovim, which relies on this behavior.
Fixes #542
2018-05-19 08:04:37 +05:30
Kovid Goyal
5d4e968f50 Allow commenting lines in command logs 2018-05-19 07:33:29 +05:30
Kovid Goyal
0e327f3d13 Allow kittens to ask for wrap markers 2018-05-18 23:09:27 +05:30
Kovid Goyal
bb06bfa627 Cleanup the as_text_generic macro
Also allow adding a \r at the end of each visual line
2018-05-18 23:06:06 +05:30
Kovid Goyal
2a713cab60 kittens should specify their own required input type
It is DRYer. Also replace the run_kitten function with just kitten that
takes no type of input argument. Backward compat for run_kitten is
maintained.
2018-05-18 22:55:42 +05:30
Kovid Goyal
26df57a1c7 More elegant handling for pressing enter with no valid current input in the hints kitten 2018-05-18 21:28:43 +05:30
Kovid Goyal
18893f86ce Render a couple more powerline symbols directly, bypassing the font
There are apparently a set of "extra" powerline glyphs that need to be
boundary aligned. https://github.com/ryanoasis/powerline-extra-symbols
Fixes #550
2018-05-18 19:20:10 +05:30
Kovid Goyal
8fead5ebe8 Add a test function to test drawing of single box characters easily 2018-05-18 15:43:40 +05:30
Kovid Goyal
6020aadbf2 diff kitten: Show overall diff stats 2018-05-18 14:19:25 +05:30
Kovid Goyal
f8b6b532e0 diff kitten: Show scroll % 2018-05-18 13:36:12 +05:30
Kovid Goyal
05ec174868 @resize-window now has a useful return code 2018-05-18 00:01:31 +05:30
Kovid Goyal
3875ee021a re-org screenshots 2018-05-17 23:53:36 +05:30
Kovid Goyal
2931afa0ae Fix vertical biasing of last window in grid not working when number of windows is odd 2018-05-17 23:42:37 +05:30
Kovid Goyal
2803e45380 Fix swapped row/col when biasing grid layout 2018-05-17 23:39:29 +05:30
Kovid Goyal
965dde599e Cleanup layout.py 2018-05-17 23:34:41 +05:30
Kovid Goyal
229ea45d81 ... 2018-05-17 23:27:35 +05:30
Kovid Goyal
8ea84c97d5 Use an overlay window for window resizing
Also implement a remote command to resize windows
2018-05-17 23:26:41 +05:30
Kovid Goyal
7c47bd547f Fix ctrl+alt+<special> not working in normal and application keyboard modes.
Fixes #548
2018-05-17 20:43:18 +05:30
Kovid Goyal
6ae58e6882 Add a couple more functions to --replay-commands 2018-05-17 20:15:59 +05:30
Kovid Goyal
3bc0f90a82 Fix incorrect parsing of --replay-commands 2018-05-17 20:06:59 +05:30
Kovid Goyal
2a99ef254f Dont segfault when printing a freetype font object with a NULL postscript name 2018-05-17 19:49:31 +05:30
Kovid Goyal
5bc811f26e Improve the help text for --replay-commands 2018-05-17 19:42:46 +05:30
Kovid Goyal
83893d762a Implement resizing for the grid layout 2018-05-17 18:47:41 +05:30
Kovid Goyal
24bed6273b Simplify grid layout code some more 2018-05-17 17:47:42 +05:30
Kovid Goyal
2a5b314f67 Simplify grid layout code 2018-05-17 17:20:09 +05:30
Kovid Goyal
e3c9fc3fba DRYer 2018-05-17 17:17:03 +05:30
Kovid Goyal
b81700a8fd DRYer 2018-05-17 17:12:24 +05:30
Kovid Goyal
b319fd4b93 Implement resizing for vertical and horizontal layouts 2018-05-17 17:09:03 +05:30
Kovid Goyal
23d6995558 ... 2018-05-17 16:50:16 +05:30
Kovid Goyal
190612d507 Make the resize step size configurable 2018-05-17 16:48:35 +05:30
Kovid Goyal
cddfe425e1 Dont keep increasing bias in Tall layout when it wont change the actual layout
Also refactor the bias code so that it is shared with the fat layout.
2018-05-17 16:02:42 +05:30
Kovid Goyal
bc6a03a41b Implement resizing for the Fat layout 2018-05-17 15:19:05 +05:30
Kovid Goyal
e053d1f566 Implement resizing of individual windows in a layout
See the Layouts section in the README for details. Fixes #362

Note that it is only implemented for the Tall layout currently. Other
layouts to follow. The implementation might also be refined in the
future.
2018-05-17 15:09:41 +05:30
Kovid Goyal
e429b8484c Update kitty invocation when preprocessing README 2018-05-17 14:56:52 +05:30
Kovid Goyal
22159c5eb4 Fix mockup for testing 2018-05-16 16:43:39 +05:30
Kovid Goyal
903df9972a ... 2018-05-16 16:25:41 +05:30
Kovid Goyal
4dcbb1f077 Avoid needless re-allocation of Layout objects on layout change
Also allows layout instance data to be preserved when cycling layouts
2018-05-16 16:24:31 +05:30
Kovid Goyal
5158d49781 Generalize bias handling 2018-05-16 15:57:04 +05:30
Kovid Goyal
3fdf47c535 Allow specifying the width of the tall window in the Tall layout as a percentage of available space
Also remove the --window-layout option as it was redundant. Same effect
can be achieved using -o enabled_layouts=some_layout,*
2018-05-16 14:02:58 +05:30
Kovid Goyal
b59d1bda8b Add a comment for RTL shaping 2018-05-16 07:00:36 +05:30
Kovid Goyal
1760fb9db2 Partial fix for rendering RTL languages like arabic 2018-05-16 06:56:16 +05:30
Kovid Goyal
082c771fc0 Fix typo in conf file 2018-05-16 00:08:52 +05:30
Kovid Goyal
7ec989d485 Fix Ctrl+backspace acting as plain backspace in normal and application keyboard modes. Fixes #538 2018-05-16 00:07:54 +05:30
Kovid Goyal
0f9613eb9e ... 2018-05-11 06:15:26 +05:30
Kovid Goyal
85a354351a ... 2018-05-11 06:06:18 +05:30
Kovid Goyal
24db8cef4f Merge branch 'add-fat-layout' of https://github.com/theJian/kitty 2018-05-11 05:23:14 +05:30
theJian
9908eee40c Update readme 2018-05-11 01:00:29 +08:00
theJian
b6517758d9 Add fat layout 2018-05-11 00:59:46 +08:00
Kovid Goyal
029500f3ed Store fd for screen_size at creation time 2018-05-10 18:27:18 +05:30
Kovid Goyal
686727a7c3 Nicer hooks for kitty-bar
Allows kitty-bar to be refactored into a pure CLI app
2018-05-10 17:47:51 +05:30
Kovid Goyal
91a1d61cc6 diff: Fix margins not being reset on exit 2018-05-10 16:21:26 +05:30
Kovid Goyal
b8e9921f3d Forgot this file in previous commit 2018-05-10 16:20:58 +05:30
Kovid Goyal
e0ce5d5629 tui: Cleanup unhandled exception processing
Also handler finalization should happen before term manager
finalization.
2018-05-10 16:20:33 +05:30
Kovid Goyal
ed511c296c Avoid needing to resend images on every draw_screen() 2018-05-10 15:58:52 +05:30
Kovid Goyal
eab1fbbbb0 diff: Mark displayed images as change starts 2018-05-10 15:29:53 +05:30
Kovid Goyal
ee3b052a50 tui: Preserve cursor position when placing images 2018-05-10 15:27:35 +05:30
Kovid Goyal
5b98f15d9b typo in comment 2018-05-10 15:15:02 +05:30
Kovid Goyal
51d76e5a2b ... 2018-05-10 14:37:43 +05:30
Kovid Goyal
a6bce0b221 diff: More work on showing images 2018-05-10 14:33:09 +05:30
Kovid Goyal
fb5dc8a2ba A spot of refactoring 2018-05-10 11:52:51 +05:30
Kovid Goyal
d571ee0d01 diff: More work on displaying images 2018-05-10 11:50:46 +05:30
Kovid Goyal
5d7ed67316 diff: More work on displaying images 2018-05-10 10:36:50 +05:30
Kovid Goyal
9f6c754339 Add a note about KITTY_WINDOW_ID 2018-05-10 10:27:34 +05:30
Kovid Goyal
2819a4ebf3 ... 2018-05-10 09:53:17 +05:30
Kovid Goyal
dec1203ea8 Make the kitty window id available as the environment variable KITTY_WINDOW_ID
Fixes #532
2018-05-10 08:52:28 +05:30
Kovid Goyal
87ab0d7b18 Make it clear that focus-window focuses the window it is run inside by default. 2018-05-10 08:46:38 +05:30
Kovid Goyal
043530409c DRYer 2018-05-10 07:47:29 +05:30
Kovid Goyal
9710282d22 Have the paste_from_selection action paste from the clipboard on platforms that do not have a primary selection such as Wayland and macOS. Fixes #529 2018-05-10 07:42:03 +05:30
Kovid Goyal
5e8e141fb5 Fix cursor_stop_blinking_after=0 not working. Fixes #530 2018-05-10 07:31:53 +05:30
Kovid Goyal
2e313fbdd2 Better exception for image conversion failure 2018-05-09 20:50:56 +05:30
Kovid Goyal
5c3e4db05f DRYer 2018-05-09 20:36:53 +05:30
Kovid Goyal
2be2f6aa0c Make icat a kitten
The kittens framework did not exist when icat was first written.
2018-05-09 20:26:30 +05:30
Kovid Goyal
6d038f5cdf Pass the image manager to the render code 2018-05-09 20:12:39 +05:30
Kovid Goyal
27feccba39 diff: More work on image support 2018-05-09 19:41:37 +05:30
Kovid Goyal
7d39d5c088 Ensure only a single screen size function is used 2018-05-09 14:14:09 +05:30
Kovid Goyal
2e69b904da diff: More work on images 2018-05-09 14:06:15 +05:30
Kovid Goyal
79dcc8c771 Don't search in names.h 2018-05-09 11:32:22 +05:30
Kovid Goyal
683e5a4754 DRYer 2018-05-09 11:32:09 +05:30
Kovid Goyal
d51a424b98 diff: Start work on image display 2018-05-09 10:25:53 +05:30
Kovid Goyal
e07d216a11 Expand environment variables in config file include directives 2018-05-09 09:35:50 +05:30
Kovid Goyal
b9fa8dbe42 DRYer 2018-05-09 09:28:38 +05:30
Kovid Goyal
3820c46801 Ensure there is a blank line before each new item 2018-05-09 08:33:24 +05:30
Kovid Goyal
b663160bc2 Fix rendering of binary files 2018-05-09 08:17:52 +05:30
Kovid Goyal
a65c807a4a diff: Add keyboard shortcuts to got to next/previous change 2018-05-09 08:12:40 +05:30
Kovid Goyal
3a1f85cb69 diff: Make the diff implementation configurable 2018-05-08 23:32:21 +05:30
Kovid Goyal
196bd9c22b Allow setting the number of context lines in diff.conf 2018-05-08 23:17:40 +05:30
Kovid Goyal
9bf2087b55 Better error message when pygments style is not found 2018-05-08 23:13:50 +05:30
Kovid Goyal
51e589c7e6 diff: Add a option for pygments style 2018-05-08 23:08:20 +05:30
Kovid Goyal
7365ed9b05 diff: Better title rendering 2018-05-08 23:02:00 +05:30
Kovid Goyal
9cb7a6b2c7 ... 2018-05-08 22:50:00 +05:30
Kovid Goyal
9ff7eae1af diff: Add an option to control syntax aliases 2018-05-08 22:46:25 +05:30
Kovid Goyal
61e1b74434 Highlight .pyj files as python 2018-05-08 22:32:34 +05:30
Kovid Goyal
324c223d54 diff kitten: keyboard shortcuts to change the number of lines of context 2018-05-08 22:19:50 +05:30
Kovid Goyal
96793a296c diff kitten has working syntax highlighting 2018-05-08 14:48:01 +05:30
Kovid Goyal
7b1626a38f Ensure highlighting is run only once 2018-05-08 09:20:36 +05:30
Kovid Goyal
09a3a3dafb More work on the diff kitten 2018-05-08 08:43:41 +05:30
Kovid Goyal
0e21708f25 ... 2018-05-08 08:26:47 +05:30
Kovid Goyal
89fa2343a6 Sign the released macOS app 2018-05-07 23:04:20 +05:30
Kovid Goyal
03256d8ac9 Code to integrate with pygments 2018-05-07 13:30:59 +05:30
Kovid Goyal
889ca77912 Allow programs running in kitty to read/write from the clipboard
By default only writing is allowed. There is a config option to enable
reading, if needed.
2018-05-07 09:57:39 +05:30
Kovid Goyal
23ee6b3109 More work on the diff kitten 2018-05-06 16:25:04 +05:30
Kovid Goyal
d133ffac25 Make using tui.operations more convenient 2018-05-06 15:34:11 +05:30
Kovid Goyal
ffc6e65392 Implement scrolling for the diff kitten 2018-05-06 14:41:10 +05:30
Kovid Goyal
d61086907d Add a global debug function to the kittens 2018-05-06 13:48:40 +05:30
Kovid Goyal
5b58c2892d Rename module 2018-05-06 10:35:01 +05:30
Kovid Goyal
67379c67cc More work on the diff kitten 2018-05-05 13:38:28 +05:30
Kovid Goyal
4691257233 ... 2018-05-05 11:19:56 +05:30
Kovid Goyal
d46a8c893a Fix --debug-config failing when no options are changed 2018-05-05 11:18:51 +05:30
Kovid Goyal
577ba0b39d Cleanup 2018-05-05 11:14:20 +05:30
Kovid Goyal
f761245280 pep8 2018-05-05 11:13:32 +05:30
Kovid Goyal
f1b4e585aa Merge branch 'master' of https://github.com/FrancescoMagliocco/kitty 2018-05-05 11:08:18 +05:30
FrancescoMagliocco
255db2cb66 Fixed where output of '--debug-config' would not be aligned if an option key was longer than 20 characters. 2018-05-05 00:39:25 -04:00
Kovid Goyal
8b6240a067 version 0.9.1 2018-05-05 09:46:28 +05:30
Kovid Goyal
f5c713b118 More work on the diff kitten 2018-05-05 09:45:35 +05:30
Kovid Goyal
ac7596b7c5 ... 2018-05-05 07:30:59 +05:30
Kovid Goyal
f69ed984a4 Output GL version when running with --debug-gl
See #521
2018-05-05 07:26:30 +05:30
Kovid Goyal
83850b28ae Update GL wrapper generated by new version of glad 2018-05-04 18:12:31 +05:30
Kovid Goyal
5efa26a98d Micro-optimization 2018-05-04 15:48:58 +05:30
Kovid Goyal
51d2c01bc1 Highlight changed in individual lines in chunks that have the same number of adds/removes 2018-05-04 15:35:11 +05:30
Kovid Goyal
be9d876997 find common prefix and suffix of two strings 2018-05-03 20:15:28 +05:30
Kovid Goyal
866b53f384 More work on the diff kitten 2018-05-03 18:05:55 +05:30
Kovid Goyal
de1a2f7682 Delay load some particularly heavy stdlib modules that are not often needed 2018-05-03 17:53:22 +05:30
Kovid Goyal
86686bfac7 Avoid rendering tab bar more than once per tick 2018-05-03 17:00:18 +05:30
Kovid Goyal
3f316c39d1 Dynamically allocate the scrollback history buffer
Reduces startup memory consumption when using very large scrollback
buffer sizes.
2018-05-03 15:17:02 +05:30
Kovid Goyal
14459a7d18 Fix #506 2018-05-03 11:19:11 +05:30
Kovid Goyal
c062b84bc6 Forgot to remove args.cmd 2018-05-03 11:14:10 +05:30
Kovid Goyal
890a68fa53 Use -c as an alias for --config instead 2018-05-03 11:12:16 +05:30
Kovid Goyal
59017a6e6f Remove the -c command line flag as it is better to use +runpy instead 2018-05-03 11:11:25 +05:30
Kovid Goyal
06cb2cafe6 Add ssh script with terminfo copy to README 2018-05-03 09:40:18 +05:30
Kovid Goyal
e4ed170748 ... 2018-05-03 09:15:05 +05:30
Kovid Goyal
f011a6c86c Disallow use of both macos_titlebar_color and background_opacity
Fixes #519
2018-05-03 09:11:41 +05:30
Kovid Goyal
45fc1ace0c Ignore -e if it is specified on the command line.
This is for compatibility with broken software that assumes terminals
should run with an -e option to execute commands instead of just passing
the commands as arguments. Fixes #502
2018-05-03 08:41:39 +05:30
Kovid Goyal
8d51edec17 Option to disable bell symbol on tab 2018-05-02 22:05:38 +05:30
Kovid Goyal
f2afba2ef4 Change the window border color if a bell occurs in an unfocused window. Can be disabled by setting the bell_border_color to be the same as the inactive_border_color. 2018-05-02 22:02:45 +05:30
Kovid Goyal
efcd3a5df7 Show a bell on the tab if a bell occurs in one of the windows in the tab and the window is not the currently focused window. Fixes #514 2018-05-02 21:44:14 +05:30
Kovid Goyal
2a52acdef4 Fix tab title not changing to reflect the window title when switching between different windows in a tab 2018-05-02 21:07:45 +05:30
Kovid Goyal
eadfeeec9b Fix window focus gained/lost events not being reported to child programs when switching windows/tabs using the various keyboard shortcuts. 2018-05-02 20:50:42 +05:30
Kovid Goyal
f8a581129f Fix #513 2018-05-02 15:52:56 +05:30
Kovid Goyal
93ff651d9e ... 2018-05-02 15:52:10 +05:30
Kovid Goyal
bec0f02b11 More work on the diff kitten 2018-05-02 15:26:47 +05:30
Kovid Goyal
0721951c79 Add hunk title lines 2018-05-02 09:47:24 +05:30
Kovid Goyal
b37d07d31a Update CHANGELOG 2018-05-01 23:41:19 +05:30
Kovid Goyal
9cacfc0c26 macOS: When the macos_titlebar_color is set to background change the titlebar background to match the current background color of the active kitty window 2018-05-01 23:37:48 +05:30
Kovid Goyal
0b93b85cf2 Dont use case range in names.h as it prevents compilation with Visual Studio 2018-05-01 11:27:10 +05:30
Kovid Goyal
f7001ea068 Fix character names for control characters not being read from unicode database
Also allow unicode_names.c to be compiled with python 2 so I can re-use
it in calibre.
2018-05-01 10:13:58 +05:30
Kovid Goyal
aa93c3fb66 Fix passing @text to other programs such as when viewing the scrollback buffer not working correctly if kitty is itself scrolled up. Fixes #509 2018-05-01 07:38:05 +05:30
Kovid Goyal
166c7bf0e6 Update CHANGELOG 2018-04-29 20:16:11 +05:30
Kovid Goyal
bb1374f64e Only define VCS_REV where it is needed 2018-04-29 18:47:14 +05:30
Kovid Goyal
053835afbe Add an option to not request window attention on bell. Fixes #507 2018-04-29 18:16:41 +05:30
Kovid Goyal
4760580d1c More work on the diff kitten 2018-04-29 08:07:03 +05:30
Kovid Goyal
8fa492e0ee More work on the diff kitten 2018-04-28 14:07:24 +05:30
Kovid Goyal
040ae75c77 Remote control: Allow matching windows by number (visible position).
Fixes #501
2018-04-28 11:00:42 +05:30
Kovid Goyal
759aaf294a Remove extra level of indirection in creating iterator 2018-04-28 10:39:59 +05:30
Kovid Goyal
9ea0de868c Parse send_text payload only once at startup 2018-04-27 18:13:37 +05:30
Kovid Goyal
78002cf3ba Update glfw from upstream
Fixes #488
2018-04-27 15:32:54 +05:30
Kovid Goyal
f68f8bf9c9 macOS: Fix changing tab title and kitty shell not working
I forgot that Apple has its own special snowflake readline variant.
Fixes #494
2018-04-27 15:16:26 +05:30
Kovid Goyal
54438cae3f DRYer 2018-04-27 11:19:46 +05:30
Kovid Goyal
2e693c31df Refactor shortcut config parsing
Resolution of kitty_mod and creation of the maps now happens in one
central place after all config is parsed. Fixes #496

Also have --debug-config output multi-key shortcuts nicely as well.
2018-04-27 11:16:58 +05:30
Kovid Goyal
0f06bf1bdb Merge branch 'macos_hide_from_tasks' of https://github.com/cfal/kitty 2018-04-27 08:19:32 +05:30
Alex Lau
b7f4f2e898 Move call to cocoa_window.m 2018-04-26 12:42:56 -07:00
Kovid Goyal
7148ee8a0f When triple-clicking select all wrapped lines belonging to a single logical line. Fixes #492 2018-04-26 10:16:00 +05:30
Kovid Goyal
238508fc0a Update glfw from upstream
Proper cross-platform fix for issue of mouse cursor not being restored
over un-focused windows.
2018-04-26 08:31:52 +05:30
Kovid Goyal
84ab0f5062 More work on the diff kitten 2018-04-26 08:01:12 +05:30
Kovid Goyal
cf04bdb36a Merge branch 'master' of https://github.com/FabioLolix/kitty 2018-04-26 06:58:16 +05:30
FabioLolix
d09a30d16c Updated Readme - Arch package
Kitty has been moved to the Arch community repository
2018-04-25 21:13:17 +02:00
Kovid Goyal
d54b58d2f3 ... 2018-04-25 19:50:40 +05:30
Kovid Goyal
0be0963dc7 Utility method to truncate formatted lines to specified width 2018-04-25 19:34:04 +05:30
Kovid Goyal
61a2360df5 hints kitten: Detect bracketed URLs and dont include the closing bracket in the URL. 2018-04-25 14:33:37 +05:30
Kovid Goyal
b3ed4e3bc2 ... 2018-04-25 09:16:10 +05:30
Kovid Goyal
316e7cb9f5 Also use cwd of child when opening programs via the hints kitten 2018-04-25 09:07:35 +05:30
Kovid Goyal
23851e31bf When calling pass_selection_to_program use the current directory of the child process as the cwd of the program. Fixes #491 2018-04-25 08:30:22 +05:30
Alex Lau
b7b64ec513 Default to off 2018-04-24 17:13:37 -07:00
Kovid Goyal
2b372373ae Update glfw from upstream 2018-04-24 18:15:28 +05:30
Kovid Goyal
7a543fac86 Wire up color handling in the diff kitten 2018-04-24 10:58:15 +05:30
Kovid Goyal
5c4b14468c Apply default colors in diff kitten 2018-04-24 10:33:18 +05:30
Alex Lau
7d4d978d97 Add macos_hide_from_tasks option 2018-04-23 22:02:54 -07:00
Kovid Goyal
fe5b8f3aec Fix using modifiers with subsequent keys in a muti-key shortcut not working 2018-04-24 09:42:37 +05:30
Kovid Goyal
f5abe7cbf7 Add a setting to clear all shortcuts defined up to that point 2018-04-24 09:08:22 +05:30
Kovid Goyal
bd0382830a Add a setting (kitty_mod) to change the modifier used by all the default kitty shortcuts, globally
See #487
2018-04-24 08:53:07 +05:30
Kovid Goyal
0b99bb534f Unicode input: When searching by name search for prefix matches as well as whole word matches
So now hori matches both "hori" and "horizontal". Switched to a
prefix-trie internally.
2018-04-24 07:45:20 +05:30
Kovid Goyal
9d67198ff9 Update path in gen-wcwidth.py 2018-04-23 21:25:33 +05:30
Kovid Goyal
fda57a81e1 Fix Shift+function key not working
Also support pressing F13-f25 function keys. Fixes #485
2018-04-23 11:28:02 +05:30
Kovid Goyal
9962ac2703 ... 2018-04-23 10:54:04 +05:30
Kovid Goyal
edc4b91d15 Expand ~ and env vars in program names. Fixes #483 2018-04-23 10:53:20 +05:30
Kovid Goyal
92ca8ab9cc Fix #482 2018-04-23 07:19:40 +05:30
Kovid Goyal
07e2d9175c Merge branch 'fixconfig' of https://github.com/Abominas/kitty 2018-04-23 06:59:44 +05:30
Abominas
c90dbb25b9 Fix config format crash 2018-04-22 17:35:58 -07:00
Kovid Goyal
b5da109e7f Wire up config infrastructure for diff kitten 2018-04-22 21:44:47 +05:30
Kovid Goyal
aa18429a8c DRYer 2018-04-22 21:22:08 +05:30
Kovid Goyal
e578d41adb Make merge_dicts() re-useable 2018-04-22 21:00:17 +05:30
Kovid Goyal
f3579e78af Make load_config() re-useable 2018-04-22 20:58:43 +05:30
Kovid Goyal
9c43707f40 Make the hinting defaults zero when missing 2018-04-22 20:34:00 +05:30
Kovid Goyal
99ff92a5a7 Don't fail to start if the user deletes the hintstyle key from their fontconfig configuration. Fixes #480 2018-04-22 20:29:46 +05:30
Kovid Goyal
d866c0d202 Fix NULL return without error set 2018-04-22 20:19:21 +05:30
Kovid Goyal
20c42ab519 tui: Allow handlers to finalize() as well as initialize() 2018-04-22 13:14:25 +05:30
Kovid Goyal
8bbc2b82d4 More work on the diff kitten 2018-04-22 13:05:58 +05:30
Kovid Goyal
6929358976 More work on the diff kitten 2018-04-21 15:45:16 +05:30
Kovid Goyal
82acd6b511 Add a note on how to create a script to launch kitty
Useful when running from source
2018-04-21 15:33:21 +05:30
Kovid Goyal
bb939ed4f8 Remove unused code 2018-04-20 22:19:31 +05:30
Kovid Goyal
cd25abc49f ... 2018-04-20 22:06:42 +05:30
Kovid Goyal
2e90e443ed Fix #476 2018-04-20 21:33:24 +05:30
Kovid Goyal
92bb6e293a Add threaded job infrastructure to tui 2018-04-20 21:12:10 +05:30
Kovid Goyal
ea9b431386 Allow changing the source used by test_compile 2018-04-20 21:02:05 +05:30
Kovid Goyal
23077fd6a6 DRYer 2018-04-20 20:56:29 +05:30
Kovid Goyal
5eee7ce338 Fix #475 2018-04-20 20:32:16 +05:30
Kovid Goyal
784894cac3 xkbcommon.org's HTTPS certificate has expired 2018-04-20 18:39:27 +05:30
Kovid Goyal
757983b729 Another ParseTuple mismatch 2018-04-20 18:29:55 +05:30
Kovid Goyal
b6660353cd Merge branch 'bigendian-fixes' of https://github.com/jamessan/kitty 2018-04-20 18:26:26 +05:30
James McCoy
215a7689d9 Correct types for various PyArg_ParseTuple/Py_BuildValue calls
Debian's [mips] build failed one of the font tests:

    FAIL: test_sprite_map (kitty_tests.fonts.Rendering)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/kitty_tests/fonts.py", line 48, in test_sprite_map
        self.ae(test_sprite_position_for(0, 1), (0, 1, 1))
        self = <kitty_tests.fonts.Rendering testMethod=test_sprite_map>
    AssertionError: Tuples differ: (0, 0, 0) != (0, 1, 1)

    First differing element 1:
    0
    1

    - (0, 0, 0)
    ?     ^  ^

    + (0, 1, 1)
    ?     ^  ^

This was due to test_sprite_position_for() using the "I" code to parse
into an unsigned short.  Since mips is big endian, the "wrong" byte was
stored into extra_glyphs.data.

This commit changes all similar data type mismatches that were found
from auditing calls to PyArg_ParseTuple/Py_BuildValue.

[mips]: https://buildd.debian.org/status/fetch.php?pkg=kitty&arch=mips&ver=0.9.0-1&stamp=1524126606&raw=0
2018-04-20 08:28:26 -04:00
Kovid Goyal
dd18a1dfd8 Simplify is_ascii_control_char
No need to use macros for unsigned char
2018-04-20 14:30:07 +05:30
Kovid Goyal
32f16ee5f5 macOS: Add support for dead keys
I have modified GLFW to support dead keys on macOS. That was painful.
Fixes #465
2018-04-20 14:25:53 +05:30
Kovid Goyal
d4f426d2ce Merge branch 'unsigned-char-build' of https://github.com/jamessan/kitty 2018-04-20 10:15:13 +05:30
Kovid Goyal
a6d96c9a14 Fix #471 2018-04-20 09:32:01 +05:30
Kovid Goyal
bf3bfeaf69 Merge branch '32bit-long-fix' of https://github.com/jamessan/kitty 2018-04-20 09:24:18 +05:30
Kovid Goyal
6ce82177ea Merge branch 'remove-sysctl-include' of https://github.com/jamessan/kitty 2018-04-20 09:21:47 +05:30
James McCoy
dc6efb5b37 Use uint64_t to detect out of range graphics command id
parse_graphics_code() uses an unsigned long to detect if the id is
"> UINT32_MAX", however sizeof(long) == sizeof(void *) on Linux systems.
So this condition will be impossible on any 32-bit system.
2018-04-19 20:32:48 -04:00
James McCoy
b26d1f306d travis: Force unsigned char on one build 2018-04-19 20:23:11 -04:00
James McCoy
cf678d8179 Remove unnecessary <sys/sysctl.h> include
The code that required this include was removed in
66803e6873, and the include is causing
build failures for some of Debian's architectures.
2018-04-19 19:14:40 -04:00
Kovid Goyal
8cecb22481 Add a link to the debian package
See #263
2018-04-19 19:42:46 +05:30
Kovid Goyal
2504266806 macOS: Fix option as alt not working for keys that act as dead keys in the current keyboard layout 2018-04-19 17:44:31 +05:30
Kovid Goyal
e3795eb07e Dont add CPPFLAGS from the python build
They contain include paths specific to the python build such as -I. that
are not appropriate for building kitty. Also move cppflags in front of
cflags when invoking the compiler.
2018-04-19 10:33:10 +05:30
Kovid Goyal
796ead5d75 Merge branch 'support-cppflags' of https://github.com/jamessan/kitty 2018-04-19 10:27:22 +05:30
Kovid Goyal
d5907a1bf9 More work on the diff kitten 2018-04-19 10:26:14 +05:30
James McCoy
ddd4774169 setup.py: Support specifying CPPFLAGS distinctly from CFLAGS 2018-04-18 23:08:45 -04:00
Kovid Goyal
1dc83a47cf When rendering a private use unicode codepoint and a space as a two cell
ligature, set the foreground colors of the space cell to match the
colors of the first cell. Works around broken applications like
powerline that use different colors for the two cells. Fixes #467
2018-04-19 07:30:36 +05:30
Kovid Goyal
0a8dc4be0a Start work on the diff kitten 2018-04-17 17:43:56 +05:30
Kovid Goyal
3d99361790 Add a note about dotted and dashed underline styles 2018-04-17 08:21:28 +05:30
Kovid Goyal
1e278938cc Fix #463 2018-04-16 21:51:55 +05:30
Kovid Goyal
ba177c61bc ... 2018-04-16 16:46:42 +05:30
Kovid Goyal
458f10be10 version 0.9.0 2018-04-15 20:18:52 +05:30
Kovid Goyal
c1667d9fc1 Fix run_kitten shortcuts in readme 2018-04-15 20:04:32 +05:30
Kovid Goyal
52f4e81d59 hints kitten: Reverse order of hints
Gives hints at the bottom of the screen smaller numbers. In
non-fullscreen usage matches closer to the bottom are more likely to be
the ones the user is looking for. Fixes #460
2018-04-14 23:07:53 +05:30
Kovid Goyal
1056ab1b81 Store marks in the index map 2018-04-14 23:01:49 +05:30
Kovid Goyal
3f9d04b616 Fix #458 2018-04-14 08:41:40 +05:30
Kovid Goyal
d9cc065c99 ... 2018-04-13 22:34:28 +05:30
Kovid Goyal
612fb3b596 Process events when timeout is zero 2018-04-13 22:34:08 +05:30
Kovid Goyal
532d51c411 Neaten up main_loop() 2018-04-13 15:19:25 +05:30
Kovid Goyal
5630c0e434 Fix merging of shortcuts
Multi-key shortcuts take precedence over conflicting single key
shortcuts defined at the same and lower levels
2018-04-12 19:40:22 +05:30
Kovid Goyal
5ba8ca2745 ... 2018-04-12 16:53:46 +05:30
Kovid Goyal
e9ffb8d185 Clarify --config help text 2018-04-12 16:47:26 +05:30
Kovid Goyal
339a2e0800 Add a word select type to the hints kitten 2018-04-12 13:49:12 +05:30
Kovid Goyal
98c04fb7da Pass some common option values to the kittens 2018-04-12 13:21:05 +05:30
Kovid Goyal
c95d1393cc Add some more default keybindings for the hints kitten 2018-04-12 13:01:16 +05:30
Kovid Goyal
1779cdd353 Fix #455 2018-04-12 10:45:29 +05:30
Kovid Goyal
6a090ac740 Add a --type argument to hints kitten
Allows addition of more sophisticated types of matches later.
2018-04-12 10:30:32 +05:30
Kovid Goyal
3c7236557c hints: Use --program=@ to copy to clipboard 2018-04-12 10:16:48 +05:30
Kovid Goyal
83a3d99824 Make --help work for all kittens 2018-04-12 09:33:50 +05:30
Kovid Goyal
808750a76a Rename url_hints to just hints 2018-04-12 09:23:48 +05:30
Kovid Goyal
32caea4197 Better error message for unknown uniform in cursor program 2018-04-12 09:11:43 +05:30
Kovid Goyal
038248f55d Remove unnecessary handling of passed in files to url_hints 2018-04-12 09:04:54 +05:30
Kovid Goyal
21b7bf6009 url_hints: Allow using a group to ignore prefix/suffix when matching via regex 2018-04-12 08:54:36 +05:30
Kovid Goyal
9dc571d8a9 Add a conveninet shortcut to test kittens 2018-04-12 08:52:00 +05:30
Kovid Goyal
805baad9cd More appropriate message when URLs not found 2018-04-12 07:27:40 +05:30
Kovid Goyal
cc910f6b79 ... 2018-04-12 07:16:20 +05:30
Kovid Goyal
56dd442e2c Flush output streams on kitten end 2018-04-11 20:24:39 +05:30
Kovid Goyal
3192b61385 ... 2018-04-11 20:19:03 +05:30
Kovid Goyal
eef3a215a1 ... 2018-04-11 14:42:07 +05:30
Kovid Goyal
cb7fff6986 Refactor the ask kitten to use the new API 2018-04-11 14:40:58 +05:30
Kovid Goyal
75b5130d96 Allow the URL hints kitten to insert the selected URL into the terminal 2018-04-11 13:22:07 +05:30
Kovid Goyal
2cf8c6aea7 Refactor the kittens framework
Make it possible to perform arbitrary actions with the kittens output
and also allow running kittens from standalone python files.
2018-04-11 13:09:31 +05:30
Kovid Goyal
5755ba72b1 Fix #449 2018-04-09 20:13:13 +05:30
Kovid Goyal
785937ecfc Remove unnecessary function calls
glfwSetInputMode is a no-op if the passed in mode is the same as the
current mode anyway.
2018-04-09 19:40:14 +05:30
Kovid Goyal
955ead05be Make the command to copy over terminfo files a one liner 2018-04-09 16:45:11 +05:30
Kovid Goyal
3830261384 Merge branch 'patch-2' of https://github.com/maximbaz/kitty 2018-04-09 16:38:42 +05:30
Maxim Baz
662ab0df45 Allow background opacity for values in range [0.91, 0.99] 2018-04-09 12:59:17 +02:00
Kovid Goyal
1ce50fb6f0 Also clean-up selection extend for line select 2018-04-09 10:43:05 +05:30
Kovid Goyal
74dcf8800d ... 2018-04-09 09:51:51 +05:30
Kovid Goyal
e90df0ca95 When double-clicking select words that continue onto next/prev line as well. Fixes #444 2018-04-09 09:47:18 +05:30
Kovid Goyal
49c375ae0f Fix #441 2018-04-08 09:05:31 +05:30
Kovid Goyal
6c4d1a4951 Merge branch 'unicode-fix' of https://github.com/epsilon-phase/kitty
Fixes #442
2018-04-08 08:54:53 +05:30
alexander white
f99e368831 Fixed crash on tab-completing without any search results. 2018-04-07 14:10:16 -04:00
Kovid Goyal
8468ad60d5 ... 2018-04-06 20:55:47 +05:30
Kovid Goyal
a1ce29aab9 Update CHANGELOG 2018-04-06 20:53:29 +05:30
Kovid Goyal
20b5084904 Update glfw
Fixes #439
2018-04-06 20:18:03 +05:30
Kovid Goyal
2fde0ea86b Add some documentation for the kitty shell 2018-04-06 15:06:28 +05:30
Kovid Goyal
b64bceac7f Add a keyboard shortcut to open the kitty shell 2018-04-06 14:59:13 +05:30
Kovid Goyal
a97174a350 Add basic command name and option name completion to the shell 2018-04-06 14:07:14 +05:30
Kovid Goyal
6141c9fdda Implement a command shell for kitty
Run it with:

kitty @
2018-04-06 12:11:37 +05:30
Kovid Goyal
a32e010f89 Move the remote commands into their own module
Separates the commands from the UI for running them.
2018-04-06 10:38:26 +05:30
Kovid Goyal
4847fb52cc Updates to README 2018-04-06 08:16:14 +05:30
Kovid Goyal
58e33e2512 URL hints: Exclude trailing punctuation from URLs 2018-04-04 08:53:12 +05:30
Kovid Goyal
584b59c7a1 Shorter filtering code 2018-04-03 10:19:21 +05:30
Kovid Goyal
2e657f0020 Have safe_remove remove all instances 2018-04-03 10:15:58 +05:30
Kovid Goyal
ae112294c8 Fix compilation on Travis 2018-04-03 10:13:18 +05:30
Kovid Goyal
8b4c7ea23f Pass CFLAGS to linker as well
Fixes #435
2018-04-03 10:03:03 +05:30
Kovid Goyal
83e225a50f ... 2018-04-02 15:30:14 +05:30
Kovid Goyal
6256b9027a Add a --reset option to @ set-colors 2018-04-02 11:14:54 +05:30
Kovid Goyal
1fd84612a8 Add a remote control command to change colors
Also add a FAQ entry about changing colors in a running kitty instance.
I'm tired of all the bug reports asking for this feature. Apparently,
people find it hard to google for the existing escape codes based
solution.
2018-04-02 10:45:52 +05:30
Kovid Goyal
2efa83bc4d Use git rev-parse instead, more robust 2018-04-01 20:33:12 +05:30
Kovid Goyal
fa064bf9cf When kitty is built from a git checkout show the current revision in --debug-config 2018-04-01 20:27:31 +05:30
Kovid Goyal
325d2bc14e Improve mouse selection for windows with padding
Moving the mouse into the padding area now acts as if the mouse is over
the nearest cell. Fixes #430

Note that this only applies to padding defined via the
window_padding_width option, not any leftover space from the window size
not being an exact multiple of the cell size.
2018-04-01 18:06:27 +05:30
Kovid Goyal
90a4b4f859 URL hints kitten: Open the URL from within the kitty process. This ensures that the behavior of the program used to open the URL is the same as when ctrl+shift clicking URLs. Fixes #424 2018-04-01 16:48:07 +05:30
Kovid Goyal
ce0db16479 Fix using kitty --single-instance to open a new window in a running kitty instance, not respecting the --directory flag. Fixes #429 2018-04-01 12:39:33 +05:30
Kovid Goyal
43ce3ce4b0 Forgot to add _replace() method to new Options class 2018-04-01 12:33:18 +05:30
Kovid Goyal
910cebeeb5 Allow setting all 256 colors in the config file 2018-04-01 12:24:00 +05:30
Kovid Goyal
1c78633d1a Add an "include" directive for the config files to read multiple config files. 2018-04-01 10:19:21 +05:30
Kovid Goyal
530fd61125 Add support for multi-key shortcuts
Fixes #338
2018-03-31 12:21:37 +05:30
Kovid Goyal
9edfafcac2 Update glfw 2018-03-31 12:21:37 +05:30
Kovid Goyal
677c47b9dd Possible fix for handling unknown modifiers on Xkb systems 2018-03-31 12:21:37 +05:30
Kovid Goyal
b59d7dda11 Import glfw from upstream, key handling on macOS works again 2018-03-31 12:21:37 +05:30
Kovid Goyal
7a3534baf8 Make ascii control char test nicer 2018-03-31 12:21:37 +05:30
Kovid Goyal
3bfcadcd81 Install newer libxkbcommon on Travis 2018-03-31 12:21:37 +05:30
Kovid Goyal
529bb5c6a0 We need xkbcommon >= 0.5 2018-03-31 12:21:36 +05:30
Kovid Goyal
caf9a12b34 Update glfw from upstream
libxkbcommon based keyboard handling now works (at least the basic
stuff, haven't tested compose/mapnotify etc.)
2018-03-31 12:21:36 +05:30
Kovid Goyal
da8e2d3d4a Adjust keys callback for new glfw keyboard API 2018-03-31 12:21:36 +05:30
Kovid Goyal
582500d3e9 Basic changes for new glfw keyboard API 2018-03-31 12:21:36 +05:30
Kovid Goyal
7926a140b8 version 0.8.4 2018-03-31 12:16:35 +05:30
Kovid Goyal
023487a1d7 Merge branch 'reduce-iconset' of https://github.com/justinnhli/kitty 2018-03-31 11:43:41 +05:30
Justin Li
71f84b1023 reduce icon set size to fit iconutil limits 2018-03-30 22:57:34 -07:00
Kovid Goyal
ce85382c68 Revert the change to use rendered bitmap width to calculate cell width
Instead if the bitmap is up to two pixels wider than the cell width
simply crop on the right. Fixes #352
2018-03-30 18:54:15 +05:30
Kovid Goyal
94d248d812 Fix presence of XDG_CONFIG_DIRS env var preventing kitty from starting up due to a silly typo
Fixes #421
2018-03-29 17:51:14 +05:30
Kovid Goyal
62db7639a8 version 0.8.3 2018-03-29 09:56:44 +05:30
Kovid Goyal
80f3fe6e9f ... 2018-03-29 00:05:37 +05:30
Kovid Goyal
9ba2c4b397 Update glfw from upstream 2018-03-28 19:57:01 +05:30
Kovid Goyal
bfa53d4b45 Update glfw from upstream
Includes proper fix for Wayland key repeat
2018-03-28 15:26:56 +05:30
Kovid Goyal
69f3ceb903 Merge glfw upstream changes to build on Wayland on FreeBSD 2018-03-28 09:47:16 +05:30
Kovid Goyal
d0f839bbd8 Fix audible bell not working under Wayland 2018-03-27 19:45:19 +05:30
Kovid Goyal
48538c0e25 Update bundled glfw 2018-03-27 15:07:25 +05:30
Kovid Goyal
02ab22f08c Update CHANGELOG 2018-03-27 12:15:25 +05:30
Kovid Goyal
b3b216a6dc ... 2018-03-27 12:09:18 +05:30
Kovid Goyal
431564c8bc Linux: When calculating cell widths use the actual rendered bitmap width in addition to the horizontal advance reported by FreeType.
The horizontal advance is insufficient for some fonts at some point
sizes. So although rendering the characters is slower, we do it
to ensure cell width is correct. Fixes #352
2018-03-27 12:04:38 +05:30
Kovid Goyal
57f1bbb71a Make cwd check more robust
Apparently getcwd() raises an exception on macOS when the cwd does not
exist.
2018-03-27 10:54:49 +05:30
Kovid Goyal
faac8649e4 Fix a regression that broke visual bell and invert screen colors escape code. Fixes #419 2018-03-27 10:46:26 +05:30
Kovid Goyal
1e6a41186f Move check for NULL boss into call_boss()
Negligible perf impact and makes it safe to use in different contexts
2018-03-27 09:56:29 +05:30
Kovid Goyal
eddee67130 Fix error when testing update_selection because not boss is defined 2018-03-27 09:54:14 +05:30
Kovid Goyal
9b834014e9 Merge branch 'zero-length-title' of https://github.com/jamessan/kitty 2018-03-27 09:41:33 +05:30
James McCoy
a467e79144 Stop setting title to ";" when 0-length OSC 2 is received
Various programs send a 0-length title if no title is configured (e.g.,
(n)vim with 'title' unset, or mutt without ts_enabled).  When this
happens, kitty is mis-parsing the data and setting the title to ";".
2018-03-26 21:30:45 -04:00
Kovid Goyal
90cc785b55 Allow double-click and triple-click + drag to extend selections word at a time or line at a time. Fixes #400 2018-03-26 16:48:28 +05:30
Kovid Goyal
09710425ab Move rectangle_select onto the selection object 2018-03-26 12:37:36 +05:30
Kovid Goyal
dd36727adf Show macOs version for --debug-config 2018-03-25 12:47:47 +05:30
Kovid Goyal
47b665a624 Prettyify --debug-config output 2018-03-25 12:36:27 +05:30
Kovid Goyal
7011329761 Add a --debug-config option to provide diagnostic info about the system and kitty 2018-03-25 12:30:56 +05:30
Kovid Goyal
ea24c23fde Allow specifying a system wide kitty config file
The system config is merged with any user specific config files, with
options in the user specific config files having higher priority.

Also follow the full XDG spec for finding config files, including
XDG_CONFIG_DIRS.
2018-03-25 11:47:11 +05:30
Kovid Goyal
be8f2b8106 Create a shortcut to set the tab title
No longer need to use remote control just to change tab titles.
2018-03-25 09:55:02 +05:30
Kovid Goyal
71db024a3b Add history based completion to the ask kitten 2018-03-24 11:49:34 +05:30
Kovid Goyal
3790af6897 Basic ask kitten 2018-03-23 18:03:43 +05:30
Kovid Goyal
dc6ef63ddd Merge branch 'oS' of https://github.com/jubalh/kitty 2018-03-23 15:33:40 +05:30
Michael Vetter
ef762f7a2b Add link to openSUSE package 2018-03-23 10:45:42 +01:00
Kovid Goyal
4ed646e062 Merge branch 'tic2' of https://github.com/jubalh/kitty 2018-03-21 21:17:46 +05:30
Michael Vetter
afbd843388 Mention tic as dependency 2018-03-21 16:42:44 +01:00
Kovid Goyal
18c3598ef2 Merge branch 'desktop' of https://github.com/jubalh/kitty 2018-03-21 20:43:50 +05:30
Michael Vetter
1c2623e609 Have more detailed desktop file category
Let's use the 'TerminalEmulator' category according to the spec:
https://specifications.freedesktop.org/menu-spec/menu-spec-1.0.html
2018-03-21 11:28:57 +01:00
Kovid Goyal
e232863028 Also recognize unicode aliases for macOS modifiers 2018-03-20 15:10:29 +05:30
Kovid Goyal
a89309153d Merge branch 'patch-1' of https://github.com/sle-odoo/kitty 2018-03-18 17:59:27 +05:30
Simon Lejeune
fee7c8e573 update dependencies to run make app
while imagemagick is defined as an optional dependency in the installation section, its presence is indeed mandatory to successfully run `make app` as seen at https://github.com/kovidgoyal/kitty/blob/master/logo/make.py#L27
2018-03-18 10:56:40 +01:00
Kovid Goyal
1a52127c55 version 0.8.2 2018-03-17 17:45:57 +05:30
Kovid Goyal
4920431c3a Update CHANGELOG 2018-03-17 17:40:41 +05:30
Kovid Goyal
773f26b61d Fix screen not being refreshed immediately after moving a window. Fixes #397 2018-03-16 22:00:57 +05:30
Kovid Goyal
16e77d7329 Replace use of PyObject_Str in a couple more places 2018-03-16 21:26:46 +05:30
Kovid Goyal
2cec0908a5 Fix a segfault when getting the contents of the scrollback buffer as text
Fixes #398
2018-03-16 21:10:48 +05:30
Kovid Goyal
b3ef62c188 Merge branch 'i386-fixes' of https://github.com/oleastre/kitty 2018-03-16 20:42:57 +05:30
Olivier Samyn
3385f6fe67 Avoid comparison between signed and unsigned compilation error (32bit) 2018-03-16 09:31:37 +01:00
Kovid Goyal
0170bf636b ... 2018-03-15 20:58:26 +05:30
Kovid Goyal
b2561fd61e Add a facility to specify command line arguments when running kitty from the GUI on macOS
Fixes #395
2018-03-15 20:57:08 +05:30
Kovid Goyal
64b48945d4 Add a focus-tab remote command
Fixes #394
2018-03-15 17:41:49 +05:30
Kovid Goyal
bbfd463357 Dont show a useless traceback when failing to match in a remote command
Fixes #393
2018-03-15 15:45:12 +05:30
Kovid Goyal
2179dab8ed Re-organize kitty.conf into sections
Sections are de-limited by vim folds
2018-03-15 13:07:02 +05:30
Kovid Goyal
801ead7f7f Add ntoe to readme about right click to extend selection 2018-03-15 12:20:46 +05:30
Kovid Goyal
9e4834d58b Right click should only extend selection if there is an existing selection 2018-03-15 12:19:45 +05:30
Kovid Goyal
f38e089de0 Merge branch 'extend-selection' of https://github.com/vsajko/kitty 2018-03-15 12:07:23 +05:30
Kovid Goyal
b252504306 ... 2018-03-15 11:31:37 +05:30
Kovid Goyal
81bcdaf48a Dont show [options] if there are no options in usage message 2018-03-15 11:30:31 +05:30
Kovid Goyal
44f654ff86 Cleanup remote_control.py 2018-03-15 11:26:22 +05:30
Kovid Goyal
84cfa9382f Add argspecs for the remote control command help text 2018-03-15 11:21:13 +05:30
Kovid Goyal
c6da374aa9 Add a configurable keyboard shortcut and remote command to set the font size to a specific value
Fixes #388
2018-03-15 11:15:35 +05:30
Vedran Sajko
d9fe0b2540 Extend selection with right click 2018-03-15 00:09:33 +01:00
Kovid Goyal
5a905dfe7f Add kitty.app to .gitignore
Also have make clean clean linux-package and kitty.app when running
manually.
2018-03-14 12:10:15 +05:30
Kovid Goyal
09b6d6e62b README cleanups 2018-03-14 08:01:10 +05:30
Kovid Goyal
6aa26cf75f Improve the wording for close_on_child_death option 2018-03-13 09:12:06 +05:30
Kovid Goyal
bae8915881 Add an option to have kitty close the window when the main processes running in it exits, even if there are still background processes writing to that terminal.
Merge branch 'master' of https://github.com/josswright/kitty
2018-03-13 09:08:45 +05:30
Kovid Goyal
9c46de319e MacOS: Fix restoring of window size not correct on Retina screens
Fixes #382
2018-03-13 08:19:15 +05:30
Joss Wright
994eecadb7 Adds close_on_child_death option for disowned processes. 2018-03-12 21:02:37 +00:00
Kovid Goyal
f7f9ceec34 Consolidate signal handling
Move the signal handler for SIGCHLD into child-monitor.c
Makes for cleaner code.
2018-03-12 21:53:02 +05:30
Kovid Goyal
527255e3a1 Fix compilation with gcc 8
Apparently some nitwit Linux distros have made an unreleased compiler
their default compiler. Fixes #376

Fixes various new warnings that GCC 8 issues
2018-03-12 10:38:12 +05:30
Kovid Goyal
0333da991d ... 2018-03-12 08:11:43 +05:30
Kovid Goyal
2bf8e1b1a3 Allow the name of the lib directory in linux-package to be configurable. Fixes #372 2018-03-12 08:10:53 +05:30
Kovid Goyal
ffc717717c Oops 2018-03-12 07:53:31 +05:30
Kovid Goyal
2c8414db5d Be a bit more specific 2018-03-12 07:52:08 +05:30
Kovid Goyal
32473d7dc7 make clean fallsback to manual cleaning when not in a git checkout
Fixes #379
2018-03-12 07:50:54 +05:30
Kovid Goyal
079f10eebd ... 2018-03-11 22:31:19 +05:30
Kovid Goyal
ae1f305a81 Add kittens to the LOC script 2018-03-11 12:03:23 +05:30
Kovid Goyal
0b1f5209d5 Use CFLAGS and LDFLAGS env vars when building the launcher as well
Fixes #374
2018-03-11 08:12:17 +05:30
Kovid Goyal
fc9980903d Make layout names case-insensitive for enabled_layouts in sessions as well 2018-03-10 23:42:06 +05:30
Kovid Goyal
ad87131926 A bit of documentation for goto_layout 2018-03-10 23:38:18 +05:30
Kovid Goyal
4dfe1b664f Add configurable keyboard shortcuts to switch to a specific layout
Fixes #369
2018-03-10 23:34:47 +05:30
Kovid Goyal
d7b2ac97b5 ... 2018-03-09 21:04:20 +05:30
Kovid Goyal
fd9dac4ca4 Add a small delay when opening the editor with the config file to workaround bugs in vim that cause it to ignore SIGWINCH if it happens early during startup. 2018-03-09 21:03:42 +05:30
Kovid Goyal
8ca9348b07 ... 2018-03-09 18:10:17 +05:30
Kovid Goyal
5cc18fdb4b ... 2018-03-09 18:02:06 +05:30
Kovid Goyal
51b6b325b9 Add a keyboard shortcut to edit the kitty config file easily
Fixes #366
2018-03-09 17:57:09 +05:30
Kovid Goyal
b3cc6f3802 ... 2018-03-09 17:49:31 +05:30
Kovid Goyal
1295094715 README cleanups 2018-03-09 11:00:50 +05:30
Kovid Goyal
af85f58e3d version 0.8.1 2018-03-09 09:21:50 +05:30
Kovid Goyal
3b34821c86 Report unhandled exceptions during loop initialization in the unicode input kitten as well 2018-03-08 13:57:13 +05:30
Kovid Goyal
eaea0b16b5 Fix URL hints not working on macOS
Fixes #363
2018-03-08 13:38:16 +05:30
Kovid Goyal
964ffadc8e DRYer 2018-03-08 13:37:56 +05:30
Kovid Goyal
1b84064e5f ... 2018-03-08 13:01:35 +05:30
Kovid Goyal
dd128a99ac Report unahndled exceptions when starting loop in URL hints kitten 2018-03-08 12:58:54 +05:30
Kovid Goyal
bc829a9712 Use a dedicated static variable for tracking window system initialization 2018-03-06 13:55:06 +05:30
Kovid Goyal
3459c55ebf Add section on reporting bugs to CONTRIBUTING 2018-03-05 21:03:01 +05:30
Kovid Goyal
a631d950e1 Add a guide to contributing 2018-03-05 20:57:57 +05:30
Kovid Goyal
f35e2d76ad Add a note about using --login on macOS when changing the default shell 2018-03-05 14:54:20 +05:30
Kovid Goyal
8db838da9f macOS: Fix shell not starting in login mode on some computers. Fixes #247 2018-03-05 13:30:09 +05:30
Kovid Goyal
7254a880dc Guard against print failure 2018-03-05 13:29:26 +05:30
Kovid Goyal
a0df5b970b Report unhandled exceptions via log_error() as well 2018-03-05 10:28:33 +05:30
Kovid Goyal
54ed08c24e Ensure the extra glyphs array is always re-initialized 2018-03-04 23:36:39 +05:30
Kovid Goyal
97e1ecabdc Render private use unicode characters that are followed by a space as two cell ligatures. Fixes #357 2018-03-04 22:58:24 +05:30
Kovid Goyal
e716f6d35e Replace deprecated ASL with os_log on macOS 2018-03-04 12:28:06 +05:30
Kovid Goyal
c7506496da Unify error logging between python and C 2018-03-04 11:55:47 +05:30
Kovid Goyal
1e3d3df9b8 Remove unused code 2018-03-04 10:59:12 +05:30
Kovid Goyal
ed75ad0d41 Log a timestamp as well when printing error messages from python 2018-03-04 10:44:28 +05:30
Kovid Goyal
fd6159c0b4 Redirect stderr/stdout to console.app when launched via launchd on macOS 2018-03-04 10:17:43 +05:30
Kovid Goyal
976c322b83 Print a couple of errors to stderr instead of stdout 2018-03-04 08:58:36 +05:30
Kovid Goyal
28c1935800 Fix Unicode emoji presentation variant selector causing new fallback font to always be loaded 2018-03-03 21:32:43 +05:30
Kovid Goyal
1edf1524f8 Update bundled glfw 2018-03-03 11:21:09 +05:30
Kovid Goyal
0dfe101c0f brew's python3 handling seems to have changed 2018-03-03 11:09:07 +05:30
Kovid Goyal
a571821f73 Fix compilation on Travis (I hope) 2018-03-03 10:56:07 +05:30
Kovid Goyal
f8e6f87984 Dont use MSG_NOSIGNAL on Apple 2018-03-03 10:51:29 +05:30
Kovid Goyal
c7338bca6f Document how to control kitty from programs not running in a kitty window 2018-03-03 10:38:25 +05:30
Kovid Goyal
15f07f57bf Finish remote control via socket implementation 2018-03-03 10:32:49 +05:30
Kovid Goyal
ec989a45b5 ... 2018-03-03 08:55:05 +05:30
Kovid Goyal
e8286c50b2 Implement sending responses to peers 2018-03-02 12:35:32 +05:30
Kovid Goyal
bfbbe3db14 mutex remove_poll_fd()
It modifies talk_data.fds which can also be modified from the main
thread when adding a writer.
2018-03-02 11:13:47 +05:30
Kovid Goyal
6214a87522 Correct error handling for pthread_join 2018-03-02 11:08:11 +05:30
Kovid Goyal
743ff719c8 join the talk thread on exit
Also shutdown reading on the control socket after message received.
2018-03-02 11:02:18 +05:30
Kovid Goyal
b491eacb9c Ensure the moitor threads are shut down on exit 2018-03-02 10:32:12 +05:30
Kovid Goyal
5bfc89e13f Implement listening on the --listen-on socket 2018-03-02 10:26:19 +05:30
Kovid Goyal
52d2b7b09e Implement --listen-on option 2018-03-02 09:08:58 +05:30
Kovid Goyal
19e59d9575 Start refactoring peer message handling to allow multiple listening sockets and responses 2018-03-02 09:08:58 +05:30
Kovid Goyal
6fe4baf1de Move pthread includes into separate header 2018-03-02 09:08:58 +05:30
Kovid Goyal
bc21ec7551 Have kitty @ use /dev/tty instead of stdout/stdin
Allows redirecting those streams, while still being able to send
messages. Downside is that if user runs it outside kitty there wont
be any useful error message.
2018-03-02 09:08:58 +05:30
Kovid Goyal
aad4a1fd6a Dont fail for non-UTF-8 encoded config files, simply replace the undecodeable chars instead 2018-03-02 08:49:27 +05:30
Kovid Goyal
721595ef04 Ensure config file is always opened with UTF-8 2018-03-02 08:47:13 +05:30
Kovid Goyal
139838c717 Option to print debug information about font fallback 2018-02-28 21:43:40 +05:30
Kovid Goyal
c93238d8c9 Some documentation for the unicode input kitten 2018-02-28 00:29:11 +05:30
Kovid Goyal
5ee1fbe07d Copy the launcher script into linux-package
The launcher script is mostly useless on linux, but is needed
when using kitty.app built from source and might be useful on linux as
well, if running kitty without putting it on PATH.
2018-02-28 00:25:57 +05:30
Kovid Goyal
ee1287211d Typo in makefile app target 2018-02-27 21:06:42 +05:30
Kovid Goyal
94e8be6b1c ... 2018-02-27 20:29:08 +05:30
Kovid Goyal
053ba7f082 Nicer error message when user tries to run logo/make.py with missing tools 2018-02-27 19:56:52 +05:30
Kovid Goyal
e8f3f00792 Handle cols being zero 2018-02-27 18:48:48 +05:30
Kovid Goyal
740a89b77f Treat Ctrl+Alt+letter as Esc,Ctrl+letter
Follows the behavior of some other terminals and is better than
generating nothing, since apparently there are some terminal programs
that use these keys. Fixes #345
2018-02-27 08:46:09 +05:30
Kovid Goyal
1fe936dbbc Fix off by one when restoring cursor position after resize. Fixes #344 2018-02-25 09:15:48 +05:30
Kovid Goyal
11e85ac703 Swapped unicode input name and hex mode prompt strings 2018-02-24 14:51:49 +05:30
Kovid Goyal
4cb99be8e6 version 0.8.0 2018-02-24 11:11:56 +05:30
Kovid Goyal
8cf9fd3cdb ... 2018-02-23 09:38:07 +05:30
Kovid Goyal
b22950bb0a More work on README 2018-02-23 09:36:46 +05:30
Kovid Goyal
f87d62571b Add links to relevant parts of the README in the major features list 2018-02-23 09:13:20 +05:30
Kovid Goyal
42afc56b65 Update CHANGELOG with entry for macos_titlebar_color
Fixes #341
2018-02-22 21:21:33 +05:30
Splinter Suidman
10c3c7c41f Implement setting title bar color. 2018-02-22 21:19:55 +05:30
Kovid Goyal
e236539e3a Option for changing macOS titlebar color
Note that the actual implementation is still needed, this is just the
option definition/parsing code.
2018-02-22 15:07:24 +05:30
Kovid Goyal
1fc605cbc0 Move needs_special_handling definition into keys.c 2018-02-22 14:37:51 +05:30
Kovid Goyal
1e4963e727 Revert change to make alt+bs emit werase
Most linux terminals emit ESC+BS instead. And iTerm2 in Esc+ mode also
emits this. So go with the majority for greatest ecosystem
compatibility. Fixes #264
2018-02-22 13:51:14 +05:30
Kovid Goyal
95384d437a Use the nice array based interface for fcntl.ioctl 2018-02-20 17:01:14 +05:30
Kovid Goyal
e44910212c Sample code to use TIOCGWINSZ in python 2018-02-20 16:47:06 +05:30
Kovid Goyal
36b8802f43 Add a link to the graphics protocol page in the README 2018-02-20 16:32:57 +05:30
Kovid Goyal
a6b0554edc Merge branch 'master' of https://github.com/Polynomial-C/kitty 2018-02-20 15:42:23 +05:30
Lars Wendler
c1df5eac57 Added Gentoo to the list of Linux packagers. 2018-02-20 11:09:43 +01:00
Kovid Goyal
68bf1be8d0 render on cursor shape change as well 2018-02-20 11:54:35 +05:30
Kovid Goyal
d5edea3c7f render on cursor position change as well 2018-02-20 11:27:39 +05:30
Kovid Goyal
eb580f5ead Update CHANGELOG for padding color 2018-02-20 10:10:28 +05:30
Kovid Goyal
c99588082b Fix incorrect bottom blank rects in vertical and tall layouts 2018-02-20 10:06:37 +05:30
Kovid Goyal
96d241e9f3 Fix enabled_layouts in session files not being respected 2018-02-20 10:01:41 +05:30
Kovid Goyal
8f423c6d8f Fix padding color not tracking active window bg color 2018-02-20 09:52:19 +05:30
Kovid Goyal
f25ecedcab Always set the padding color to current window background 2018-02-20 09:43:59 +05:30
Kovid Goyal
2913c1aedc Change the color of the padding and margins to match the current background color of the window, when only a single window is visible.
Fixes #323
2018-02-20 09:43:49 +05:30
Kovid Goyal
5a15f7e8ad Sync to monitor refreshes by default
Prevents tearing while scrolling. See #318

Reduce draw calls while processing mouse move events to make latency
while selecting with the mouse acceptable. Also add a config option to
turn off monitor syncing, so people with keyboard repeat rates higher
than their monitor's refresh rate can use it.
2018-02-20 09:38:00 +05:30
Kovid Goyal
e6cb64baa5 Revert "Enable syncing of redraws to monitor refresh rate"
This reverts commit 6a51096304.
Turns out that dynamically changing the swap interval causes bad flicker
when rendering on X11 in a fullscreen window (or more generally, when
only a single X11 window is visible).
2018-02-20 08:32:33 +05:30
Kovid Goyal
537023ef5a Fix simple_render_screen() broken by multiple OSwindow draw calls optimization 2018-02-20 05:52:32 +05:30
Kovid Goyal
70125e0de5 Only build asan-launcher if --sanitize is given
Fixes #328
2018-02-16 08:56:30 +05:30
Kovid Goyal
8c5646b81b Merge branch 'build-package-fix' of https://github.com/13k/kitty 2018-02-16 08:22:30 +05:30
Kiyoshi '13k' Murata
bd741365cb Fix packaging trying to modify unrelated files
`package()` method in `setup.py` tries to compile and chmod all files
under the directory given by `--prefix PREFIX`.

If PREFIX is a directory containing other distributions (like
`/usr/local` or `$HOME/.local`), then it would try to compile - using
possibly the wrong python version - and chmod all files within PREFIX.
2018-02-15 19:46:51 -02:00
Kovid Goyal
efd9843920 Update CHANGELOG 2018-02-15 17:42:32 +05:30
Kovid Goyal
0bb8ec61e5 Fix regression caused by overlay window support code
Closing a window would not update the window layout, depending on the
position of the window in the current layout.
2018-02-15 09:16:00 +05:30
Kovid Goyal
6a51096304 Enable syncing of redraws to monitor refresh rate
Now, when large changes, such as scrolling occur, the OpenGL back buffer
swapping is synchronized to the monitor refresh rate (if supported by
the OS). This eliminates tearing artifacts when scrolling the screen fast.
Fixes #318
2018-02-14 20:59:58 +05:30
Kovid Goyal
807c8f9005 Do not send history buf in alternate screen mode 2018-02-14 20:46:12 +05:30
Kovid Goyal
9c21610215 Use a single generic function to get text and ANSI representations of all buffers 2018-02-14 20:38:53 +05:30
Kovid Goyal
97b4256ba4 Remove unused code 2018-02-14 18:50:52 +05:30
Kovid Goyal
e4b643fdaf Show a nice message when no URLs are found 2018-02-14 18:36:57 +05:30
Kovid Goyal
0bda7b3679 When running kittens respect current screen scroll 2018-02-14 18:35:32 +05:30
Kovid Goyal
51e3e9997c Allow clicking URLs via keybaord hints by pressing ctrl+shift+e 2018-02-14 17:18:57 +05:30
Kovid Goyal
9f52d427e5 http->https in readme 2018-02-14 17:08:09 +05:30
Kovid Goyal
ad706f9924 Make the list of URL prefixes configurable 2018-02-14 12:48:44 +05:30
Kovid Goyal
57cf789c75 Finish up the URL hints kitten 2018-02-14 12:34:01 +05:30
Kovid Goyal
62174fdbcc DRYer 2018-02-14 11:19:58 +05:30
Kovid Goyal
dff7ddea39 Make the default intense black a little lighter
Brings it closer to the color definitions at:
https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit
2018-02-14 11:17:07 +05:30
Kovid Goyal
0c3257b6b9 Start work on url hints kitten 2018-02-14 11:01:17 +05:30
Kovid Goyal
4bbf5c0bc9 Allow choosing a match by index in the search by name panel as well 2018-02-13 11:25:45 +05:30
Kovid Goyal
b0820f6e13 Use . instead of r for the index char 2018-02-13 11:10:35 +05:30
Kovid Goyal
b0f5d8dfdc Fix table row generation for non-name unicode input panels 2018-02-13 10:50:06 +05:30
Kovid Goyal
67e0d3723a Implement favorites for unicode input 2018-02-13 10:33:55 +05:30
Kovid Goyal
a36f4a4670 Add a Emoji panel to the unicode input kitten 2018-02-13 09:06:39 +05:30
Kovid Goyal
dab852c412 Implement searching for unicode characters by name 2018-02-12 14:08:54 +05:30
Kovid Goyal
193ac6cd81 Forgot to remove from recent when adding to top of list 2018-02-12 12:39:02 +05:30
Kovid Goyal
34ca8419bb Finish chose unicode symbol by recently used 2018-02-12 10:19:29 +05:30
Kovid Goyal
6094aabe26 ... 2018-02-12 10:19:29 +05:30
Kovid Goyal
19648257f2 Have wcwidth() ignore SGR 2018-02-12 10:19:29 +05:30
Kovid Goyal
3363a9459b Implement drawing of titlebar, remembering of mode and fix various bugs in tui 2018-02-12 10:19:29 +05:30
Kovid Goyal
4d92f4871a Mark names.h as being generated 2018-02-12 10:19:29 +05:30
Kovid Goyal
f0d4ad16d2 Work on search by name in unicode input 2018-02-12 10:19:29 +05:30
Kovid Goyal
2cc8402458 A FAQ entry about terminfo over SSH 2018-02-12 10:19:12 +05:30
Kovid Goyal
1c79320133 Fix #319 2018-02-11 13:03:20 +05:30
Kovid Goyal
8b099d969f oops 2018-02-11 11:37:05 +05:30
Kovid Goyal
61157e8763 Remove the passing of swap_interval as a constructor parameter
It was unused and makes it more complicated to override via an option,
if needed.
2018-02-11 11:14:48 +05:30
Kovid Goyal
f97d078f81 Fix kitty saving incorrect window heights
Typo caused saved window height to be actually the window width
2018-02-10 10:00:54 +05:30
Kovid Goyal
a14cf81422 Store cached window sizes in the cache dir rather than the config dir
A side-effect is that on the very next start kitty wont remember window
sizes, apologies for the on convenience.
2018-02-10 10:00:47 +05:30
Kovid Goyal
feeba9b5f5 Add a note about where kitty @ messaging works 2018-02-10 07:35:36 +05:30
Kovid Goyal
b1b76ca250 Redraw windows when the window manager tells us they have been damaged
Needed on systems with non-compositing window managers. Fix #317
2018-02-10 06:54:30 +05:30
Kovid Goyal
e119ed0daa Ignore harmless KeyError while modifying selectors 2018-02-09 20:20:18 +05:30
Kovid Goyal
8c18486836 Module with all the data for unicode entry by character name 2018-02-09 19:56:25 +05:30
Kovid Goyal
b6ed3951bc Add the kittens dir when building the package 2018-02-09 16:59:15 +05:30
Kovid Goyal
ea178ea689 Forgot to marcj launcher script executable 2018-02-09 16:48:04 +05:30
Kovid Goyal
973bbf3f8a Fix #316 2018-02-09 16:44:52 +05:30
Kovid Goyal
3068846d8f Implement using Ctrl+Shift+u to input unicode
Fixes #302
2018-02-08 22:47:17 +05:30
Kovid Goyal
194454715f Basic unicode input works 2018-02-08 22:16:39 +05:30
Kovid Goyal
ac02e053ee Dont save/restore DECCOLM since it is actually unused in kitty 2018-02-08 22:12:51 +05:30
Kovid Goyal
75db360929 ... 2018-02-08 12:57:57 +05:30
Kovid Goyal
f9141120aa A few fixes for the extended key protocol 2018-02-08 12:57:16 +05:30
Kovid Goyal
d19f9e5b96 Fix error handling in tui.loop 2018-02-08 12:33:27 +05:30
Kovid Goyal
213a223861 Typo in incremental decoder init 2018-02-08 11:56:34 +05:30
Kovid Goyal
ef9a24932f Start work on unicode input kitten 2018-02-08 11:00:57 +05:30
Kovid Goyal
bf5b0070c1 Add note about terminfo property used for styled underlines 2018-02-08 10:29:37 +05:30
Kovid Goyal
2ab6f57159 Add non-standard terminfo capabilities
Advertises support for truecolor and styled underlines.
The truecolor properties are used by at least tmux and neovim.
2018-02-08 10:26:13 +05:30
Kovid Goyal
77d46630d7 Update bundled glfw 2018-02-08 09:15:40 +05:30
Kovid Goyal
b78612aebd Entry point to run python on cmd line and from scripts 2018-02-08 09:11:13 +05:30
Kovid Goyal
0f63d1bfa7 ... 2018-02-07 22:41:03 +05:30
Kovid Goyal
66a897cc80 Add interrupt and eot callbacks 2018-02-07 19:46:53 +05:30
Kovid Goyal
3828511051 forgot to include in last commit 2018-02-07 14:40:23 +05:30
Kovid Goyal
226a89c184 Add JSON definition of key encoding 2018-02-07 14:39:11 +05:30
Kovid Goyal
e3b4919c17 Finish up tui.Loop 2018-02-07 13:30:34 +05:30
Kovid Goyal
168bc58635 The kittens learn about mice 2018-02-07 12:40:04 +05:30
Kovid Goyal
f4f0b8fd5f Kittens learn about bracketed paste 2018-02-07 10:39:05 +05:30
Kovid Goyal
13c034c613 Add link to ncurses FAQ on bce as well 2018-02-07 08:06:24 +05:30
Kovid Goyal
35f1658f4a Key and text handler for the kittens 2018-02-06 20:58:46 +05:30
Kovid Goyal
328f22adab Let update_cell_emtrics() know if it is being called in response to a DPI change 2018-02-06 20:12:57 +05:30
Kovid Goyal
22cf67b407 More work on tui.loop 2018-02-06 20:08:28 +05:30
Kovid Goyal
0c7d51dd9d Avoid unnecessary draw calls with multiple OS Windows
Do not ask the GPU to draw and swap buffers for OS Windows that are not
dirtied. See #313
2018-02-06 19:32:24 +05:30
Kovid Goyal
fa87ce72a8 A terminal input parse helper for the kittens 2018-02-06 17:29:05 +05:30
Kovid Goyal
ff2e5b3966 Avoid unnecessary calls to mark_for_codepoint 2018-02-06 11:23:39 +05:30
Kovid Goyal
96c93fa252 Add support for emoji presentation when choosing fallback fonts 2018-02-06 11:11:22 +05:30
Kovid Goyal
e830b7edf7 Add emoji presentation variation selector support to wcswidth() as well 2018-02-06 10:16:23 +05:30
Kovid Goyal
9c874f6685 Add support for the unicode emoji presentation variation selector 2018-02-06 09:52:55 +05:30
Kovid Goyal
b8ab15bea8 Fix incorrect window border drawing for overlay windows 2018-02-06 09:41:19 +05:30
Kovid Goyal
6c7247f726 Disable display_scrollback for overlay windows 2018-02-06 09:36:36 +05:30
Kovid Goyal
7674aa4e7c Add FAQ entry about bce in vim 2018-02-06 08:55:42 +05:30
Kovid Goyal
ebe97bf492 Get rid of safe_wcwidth
Since wcwidth is now in our control, we dont need to wrap it.
2018-02-05 10:11:30 +05:30
Kovid Goyal
fbe4d036d8 Have wcwidth() return 0 for marks instead of -1
Since kitty always treats marks as combinig chars, this allows us to
remove a few unnecessary branches
2018-02-05 10:06:05 +05:30
Kovid Goyal
c572b8bb1a Refactor screen_draw()
Make it a little faster and also clearer, splitting out
the logic for combining chars into a separate function.
2018-02-05 09:55:17 +05:30
Kovid Goyal
59a5e23466 Almost always resize glyphs that are too wide
When using FreeType, rescale glyphs that dont fit if they are more than
1px wider than the cell rather than 25% of the cell width. This matches
the behavior of CoreText and is needed for rendering the various Emoji
with default text presentation (i.e. emoji that have wcwidth() == 1)
2018-02-05 09:21:14 +05:30
Kovid Goyal
b9857f9499 Only consider emoji characters with emoji presentation to have width two
Fixes #308
2018-02-05 09:21:13 +05:30
Kovid Goyal
b667e3a577 DRYer 2018-02-05 09:19:12 +05:30
Kovid Goyal
240b1475c7 Fix regression that caused a few ligatures to not render correctly in rare circumstances
This was caused by cache corruption. is_special_glyph() and
is_empty_glyph() were treading over each other if called in
the right sequence. Fixes #303
2018-02-05 00:04:05 +05:30
Kovid Goyal
3f24e5b571 A few more places to remove wcwidth from 2018-02-04 22:47:02 +05:30
Kovid Goyal
fc7ec1d3f7 Get rid of the option to use the system wcwidth
The system wcwidth() is often wrong. Not to mention that if you SSH into
a different machine, then you have a potentially different wcwidth. The
only sane way to deal with this is to use the unicode standard.
2018-02-04 21:02:30 +05:30
Kovid Goyal
452ff02b15 Oops added extra file in previous commit 2018-02-04 20:34:02 +05:30
Kovid Goyal
c2cb43cc07 Framework for kittens 2018-02-04 20:23:52 +05:30
Kovid Goyal
6736fd3835 Get rid of the query escape code for styled underlines 2018-02-04 16:40:48 +05:30
Kovid Goyal
a1bd69a9c2 Fix incorrect handling of CSI s/r/u 2018-02-04 16:16:57 +05:30
Kovid Goyal
561e63ee2d Use an overlay window for browsing the scrollback buffer in less 2018-02-04 11:28:13 +05:30
Kovid Goyal
647b95631f Add tests for layout operations with an overlay window 2018-02-04 11:28:13 +05:30
Kovid Goyal
aa518b2520 Add tests for basic layout operations 2018-02-04 11:28:13 +05:30
Kovid Goyal
51c0f01539 Support for overlay windows in the layout manager 2018-02-04 11:28:02 +05:30
Kovid Goyal
cc9a19b303 Move set_active_window into base class
It was only used in a single sub-class anyway
2018-02-02 13:56:25 +05:30
Kovid Goyal
2ee9844c2b Track cursor position explicitly during rewrap
Instead of using heuristics to position the cursor after a resize, track
the position during re-wrapping and place the cursor at the re-wrapped
position. Fixes #242 (I hope)
2018-02-02 13:06:18 +05:30
Kovid Goyal
4c53a74fa9 Fix resize debounce implementation 2018-02-02 13:06:18 +05:30
Kovid Goyal
9b0ffdbf5a A spot of refactoring 2018-02-02 11:19:42 +05:30
Kovid Goyal
2777b89e45 Update bundled glfw 2018-02-01 13:03:26 +05:30
Kovid Goyal
7f90430414 Designating charsets should not switch to them
Fixes #301
2018-02-01 12:05:07 +05:30
Kovid Goyal
ee4e56edf9 ... 2018-02-01 10:26:17 +05:30
Kovid Goyal
93c83d03c0 More robust private mode restore 2018-02-01 09:45:34 +05:30
Kovid Goyal
855b3de473 Implement support for save/restore of DEC private modes (CSI ? s/r) 2018-02-01 09:19:43 +05:30
Kovid Goyal
a9be05c885 ... 2018-01-31 18:13:36 +05:30
Kovid Goyal
9f3dfc27da version 0.7.1 2018-01-31 10:37:58 +05:30
Kovid Goyal
4b4f6bc928 Update CHANGELOG 2018-01-31 10:34:54 +05:30
Kovid Goyal
273735f9dc ... 2018-01-31 10:14:08 +05:30
Kovid Goyal
b95e0fb80e Shorten build/run commands 2018-01-30 15:59:31 +05:30
Kovid Goyal
6ad21fc98f Update bundled glfw 2018-01-29 12:30:05 +05:30
Kovid Goyal
bff9b03935 ... 2018-01-28 10:18:02 +05:30
Kovid Goyal
edf9413356 Add a setting to adjust the width of cells, similar to the existing setting to adjust the height of cells 2018-01-28 10:16:59 +05:30
Kovid Goyal
c74f4a8165 Fix extra columns cut-off from the right edge of italic characters that are too wide to fit in a cell 2018-01-28 10:06:39 +05:30
Kovid Goyal
8201cd3288 Add a Makefile target for building kitty-profile 2018-01-26 21:35:48 +05:30
Kovid Goyal
1603310b86 Fix off-by-one when iterating over selections that stretch into the history buf
Fixes #295
2018-01-25 20:50:34 +05:30
Kovid Goyal
627b91ffba version 0.7.0 2018-01-24 15:33:16 +05:30
Kovid Goyal
9ad65f2e1d Cleanup layouts patch
Fix bottom rect in horizontal layout not covering all windows. Fix pep8
issues. Add README and CHANGELOG entries.
2018-01-23 19:35:30 +05:30
Guybrush Threepwood
a6a606ff3d Added vertical and horizontal layouts 2018-01-23 19:30:41 +05:30
Kovid Goyal
63317f9c78 macOS: Fix alt+arrow keys not working when disabling the macos_option_as_alt config option. 2018-01-21 15:41:56 +05:30
Kovid Goyal
46d9dfb614 ... 2018-01-20 17:33:55 +05:30
Kovid Goyal
be3b33af06 Update CHANGELOG 2018-01-19 17:08:21 +05:30
Kovid Goyal
04e1b8b1ae tab bar blank rects dont extend down enough 2018-01-19 17:05:18 +05:30
Kovid Goyal
213768b6e0 Option to place tab bar at the top edge
Fixes #288
2018-01-19 17:04:58 +05:30
Kovid Goyal
aff1abdb26 Fix top line of hollow block cursor 1px too high 2018-01-19 16:23:47 +05:30
Kovid Goyal
44a413df81 Fix blank rects on the sides of the tab bar not being drawn 2018-01-19 16:02:07 +05:30
Kovid Goyal
4f12c91fff Use the new region function everywhere
Centralizes window layout calculation and no longer assumes
tab bar geometry
2018-01-19 15:56:07 +05:30
Kovid Goyal
b6188bf436 Move window region calculations into one place 2018-01-19 11:31:44 +05:30
Kovid Goyal
b9a14e0e4a A Makefile target for building kitty.app 2018-01-19 10:42:12 +05:30
Kovid Goyal
6882c23f43 Update CHANGELOG 2018-01-18 16:26:33 +05:30
Kovid Goyal
80301d465b Handle non-BMP combining characters
Use a level of indirection to store combining characters. This allows
combining characters to be stored using only two bytes, even if they are
after USHORT_MAX
2018-01-18 16:25:42 +05:30
Kovid Goyal
32632264ee Mapping that can be used to store unicode mark symbols in only two bytes 2018-01-18 16:06:07 +05:30
Kovid Goyal
409bd37db5 Store combining chars as an array in the Cell
Makes it easier to increase the number of combining chars if needed,
rather than storing them as a mask.
2018-01-18 14:10:58 +05:30
Kovid Goyal
5fd4bc965f Annotate Cell structure
Make it clear what parts are needed only on the CPU
2018-01-18 12:47:49 +05:30
Kovid Goyal
e86e5ce1d8 ... 2018-01-18 00:15:39 +05:30
Kovid Goyal
5faa649452 Drop the dependency on libunistring 2018-01-18 00:09:40 +05:30
Kovid Goyal
2ddc7e8c80 Have all marks return a wcwidth of -1
Mirrors recent change to onsidering all marks combining chars instead of
only the marks with a non-zero combining class
2018-01-17 23:25:59 +05:30
Kovid Goyal
ed700ff830 ... 2018-01-17 21:59:10 +05:30
Kovid Goyal
33ed873997 Remove unnecessary extra test for combinig characters
There are not combining characters with a non-zero combining class that
are not in the marks category.
2018-01-17 21:56:30 +05:30
Kovid Goyal
9125c00f96 Update CHANGELOG 2018-01-17 21:50:00 +05:30
Kovid Goyal
73fe3293be Fix copying from selection being restricted to only the visible part of the selection. Fixes #287 2018-01-17 21:39:24 +05:30
Kovid Goyal
804c4fbe19 Recognize characters from the unicode Mark categories as combining characters, even if they do not have a combining class (i.e. are not re-ordered). Fixes #286 2018-01-15 11:24:11 +05:30
Kovid Goyal
d6c82ba21c oops 2018-01-14 11:18:44 +05:30
Kovid Goyal
67308f2ca1 Add some documentation for the shaping algorithm 2018-01-14 11:18:44 +05:30
Kovid Goyal
4a17a946fb Ensure groups dont have too many cells 2018-01-14 11:18:44 +05:30
Kovid Goyal
1ae7ae4a1d Fix consecutive separate ligatures being rendered in the same group
Rendering multiple ligatures in the smae group is bad for performance
and also causes incorrect rendering if the last ligature in the group
does not fit into the number of cells in the group.
2018-01-14 11:18:44 +05:30
Kovid Goyal
404ca23de3 Make handling of last glyph a little more intelligent 2018-01-14 11:18:44 +05:30
Kovid Goyal
d385952fef Add a bounds check 2018-01-14 11:18:44 +05:30
Kovid Goyal
f03cac8a9d Allow storing more flags in the special glyph cache 2018-01-14 11:18:44 +05:30
Kovid Goyal
4b501fd694 Fix rendering of ligatures with ligature fonts that dont use dummy glyphs 2018-01-14 11:18:43 +05:30
Kovid Goyal
872d39eb2c Have the ctrl+shift+<key> generate the ASCII C0 control codes for the few shifted control codes there are.
See #285
2018-01-14 11:18:30 +05:30
Kovid Goyal
0341cae922 Fix unused function warning 2018-01-13 15:49:44 +05:30
Kovid Goyal
5357a9a1cc Merge branch 'us/master' of https://github.com/koekeishiya/kitty 2018-01-13 07:33:30 +05:30
koekeishiya
3695538a11 fix mac os_window focus issue 2018-01-12 20:24:11 +01:00
Kovid Goyal
7780d52930 DRYer 2018-01-12 11:27:23 +05:30
Kovid Goyal
6a23b4ee47 Allow kitty @xxx in addition to kitty @ xxx 2018-01-12 11:23:34 +05:30
Kovid Goyal
f48b770036 macOS: Fix focus not being transferred on OSWindow close
Fixes #280
2018-01-12 08:05:12 +05:30
Kovid Goyal
81b5d2c4f2 Option to copy to clipboard on mouse select 2018-01-12 07:33:21 +05:30
Kovid Goyal
d43d6ab0a9 Update bundled glfw 2018-01-12 05:34:53 +05:30
Kovid Goyal
5a4e883360 Merge branch 'macos-logo-make' of https://github.com/zchee/kitty 2018-01-11 22:31:18 +05:30
Koichi Shiraishi
eb93cd4048 Add missing 64 size because doesn't create icon_32x32@2x.png 2018-01-12 00:59:19 +09:00
Koichi Shiraishi
d83e3fddb0 Add install 'optipng' description because logo/make.py depends 'optipng' 2018-01-12 00:58:02 +09:00
Kovid Goyal
80ca25e879 ... 2018-01-11 16:03:23 +05:30
Kovid Goyal
c86b34aacd Move to_color into config_utils 2018-01-11 16:02:52 +05:30
Kovid Goyal
8da426039b Make the config parsing code more re-useable 2018-01-11 12:17:18 +05:30
Kovid Goyal
9184e9a28f Update CHANGELOG 2018-01-11 10:46:50 +05:30
Kovid Goyal
578d537d5f kitty icat: Fix some PNG images not being displayed
Work around for bug in ImageMagick where it converts images
into rgba data with fewer rows than specified. Fixes #276
2018-01-11 09:56:40 +05:30
Kovid Goyal
236c92b2b4 No longer use a shell script for the wrapper .app 2018-01-11 08:40:35 +05:30
Kovid Goyal
66a46279f4 ... 2018-01-11 00:26:29 +05:30
Kovid Goyal
eb35edbe20 kitty icat: Fix typo that broke the SIGWNCH signal handler 2018-01-11 00:24:26 +05:30
Kovid Goyal
7cf2404331 Update CHANGELOG 2018-01-10 15:29:58 +05:30
Kovid Goyal
9ccc6bf835 Fix incorrect handling of zero extra pixel offset 2018-01-10 13:54:51 +05:30
Kovid Goyal
025a46bb35 Fix the in cell offset calculations 2018-01-10 13:50:44 +05:30
Kovid Goyal
677e8a1ae9 Make the signal handler a little simpler 2018-01-10 13:37:43 +05:30
Kovid Goyal
03702772d3 kitty icat: Add a --scale-up option to expand images when used with the --place operator 2018-01-10 13:32:05 +05:30
Kovid Goyal
3cd744b247 Implement @focus-window 2018-01-10 13:23:04 +05:30
Kovid Goyal
88523b2692 Add a note about @ls to the tutorial 2018-01-10 13:00:59 +05:30
Kovid Goyal
dcb39eb210 ... 2018-01-10 12:57:15 +05:30
Kovid Goyal
102823809b Add a tutorial for controlling kitty from scripts 2018-01-10 12:54:21 +05:30
Kovid Goyal
23f2b29069 Add --keep-focus for @new-window 2018-01-10 12:36:15 +05:30
Kovid Goyal
7b33a87725 @send-text allow sending from files and stdin 2018-01-10 10:37:43 +05:30
Kovid Goyal
6dde573ed9 Fix __name__ != __main__ when using runpy in the osx-bundle 2018-01-10 08:31:22 +05:30
Kovid Goyal
566e641be1 Allow easily building a kitty.app wrapper to run kitty from source 2018-01-10 07:44:16 +05:30
Kovid Goyal
08d5448523 Move creation of Info.plist and kitty.icns into osx-bundle 2018-01-10 06:58:57 +05:30
Kovid Goyal
c11a20f1ec Add --new-tab to @new-window 2018-01-09 23:09:57 +05:30
Kovid Goyal
e5b9bd2e5a Implement @get-text 2018-01-09 22:48:24 +05:30
Kovid Goyal
6ad49bd7fb Add an option to override the default shell 2018-01-09 16:28:46 +05:30
Kovid Goyal
5d082d8d5a Implement @new-window 2018-01-09 16:13:28 +05:30
Kovid Goyal
977575da73 Implement @close-tab 2018-01-09 15:30:46 +05:30
Kovid Goyal
bced6f31b1 Implement @close-window 2018-01-09 15:27:12 +05:30
Kovid Goyal
6bf04e22cc Fix send_text parsing choking on ''' 2018-01-09 13:10:28 +05:30
Kovid Goyal
2f9784809d Chunk up overly large send text inputs 2018-01-09 02:51:22 +05:30
Kovid Goyal
3e85497c2c Implement @set-tab-title 2018-01-08 16:13:38 +05:30
Kovid Goyal
3b551a1dee Implement @set-window-title 2018-01-08 14:04:27 +05:30
Kovid Goyal
d2fdb1c1eb DRYer 2018-01-08 13:57:43 +05:30
Kovid Goyal
db92af68e9 Fix a couple of typos 2018-01-08 13:54:08 +05:30
Kovid Goyal
815087460c ... 2018-01-08 13:25:25 +05:30
Kovid Goyal
b4cb9d7c4d ... 2018-01-08 13:07:47 +05:30
Kovid Goyal
c6d10c6a23 Use the launch time argv for cmdline on macOS 2018-01-08 13:07:06 +05:30
Kovid Goyal
464c7a80e2 Implement window matching for remote control 2018-01-08 13:01:57 +05:30
Kovid Goyal
4f56cce727 Fix client eating up send-text when seding to same window 2018-01-08 12:48:15 +05:30
Kovid Goyal
7dea6e0ef4 Initial implementation of send-text remote cmd 2018-01-08 12:48:15 +05:30
Kovid Goyal
8c143db381 Add documentation for the ls command 2018-01-08 12:48:15 +05:30
Kovid Goyal
0cea6d5a1b Implement window listing 2018-01-08 12:48:15 +05:30
Kovid Goyal
eff881f4bb Allow sending arbitrary sized escpae codes to children 2018-01-08 12:48:14 +05:30
Kovid Goyal
c64fd1760c More work on remote control 2018-01-08 12:48:14 +05:30
Kovid Goyal
9e361700d2 Handle reading of RC response via stdin 2018-01-08 12:48:14 +05:30
Kovid Goyal
1f976644bf Refactor read with timeout logic into its own function 2018-01-08 12:48:14 +05:30
Kovid Goyal
f3cb68ee40 Framework for remote control 2018-01-08 12:48:14 +05:30
Kovid Goyal
85a3da057f Session file: Allow setting the title for windows 2018-01-08 12:47:47 +05:30
Kovid Goyal
c551384369 Session file: Allow specifying multiple cd directives per tab to have different windows launched with different working directories 2018-01-08 12:38:01 +05:30
Kovid Goyal
ce230b071b Add tests for SGR protocol encoding 2018-01-07 23:48:16 +05:30
Kovid Goyal
13d5f04ad9 A spot of refactoring 2018-01-07 21:26:28 +05:30
Daniels Kursits
3b861de3d2 Fix mouse move events being reported as drag events
when using the SGR mouse reporting protocol

Fixes #271
2018-01-07 21:12:50 +05:30
Kovid Goyal
1ef010689d Add support for clearing the scrollback buffer
kitty now supports using \E3J to clear the screen and scrollback buffer.
See #268
2018-01-06 23:55:49 +05:30
Kovid Goyal
3523ab283f More trailing whitespace 2018-01-06 09:12:23 +05:30
Kovid Goyal
5b2a9b101d Fix trailing whitespace 2018-01-05 21:27:24 +05:30
Kovid Goyal
fdcfcfa1b9 Make alt+backspace delete the previous word
i.e. alt+backspace now sends ^W (werase). THis matches the behavior of
terminal.app and gnome-terminal. Fixes #264
2018-01-05 21:08:42 +05:30
Kovid Goyal
88e9c21a3b Ensure a kitty executable is on PATH even when running from source 2018-01-05 14:56:01 +05:30
Kovid Goyal
973352a98d Allow + prefixing of special invocations 2018-01-05 14:36:31 +05:30
Kovid Goyal
f06f871dfc Handle fork() failures more gracefully 2018-01-05 13:57:49 +05:30
Kovid Goyal
e03c713294 Remove a few more signal unsafe function calls between fork() and exec() 2018-01-05 00:24:15 +05:30
Kovid Goyal
aa107956f9 ... 2018-01-04 23:55:03 +05:30
Kovid Goyal
d725578e1b Silence spurious compiler warning 2018-01-04 23:54:35 +05:30
Kovid Goyal
239eb8202b Move fork()+exec() of child processes into C
By avoiding python in the child process before exec we ensure that
malloc and other unsafe to use after fork functions are not used.
Should also mean that less pages will need to be copied into thec hild
process, leading to marginally faster startups.
2018-01-04 23:19:09 +05:30
Kovid Goyal
58d7439719 Add a note on installing dev packages for X11 on linux
Fixes #260
2018-01-04 18:06:11 +05:30
Kovid Goyal
cc145ec3dd DRYer 2018-01-04 12:38:35 +05:30
Kovid Goyal
847ce37160 Take the mouse wheel multiplier into account when generating keypresses for mouse wheel events. Fixes #262 2018-01-04 12:34:31 +05:30
Kovid Goyal
0305009766 Remove --without-cairo from brew install since it is ignored anyway 2018-01-03 09:22:23 +05:30
Kovid Goyal
fe1b056371 Allow using macOS specific modifier key names in the config file
cmd and option can now be used instead of super and alt respectively.
2018-01-03 08:59:36 +05:30
Kovid Goyal
0c4804db79 DRYer 2017-12-31 09:04:22 +05:30
Kovid Goyal
f7e84df332 Add an explicit OpenGL version test
Apparently there are some pre 3.3 drivers that include the
texture_storage extension. Fixes #258
2017-12-31 08:36:50 +05:30
Kovid Goyal
bd654d22f4 Read the required wayland protocols version from upstream instead of hardcoding it 2017-12-28 14:12:46 +05:30
Kovid Goyal
115de36599 version 0.6.1 2017-12-28 10:40:42 +05:30
Kovid Goyal
b01c3483de Add an option to fade text in inactive windows
Fixes #256
2017-12-28 10:36:48 +05:30
Kovid Goyal
db7f566a0c Update Changelog 2017-12-27 10:17:34 +05:30
Kovid Goyal
9f806e76e7 Fix incorrect condition for aborting cursor geometry calculation 2017-12-27 10:07:21 +05:30
Kovid Goyal
12bdd4dddd Bump min version of wayland-protocols to match upstream 2017-12-27 07:24:38 +05:30
Kovid Goyal
72a1eb237d Fix regression that broke drawing of hollow cursor when window loses focus
Fixes #255
2017-12-27 07:15:48 +05:30
Kovid Goyal
6a89289907 Merge branch 'recmod' of https://github.com/grimpy/kitty 2017-12-27 06:40:53 +05:30
Kovid Goyal
7ed835cf13 Fix a crash when detecting URLs continued onto multiple lines
Fixes #244
2017-12-27 06:35:09 +05:30
Kovid Goyal
4621ff41d9 Skip building the wayland backend on systems with missing wayland protocol definitions
Fixes #254
2017-12-27 06:22:36 +05:30
Jo De Boeck
60e17d5224 Make it possible to modify rectangle selection modifiers
Signed-off-by: Jo De Boeck <deboeck.jo@gmail.com>
2017-12-24 18:40:25 +02:00
Kovid Goyal
1e2f7c705d ... 2017-12-22 12:36:40 +05:30
Kovid Goyal
1ebf0b95c4 Implement reading of cwd of a process on macOS as well 2017-12-21 12:30:34 +05:30
Kovid Goyal
c5acd94456 Add new actions to open tabs/windows with the working directory set to the working directory of the current window
Fixes #237
2017-12-21 11:29:21 +05:30
Kovid Goyal
448ffe01c3 Fix new window being created with different DPI not changing global DPI 2017-12-21 09:06:07 +05:30
Kovid Goyal
5c882f3290 Fix Travis flake failure on gen-wcwidth.py because of old python version 2017-12-20 23:38:16 +05:30
Kovid Goyal
70a4720bf9 Fix for window being opened on secondary monitor using primary monitor DPI 2017-12-20 23:01:06 +05:30
Kovid Goyal
c8aee8c881 Automatically adjust cell height when DPI changes
DPI changes are detected as a change in the ration of the window size to
the framebuffer size. I dont know how reliable that is. Possiblly Fix #77
2017-12-20 22:55:05 +05:30
Kovid Goyal
c2ad0607b8 Fix trailing whitespace in generated unicde data files 2017-12-20 22:44:20 +05:30
Kovid Goyal
d1282b9f55 Add a script to generate wcwidth as well
Generated function is more efficient than the implementation from
wcwidth9 and also makes it easy to update when the unicode standard
changes.
2017-12-20 16:18:05 +05:30
Kovid Goyal
11ee317884 Fix some emoji glyphs not colored on Linux
Linux has a plethora of fonts that contain some emoji glyphs. If one of
those fonts is used as a fallback font for a non-emoji character, it
also gets used for emojis -- leading to non-colored emoji. Fix by making
sure the first fallback font is a dedicated emoji font.
2017-12-20 10:40:27 +05:30
Kovid Goyal
e69de2f968 Use the new glfw API for setting WM_CLASS 2017-12-20 09:18:29 +05:30
Kovid Goyal
2f4f3e3331 Update bundled glfw 2017-12-20 09:07:06 +05:30
Kovid Goyal
020f8a2047 Add trailing space test to travis 2017-12-20 08:52:06 +05:30
Kovid Goyal
b8faba2a16 More trailing space removal 2017-12-20 08:50:09 +05:30
Kovid Goyal
0fcce6ec58 Remove trailing whitespace from native code files 2017-12-20 08:44:47 +05:30
Kovid Goyal
15f5ea92b8 Merge branch 'master' of https://github.com/FabioLolix/kitty 2017-12-20 08:24:20 +05:30
FabioLolix
2bbb5d25eb Updated readme 2017-12-20 00:12:58 +01:00
Kovid Goyal
8d94285a5d Ensure underlines are rendered even for fonts with very poor metrics
Fixes #236
2017-12-19 00:54:04 +05:30
Kovid Goyal
eed11361c5 Fix typo in config directory override env var 2017-12-18 06:59:19 +05:30
Kovid Goyal
b759f96f96 version 0.6.0 2017-12-18 06:39:55 +05:30
Kovid Goyal
df3342d121 Update CHANGELOG 2017-12-18 06:28:57 +05:30
Kovid Goyal
862ed40c44 Update CHANGELOG 2017-12-18 06:26:16 +05:30
Kovid Goyal
8018024cb7 Fix middle and right mouse button swapped
Fixes #235
2017-12-18 05:48:51 +05:30
Kovid Goyal
c8d5f232b3 Some documentation for the kitty extensions to DECCARA 2017-12-17 18:13:39 +05:30
Kovid Goyal
d48b76508b Implement DECCARA
Ability to set text attributes/colors in arbitrary screen regions,
instead of working via the cursor. Note that kitty extends the original
DECCARA spec from the VT-510 to allow setting all supported SGR
attributes.
2017-12-17 18:03:39 +05:30
Kovid Goyal
2d62e10a7e ... 2017-12-16 15:40:09 +05:30
Kovid Goyal
0b3a5a7d45 icat: Add --clear to clear all display images 2017-12-16 10:33:16 +05:30
Kovid Goyal
076658a1e8 Possible fix for crash reported in #233 2017-12-16 10:23:12 +05:30
Kovid Goyal
be1a05b322 ... 2017-12-16 10:22:03 +05:30
Kovid Goyal
945613555a icat: Add option to display image at arbitrary location on screen
Fixes #228
2017-12-16 09:45:49 +05:30
Kovid Goyal
5f75becc5a Add note about creating launcher app for running kitty from source 2017-12-16 09:29:19 +05:30
Kovid Goyal
51ac78f74d X11: Set the WINDOWID environment variable
Fixes #232
2017-12-16 08:57:52 +05:30
Kovid Goyal
3cce9b1c38 ... 2017-12-16 08:54:55 +05:30
Kovid Goyal
8a9ee6f3f5 ... 2017-12-15 16:32:28 +05:30
Kovid Goyal
d3059c09e0 Nicer CLI help output 2017-12-15 14:49:42 +05:30
Kovid Goyal
1f093b4ff2 icat: Add an option to only detect image display support 2017-12-15 14:06:41 +05:30
Kovid Goyal
50470b5747 icat: Add --transfer-mode option
Explicitly control the transfer mode instead of auto-detecting
2017-12-15 13:34:39 +05:30
Kovid Goyal
304f21e79d icat: Fix temp files not being deleted when transmitting using escape codes 2017-12-15 13:18:18 +05:30
Kovid Goyal
cb04deef63 icat: Add a command line argument for horizontal alignment 2017-12-15 13:08:27 +05:30
Kovid Goyal
ddb2e41352 Get rid of argparse from kitty-icat as well 2017-12-15 12:35:30 +05:30
Kovid Goyal
a6700c951a Also filter 8-bit control sequences when sanitizing 2017-12-15 09:36:45 +05:30
Kovid Goyal
684a2e05f4 Move logical DPI calculation into glfw module
Now DPI state is maintained in only one central place.
2017-12-14 18:30:53 +05:30
Kovid Goyal
c7e1a12eb6 Have pt_to_px use global_state instead of get_dpi
DRYer and reduces code size
2017-12-14 18:04:10 +05:30
Kovid Goyal
ce7be5a05e Fix #226 2017-12-14 06:42:52 +05:30
Kovid Goyal
433640de84 Support running on the "low power" GPU on dual GPU macOS machines
Fixes #136
2017-12-14 06:14:22 +05:30
Kovid Goyal
7f19424f2d Fix for kitty sometimes not detecting child death on macOS 2017-12-13 22:20:11 +05:30
Kovid Goyal
b9d0ec0d4c CoreText: Use the layout engine to calculate cell height
Slower, but hopefully more accurate, since it takes into account
whatever kludges Apple is currently using to calculate line height
in its applications.
2017-12-13 14:12:23 +05:30
Kovid Goyal
869abc4d5c ... 2017-12-13 14:05:01 +05:30
Kovid Goyal
872118fcbe CoreText: Fix incorrect underline position and thickness calculation 2017-12-13 13:59:11 +05:30
Kovid Goyal
da0309545e Ensure bounds in add_line() 2017-12-13 13:46:28 +05:30
Kovid Goyal
54b802f1e6 Ensure bounds in add_dline() 2017-12-13 13:45:11 +05:30
Kovid Goyal
d097403a12 Implement select-by-rectangle when holding down Ctrl+Alt
Fixes #225
2017-12-13 13:26:55 +05:30
Kovid Goyal
c81a8216dc Limit the max number of lines to extend URLs over 2017-12-13 12:18:35 +05:30
Kovid Goyal
95683c658b When hovering over a URL, highlight the URL fully even if it continues over multiple lines. Note that URL detection has not changed. A URL will be detected only if the mouse hovers over the line containing the start of the URL. 2017-12-13 11:11:13 +05:30
Kovid Goyal
d25c0d42bc CoreText: Ensure cell_width and cell_height are never zero 2017-12-13 09:35:50 +05:30
Kovid Goyal
77f0328f4f Ensure mouse cursor is in default state when focus is switched to the OSWindow 2017-12-13 08:54:11 +05:30
Kovid Goyal
a1b4f7c92d Fix COreText leak on exit 2017-12-13 08:27:33 +05:30
Kovid Goyal
47704f24c1 CoreText: Get rid of the line height fudge factor
It was leading to larger line heights than in iTerm on High Sierra with
Menlo. Also as per Apple documentation, line height should be ascent +
descent + leading.
https://developer.apple.com/library/content/documentation/TextFonts/Conceptual/CocoaTextArchitecture/TypoFeatures/TextSystemFeatures.html
2017-12-13 08:22:26 +05:30
Kovid Goyal
e0ef563885 Use glfw primary monitor content scale for logical DPI on macOS as well
It gives the correct DPI value on a MacBook Air monitor, while physical
DPI is too high, leading to overlarge fonts.
2017-12-12 23:47:42 +05:30
Kovid Goyal
2e570e21a0 Ensure kitty is on the PATH when running from kitty.app 2017-12-12 23:29:01 +05:30
Kovid Goyal
a962a28b36 ... 2017-12-12 22:23:16 +05:30
Kovid Goyal
898395253b Add test for ignored color id in SGR colon based color sequence 2017-12-12 18:50:37 +05:30
Kovid Goyal
346a9f68b1 Fix #227 2017-12-12 18:38:52 +05:30
Kovid Goyal
dbf8eb773c Add a FAQ entry about building kitty.app 2017-12-12 09:49:41 +05:30
Kovid Goyal
47ed1a4dca Make update-on-ox not depend on remote script 2017-12-11 23:11:34 +05:30
Kovid Goyal
4c566ee37f Clarify FAQ entry further 2017-12-11 21:38:16 +05:30
Kovid Goyal
a29b424477 CoreText: Implement resizing of glyphs too wide to fit 2017-12-11 20:34:23 +05:30
Kovid Goyal
56a30a014c Fix compilation order reversed 2017-12-11 20:28:36 +05:30
Kovid Goyal
abdc149f65 Update travis script 2017-12-11 19:10:00 +05:30
Kovid Goyal
005c4bf29e Finish up CoreText based rendering 2017-12-11 19:04:44 +05:30
Kovid Goyal
c86c166448 More work on positioning glyphs with CoreText 2017-12-11 18:48:14 +05:30
Kovid Goyal
0999ce159e Fix colors incorrect when rendering directly to buf 2017-12-11 10:43:32 +05:30
Kovid Goyal
98d8ab2953 Fix OT shaper not working on macOS
Also dont keep an extra reference to the hb font in fonts.c
2017-12-11 09:48:20 +05:30
Kovid Goyal
5407fa72b4 Start work on rendering with CoreText 2017-12-10 20:28:06 +05:30
Kovid Goyal
e332522a61 Mark backend API in fonts.h header 2017-12-10 09:21:46 +05:30
Kovid Goyal
ee27f23862 Add rgba and lcdfilter fields to the fc-dict 2017-12-09 12:58:23 +05:30
Kovid Goyal
b1853ca966 Dont insist color fonts have bitmaps 2017-12-09 12:01:43 +05:30
Kovid Goyal
ed2e83654f Draw emoji on macOS using CoreText rather than FreeType
Needed because FreeType cannot handle the latest version of the Apple
Color Emoji font, which probably uses SVG-in-OTF instead of SBIX.
Finishes up the color emoji implementation.
2017-12-09 12:01:43 +05:30
Kovid Goyal
ec6dcd53b5 Finish up placement of color emojis
Note that for some reason rendering is broken on Apple
2017-12-09 12:01:43 +05:30
Kovid Goyal
0b6fe99611 Report errors rendering glyphs 2017-12-09 12:01:43 +05:30
Kovid Goyal
03847b15f6 Implement downsampling of color emoji bitmaps
Still need to fix placement of the downsampled bitmaps in the cell
2017-12-09 12:01:43 +05:30
Kovid Goyal
8d7515bd9b Basic color emoji rendering working
Still need to downscale color bitmaps to fit into cells
2017-12-09 12:01:43 +05:30
Kovid Goyal
e4b839742c Add option to control using color emoji or not 2017-12-09 12:01:43 +05:30
Kovid Goyal
f3cdf4194a Prefer color emoji fonts 2017-12-09 12:01:43 +05:30
Kovid Goyal
ef6f4c2fbf Improve fontconfig fallback font queries for emoji 2017-12-09 12:01:43 +05:30
Kovid Goyal
9cda51b5a8 Store sprites in an RGBA texture
Needed to support color emoji
2017-12-09 12:01:42 +05:30
Kovid Goyal
b8093d6b83 ... 2017-12-09 11:28:49 +05:30
Kovid Goyal
ffedc5d170 ... 2017-12-09 11:01:32 +05:30
Kovid Goyal
f223cd4b56 Set use_system_wcwidth to no by default
I am tired of seeing the endless bug reports from people running on
systems with outdated wcwidth() implementations.
2017-12-09 10:53:13 +05:30
Kovid Goyal
111c7fa57c Ensure config file is always decoded as UTF-8 2017-12-08 01:27:35 +05:30
Kovid Goyal
e630abfe7f Revert change to use libpng16
Does not fix the OP's problem.
2017-12-06 21:10:48 +05:30
Kovid Goyal
11b17c09ce Call pkg-config with libpng16 instead of libpng
Should fix compilation on linux systems that have libpng12 as their
default libpng. libpng16 was released over five years ago! Sigh...
Fixes #216
2017-12-06 20:54:46 +05:30
Kovid Goyal
466d96c167 Remove spurious call to Py_DECREF 2017-12-06 10:13:57 +05:30
Kovid Goyal
c90223e4c8 Report unknown CSI r sequences 2017-12-06 00:31:03 +05:30
Kovid Goyal
01324a7ad2 Reduce the rescale threshold from 133% to 125% 2017-12-05 23:32:40 +05:30
Kovid Goyal
122ad8a1f8 Detect if a freetype font has color tables 2017-12-05 23:31:26 +05:30
Kovid Goyal
138bfcf2a8 Fix key-presses mapped to CSI codes not respecting SC81t mode 2017-12-05 20:21:13 +05:30
Kovid Goyal
c95418a947 Remove unused code 2017-12-05 20:21:13 +05:30
Kovid Goyal
b191727567 Some simple tests for sc81t 2017-12-05 20:21:12 +05:30
Kovid Goyal
c17c6cae4c Support S8C1T mode
That is, eight bit control codes. When in S8C1T mode, kitty will send
only eight bit control codes to the client.
2017-12-05 20:21:12 +05:30
Kovid Goyal
ed9b332da5 Add an option to control the underline style for highlighting URLs on mouse over 2017-12-05 12:28:10 +05:30
Kovid Goyal
e8441ce697 Ensure double underline is gapped even when underline thickness is less than three pixels 2017-12-05 11:42:35 +05:30
Kovid Goyal
f2d00589d8 Update test to match new set of pre-rendered sprites 2017-12-04 12:41:50 +05:30
Kovid Goyal
e81ba3b207 Change undercurl escape code to 4:x
See https://github.com/neovim/neovim/issues/7479
for discussion. Also implement double underline.
2017-12-04 12:26:50 +05:30
Kovid Goyal
27cd303a05 Centralize code to convert to SGR
Conversion from formatting attributes to SGR now always goes through a
Cursor.
2017-12-04 10:51:06 +05:30
Kovid Goyal
52ecdfe3a9 Fix incorrect termcap query responses
Did not realize that the responses had to be processed via tparm() i.e.
they should be the actual bytes not the textual representation of them.
This broke the backspace key in vim.
2017-12-03 21:34:55 +05:30
Kovid Goyal
70f71e8ada Fix #211 2017-12-03 00:30:11 +05:30
Kovid Goyal
d12063daad Add configurable shortcuts to go to a tab by number
Fixes #208
2017-12-02 16:31:40 +05:30
Kovid Goyal
b9798c74d4 Support for DCS status and capabilities reporting codes 2017-12-02 14:35:06 +05:30
Kovid Goyal
c12bce3d2f Respond to OSC color query escape codes 2017-12-01 21:02:30 +05:30
Kovid Goyal
73b501c961 Make color parsing a little more robust
Add a few tests for it
2017-12-01 20:02:47 +05:30
Kovid Goyal
08079ad889 Update README on layouts 2017-12-01 12:23:57 +05:30
Kovid Goyal
b4509e341a Update glfw 2017-12-01 12:16:18 +05:30
Kovid Goyal
08ee77d11c Allow D&D of files into kitty
Fixes #206
2017-12-01 12:16:17 +05:30
Kovid Goyal
868c1d634b Apparently libunistring is already installed by brew 2017-12-01 12:16:17 +05:30
Kovid Goyal
ccc67b66c4 Add more options to customize the tab-bar
Fixes #203
2017-12-01 12:16:17 +05:30
Kovid Goyal
a0702f4a97 Add an option to set the window title
Fixes #201
2017-12-01 12:16:17 +05:30
Kovid Goyal
cada4a8ca8 Move changelog entries 2017-12-01 12:16:17 +05:30
Kovid Goyal
af69f714b1 Update CHANGELOG 2017-12-01 12:16:17 +05:30
Kovid Goyal
9c135f9f4c Add a grid window layout
Fixes #192
2017-12-01 12:16:17 +05:30
Kovid Goyal
d1df5ad4e2 Enumerate window layout choices in help 2017-12-01 12:16:17 +05:30
Kovid Goyal
6352f585e8 Fix kitty discarding peer messages in rapid succession 2017-12-01 12:16:17 +05:30
Kovid Goyal
fe3bb92b54 ... 2017-12-01 12:16:17 +05:30
Kovid Goyal
59243355f6 ... 2017-12-01 12:16:16 +05:30
Kovid Goyal
fd49d17591 Paginate --help output 2017-12-01 12:16:16 +05:30
Kovid Goyal
1d9b36996a Line wrap --help output 2017-12-01 12:16:16 +05:30
Kovid Goyal
0cac74d39a Get rid of the horrible argparse
It's slow, bloated and has no support for decent output formatting
2017-12-01 12:16:16 +05:30
Kovid Goyal
fb41ecb2e5 Update bundled glfw 2017-12-01 12:16:16 +05:30
Kovid Goyal
0296d1f9a2 Fix refactor caused cursor visibility to no longer be respected 2017-12-01 12:16:16 +05:30
Kovid Goyal
b51100195a Dont use FBO's unless absolutely necessary
Negative z-index images dont need FBO based rendering when the
background is opaque. Finishes up support for background_opacity.

Fixes #31
2017-12-01 12:16:16 +05:30
Kovid Goyal
b86e0ef669 Tell the OS we dont use depth and stencil buffers 2017-12-01 12:16:16 +05:30
Kovid Goyal
86e33f739c Ensure OS windows have both buffers cleared after a resize/on first render 2017-12-01 12:16:16 +05:30
Kovid Goyal
259dcf376c DRYer 2017-12-01 12:16:16 +05:30
Kovid Goyal
466155fd24 API needed for kitty-bar 2017-12-01 12:16:16 +05:30
Kovid Goyal
452fd71fea Simplify blit vertex shader
Also fixes rendering on macOS which for some reason was not doing the
texture co-ordinate mapping correctly in the old shader.
2017-12-01 12:16:15 +05:30
Kovid Goyal
da8944b551 ... 2017-12-01 12:16:15 +05:30
Kovid Goyal
5e2587920a Call glViewport in the render loop
Ensure FBOs have correct viewport
2017-12-01 12:16:15 +05:30
Kovid Goyal
7fb48dc04c ... 2017-12-01 12:16:15 +05:30
Kovid Goyal
b8e477c6eb Clamp the FBO texture 2017-12-01 12:16:15 +05:30
Kovid Goyal
a3b85883f8 Block cursor should not be affected by background_opacity 2017-12-01 12:16:15 +05:30
Kovid Goyal
e1c553e7b2 Wakeup main loop on peer message received 2017-12-01 12:16:15 +05:30
Kovid Goyal
be6151730d Fix SPECIAL stage in interleaved rendering 2017-12-01 12:16:15 +05:30
Kovid Goyal
444d9536a7 Graphics programs should generate pre-multipled colors in interleaved mode
Also fix a few OpenGL state initialization issues.
2017-12-01 12:16:15 +05:30
Kovid Goyal
ffff343e3d Work on rendering to FBO 2017-12-01 12:16:15 +05:30
Kovid Goyal
f85c050235 Get background_opacity working, at the cost of breaking negative z-index image rendering.
Image rendering will need to use an FBO since OpenGL cannot do proper alpha compositing.
As a first step, the interleaved shaders now generate premultiplied colors as opengl can only alpha blend pre-multipled colors
2017-12-01 12:16:14 +05:30
Kovid Goyal
fe214f43cb Set _NET_STARTUP_ID before the window is mapped 2017-12-01 12:16:14 +05:30
Kovid Goyal
d9b0b5c08f oops, forgot one place to enable GL_BLEND 2017-12-01 12:16:14 +05:30
Kovid Goyal
a561697f04 No need for GL_BLEND while drawing background colors 2017-12-01 12:16:14 +05:30
Kovid Goyal
bbc140e020 Only enable GL_BLEND when actually needed 2017-12-01 12:16:14 +05:30
Kovid Goyal
2bcbcfff44 Start work on background opacity 2017-12-01 12:16:14 +05:30
Kovid Goyal
1fb81d2265 Fix incorrect blending of foreground and background colors when negative z-index images are present
Also optimize the blending calculation a bit by using the mix() function
and just adding the text and strike alphas.
2017-12-01 12:16:14 +05:30
Kovid Goyal
3b4a242e26 Fix sprites uniform not being initialized when using layered rendering
Had no actual bad effects since it is initialized to zero anyway
2017-12-01 12:16:14 +05:30
Kovid Goyal
b8937bc151 Only use wayland if a special env var is present
wayland is currently fairly broken. No window decorations and no key
auto-repeat.
2017-12-01 12:16:14 +05:30
Kovid Goyal
b3de442116 pretty colors 2017-12-01 12:16:14 +05:30
Kovid Goyal
fb797d7735 ... 2017-12-01 12:16:14 +05:30
Kovid Goyal
982a9320c5 Final fixes needed for wayland building
kitty now runs under wayland again
2017-12-01 12:16:13 +05:30
Kovid Goyal
47dec2c2e9 Dynamic detection of wayland 2017-12-01 12:16:13 +05:30
Kovid Goyal
eb8f4e0b3c isosx -> is_macos 2017-12-01 12:16:13 +05:30
Kovid Goyal
85fcd51ea3 Enable building of glfw-wayland backend 2017-12-01 12:16:13 +05:30
Kovid Goyal
9ec6cf721f Update compilation database even after failed builds 2017-12-01 12:16:13 +05:30
Kovid Goyal
bcd4c64b8a Key compilation database by output as well 2017-12-01 12:16:13 +05:30
Kovid Goyal
3b0d8ec500 Nicer error when pkg-config fails 2017-12-01 12:16:13 +05:30
Kovid Goyal
73ce2ccb47 remove unused header 2017-12-01 12:16:13 +05:30
Kovid Goyal
a5078afd1e Move the bell implementation into glfw 2017-12-01 12:16:13 +05:30
Kovid Goyal
32a6dd2aa1 Add a command line switch to set the name part of WM_CLASS independently 2017-12-01 12:16:13 +05:30
Kovid Goyal
02884c5045 Debounce audio bells 2017-12-01 12:16:12 +05:30
Kovid Goyal
25d7668b70 Add an option to control the audio bell volume on X11 2017-12-01 12:16:12 +05:30
Kovid Goyal
2ff39c1578 DRYer 2017-12-01 12:16:12 +05:30
Kovid Goyal
a11d6466c6 Update vendored glfw 2017-12-01 12:16:12 +05:30
Kovid Goyal
df56080303 Fix building on travis/macOS libunistring detection 2017-12-01 12:16:12 +05:30
Kovid Goyal
4d1eb1f729 Install libxkbcommon on Travis 2017-12-01 12:16:12 +05:30
Kovid Goyal
ec06dd7460 Add a --verbose build flag 2017-12-01 12:16:12 +05:30
Kovid Goyal
163ce2a066 Update CHANGELOG 2017-12-01 12:16:12 +05:30
Kovid Goyal
058c1bec10 Workaround for new windows not getting focus events on macOS 2017-12-01 12:16:12 +05:30
Kovid Goyal
ba40bf5e6f remove no longer needed code 2017-12-01 12:16:12 +05:30
Kovid Goyal
d457abdee4 Prevent glfw from doing stupid stuff on cocoa 2017-12-01 12:16:11 +05:30
Kovid Goyal
3773aaa8a1 Get it building on macOS 2017-12-01 12:16:11 +05:30
Kovid Goyal
cfc99baac4 Get rid of ctypes based loading of libglfw/libX11 2017-12-01 12:15:36 +05:30
Kovid Goyal
b6be6ee1e7 Explicitly set expandtab 2017-12-01 12:15:36 +05:30
Kovid Goyal
dfd8a69cf2 Build kitty against bundled glfw 2017-12-01 12:15:36 +05:30
Kovid Goyal
9307486254 Initial import of glfw 2017-12-01 12:15:36 +05:30
Kovid Goyal
6a627cca9e A spot of refactoring 2017-12-01 12:15:36 +05:30
Kovid Goyal
480f4bf44e Build script should not fail on python without threading 2017-12-01 12:15:36 +05:30
Kovid Goyal
b5b2f11b18 Enable parallel builds 2017-12-01 12:15:36 +05:30
Kovid Goyal
ee232fb08c API needed for kitty-bar 2017-12-01 12:15:36 +05:30
Kovid Goyal
ef7dcbf365 API to create initially hidden windows 2017-12-01 12:15:36 +05:30
Kovid Goyal
3e511d217b Pass the window class and size settings when creating a grouped window 2017-12-01 12:15:36 +05:30
Kovid Goyal
b08f4ab593 Use startup notifications in single instance mode 2017-12-01 12:15:35 +05:30
Kovid Goyal
fa1ae39480 Update Changelog 2017-12-01 12:15:35 +05:30
Kovid Goyal
96483a0e92 Finish single_instance implementation 2017-12-01 12:15:35 +05:30
Kovid Goyal
7deb68de61 Get IPC working 2017-12-01 12:15:35 +05:30
Kovid Goyal
bf09c33b99 Move option_parser into its own module 2017-12-01 12:15:35 +05:30
Kovid Goyal
9e5882c9fb Code to handle messages from peers 2017-12-01 12:15:35 +05:30
Kovid Goyal
c5d17934e4 Function to establish IPC communication 2017-12-01 12:15:35 +05:30
Kovid Goyal
c8c1a3618c Get the user cache dir path on macOS 2017-12-01 12:15:35 +05:30
Kovid Goyal
593b4c5a46 Use sigaction() rather than signal() to register signal handlers 2017-12-01 12:15:35 +05:30
Kovid Goyal
d7ea28f8e7 Fix sprite texture not initially bound for new OSWindow 2017-12-01 12:15:35 +05:30
Kovid Goyal
c4bcda80e9 Fix removing OSWindow breaking pointer references in glfw 2017-12-01 12:15:34 +05:30
Kovid Goyal
528573ac80 Make sure window context is correct for all remove_vao calls 2017-12-01 12:15:34 +05:30
Kovid Goyal
dba067d875 Ensure correct OpenGL ctx in effect when creating a new window 2017-12-01 12:15:34 +05:30
Kovid Goyal
5a5d27077c Shortcut to open new OSWindow
Note that rendering is still pretty buggy with multiple windows.
2017-12-01 12:15:34 +05:30
Kovid Goyal
c145dfc832 Forgot to destroy glfw window when closing OSWindow
Also fix double decref of OSWindow->window_title
2017-12-01 12:15:34 +05:30
Kovid Goyal
407431adc8 Debounce resize requests 2017-12-01 12:15:34 +05:30
Kovid Goyal
8e3b5ddb0b Also show mouse cursor when window gains focus 2017-12-01 12:15:34 +05:30
Kovid Goyal
e1b77f0a59 Ensure cleanup when closing OSWindow 2017-12-01 12:15:34 +05:30
Kovid Goyal
81a465f7bc ... 2017-12-01 12:15:34 +05:30
Kovid Goyal
0bec6ea15d Fix mem leak when closing tabs introduced by move to OSWindow 2017-12-01 12:15:34 +05:30
Kovid Goyal
2b988b01c6 Get rid of the needs_render tracking as it was too fragile. 2017-12-01 12:15:34 +05:30
Kovid Goyal
ab604fb149 more bugs 2017-12-01 12:15:33 +05:30
Kovid Goyal
d344c391fd ... 2017-12-01 12:15:33 +05:30
Kovid Goyal
449c1ba5d7 Ensure OSWindow references are not stale 2017-12-01 12:15:33 +05:30
Kovid Goyal
12340e4c60 Ensure window object is fully initialized in callbacks 2017-12-01 12:15:33 +05:30
Kovid Goyal
95aad91a49 ... 2017-12-01 12:15:33 +05:30
Kovid Goyal
c3f5b20ca7 more bugs 2017-12-01 12:15:33 +05:30
Kovid Goyal
f8c7a7a690 more bug fixes 2017-12-01 12:15:33 +05:30
Kovid Goyal
c5649df971 Fix various bugs introduced by the refactoring to support OSWindow 2017-12-01 12:15:33 +05:30
Kovid Goyal
9cedefb50c Port tab_manager and miscellaneous cleanups 2017-12-01 12:15:33 +05:30
Kovid Goyal
96f8f8c79d Remove unused code 2017-12-01 12:15:33 +05:30
Kovid Goyal
889d5b07a6 Pass os_window_id in activate_tab_at 2017-12-01 12:15:32 +05:30
Kovid Goyal
82d17c8a59 DRYer 2017-12-01 12:15:32 +05:30
Kovid Goyal
7ba3aa0c6f ... 2017-12-01 12:15:32 +05:30
Kovid Goyal
598f08e222 Avoid unneccessary roundtrip through python to create VAOs 2017-12-01 12:15:32 +05:30
Kovid Goyal
625798220a ... 2017-12-01 12:15:32 +05:30
Kovid Goyal
2f06c0f721 Remove last view uses of viewport_size and cell_size in python
Also move counters into C
2017-12-01 12:15:32 +05:30
Kovid Goyal
0ec793e8bc Finish porting of borders and layout 2017-12-01 12:15:32 +05:30
Kovid Goyal
e30f88d382 ... 2017-12-01 12:15:32 +05:30
Kovid Goyal
49be779982 Port drawing of borders 2017-12-01 12:15:32 +05:30
Kovid Goyal
2ac8ad39c9 Implement destruction of OS windows 2017-12-01 12:15:32 +05:30
Kovid Goyal
e11a50ae83 Work on migrating the code needed for application startup 2017-12-01 12:15:32 +05:30
Kovid Goyal
eecd0c8d9a Function to remove OSWindows 2017-12-01 12:15:31 +05:30
Kovid Goyal
974950e7de Allocate window management structures on the heap 2017-12-01 12:15:31 +05:30
Kovid Goyal
47446975ac Fix spelling of var name 2017-12-01 12:15:31 +05:30
Kovid Goyal
c69145b6bc Port state.c and all code that calls into it 2017-12-01 12:15:31 +05:30
Kovid Goyal
141a08ec7c Migrate child-monitor.c to use OSWindow 2017-12-01 12:15:31 +05:30
Kovid Goyal
f0003f223a Start work on multi-window support
Port the glfw.c module and various bits of code that depend on it.
2017-12-01 12:15:31 +05:30
Kovid Goyal
a4fe97c88c Apparently libunistring is now already install by brew 2017-12-01 12:08:28 +05:30
Kovid Goyal
cc23515a35 Make the publish script a little smarter 2017-12-01 10:31:50 +05:30
Kovid Goyal
8d2a720fb9 version 0.5.1 2017-12-01 10:15:18 +05:30
Kovid Goyal
9ed980a511 More 32bit fixes 2017-11-30 00:02:44 +05:30
Kovid Goyal
1365eafce5 ... 2017-11-29 18:15:12 +05:30
Kovid Goyal
07b70f8c95 Image display: Fix displaying images taller than two screen heights not scrolling properly
Fixes #194
2017-11-29 18:12:22 +05:30
Kovid Goyal
f16bf2a136 ... 2017-11-29 08:32:00 +05:30
Kovid Goyal
0f2bcfabb3 Sanity check when moving baseline for line height adjustment 2017-11-29 08:30:34 +05:30
Kovid Goyal
d3e8c616b0 Fix text not vertically centered when adjusting line height
Fixes #193
2017-11-29 08:27:28 +05:30
Kovid Goyal
99888996a0 Implement special rendering for unicode block characters
Fixes #184
2017-11-26 21:29:00 +05:30
Kovid Goyal
4c94e16936 Refactor the box drawing showcase code
Make it work with the new font render infrastructure
2017-11-26 19:53:25 +05:30
Kovid Goyal
235f3940f2 DRYer 2017-11-26 18:10:34 +05:30
Kovid Goyal
e86c2f2000 Fix shift+up/down not generating correct escape codes
Fixes #186
2017-11-26 17:34:34 +05:30
Kovid Goyal
65b212fa1b Add a config option to control the line thickness for box drawing characters
Fixes #183
2017-11-26 11:24:27 +05:30
Kovid Goyal
4b0ff03868 Increase max ligature length to 9 chars
Fixes #182
2017-11-26 10:33:57 +05:30
Kovid Goyal
8961eaaa9d Fix compilation error on 32bot systems
Fixes #185
2017-11-26 08:22:14 +05:30
Kovid Goyal
356722b9a6 Fix build failure on systems with __OPTIMZE__ defined
Fixes #181
2017-11-24 22:42:56 +05:30
Kovid Goyal
89e5ae28bb Dont fail to start if the user's /etc/passwd is missing an entry for the current uid
Appears to happen on some nix systems. Fixes #178
2017-11-23 00:40:21 +05:30
Kovid Goyal
b40e1e6492 Decrease minimum fonts size to 4pt 2017-11-21 07:13:17 +05:30
Kovid Goyal
4dc6918b13 Get rid of the send_text_map code
Just transform send_text directives in the config file to map
directives.
2017-11-19 08:56:34 +05:30
Kovid Goyal
1d45a831ef version 0.5.0 2017-11-19 07:59:01 +05:30
Kovid Goyal
32920fee5b Fix super imposing of glyphs generating fringes 2017-11-19 07:56:35 +05:30
Kovid Goyal
121de41930 Make send_text a normal keybaord shortcut action
Uses the new support for arguments to shortcut actions. Fixes #173
2017-11-17 01:27:26 +05:30
Kovid Goyal
a553107da8 Update README 2017-11-16 10:46:42 +05:30
Kovid Goyal
8cad6ae9d6 Fix leak-on-exit from libstartup-notification 2017-11-16 10:29:21 +05:30
Kovid Goyal
ed60e7cf19 Fix #172 2017-11-16 07:47:08 +05:30
Kovid Goyal
a9db9f8874 ... 2017-11-14 12:41:09 +05:30
Kovid Goyal
b9b2570369 Reduce brew install harfbuzz time on travis 2017-11-14 12:01:06 +05:30
Kovid Goyal
c4f61de3fe Add a couple more targets to the makefile 2017-11-14 09:48:59 +05:30
Kovid Goyal
523c9ff0d1 Make incremental building the default 2017-11-14 09:47:08 +05:30
Kovid Goyal
a02fd8411a Generate a compilation database, useful for llvm tooling 2017-11-14 09:31:23 +05:30
Kovid Goyal
98d8d6b915 Update CHANGELOG 2017-11-13 19:48:06 +05:30
Kovid Goyal
2b87e1f601 Fix #170 2017-11-13 19:47:54 +05:30
Kovid Goyal
084fb23930 Forgot to clear hash table roots after deleting
Doesn't matter in normal usage, but causes tests to fail.
2017-11-13 16:12:28 +05:30
Kovid Goyal
244840255b Remove unused function 2017-11-13 16:03:44 +05:30
Kovid Goyal
94c11af7c8 Refactor the font management code
Use a hash table for special glyph status caching
Manage (almost) all global state with a single object
Allocate all fonts on the heap
Fix the use-after-free for fallback fonts
2017-11-13 15:53:34 +05:30
Kovid Goyal
26e6716f67 A test that reliably triggers the current failure 2017-11-13 15:30:30 +05:30
Kovid Goyal
aef8b4ae67 Allow re-use of ensure_space_for macro 2017-11-13 15:29:52 +05:30
Kovid Goyal
a97ba08cbb Fix asan test failure 2017-11-13 09:31:48 +05:30
Kovid Goyal
ddc327b772 Prevent DoS attacks via requesting too many fallback fonts 2017-11-13 08:40:47 +05:30
Kovid Goyal
a70f6405ac Allocate fallback fonts on the heap
The size of a font is quite large ~ 100KB so it does not make sense to
store their data statically.
2017-11-13 08:39:30 +05:30
Kovid Goyal
bf0ad30d17 DRYer 2017-11-13 07:30:35 +05:30
Kovid Goyal
6fbe52acf4 ... 2017-11-13 07:13:42 +05:30
Kovid Goyal
9fccc38382 Better fix for not using the unsafe to break flag
Recognize special glyphs by comparing the index to the glyph for the
codepoint in the font. Cannot rely on glyph width as many glyphs have
zero width. For example the glyph for space characters.
2017-11-13 07:03:58 +05:30
Kovid Goyal
339c0d2980 Put back consumed API 2017-11-12 23:43:22 +05:30
Kovid Goyal
336857a106 A more general cp->gid API 2017-11-12 23:43:21 +05:30
Kovid Goyal
d01e5f72fc Use a cache for dummy glyph lookups 2017-11-12 23:43:21 +05:30
Kovid Goyal
5c6be7f637 Insulate emoji test from system wcwidth 2017-11-12 23:43:21 +05:30
Kovid Goyal
088087df73 Use only cluster numbers and glyph sizes for grouping glyphs into cells
See https://github.com/behdad/harfbuzz/issues/615 for discussion
2017-11-12 23:43:21 +05:30
Kovid Goyal
0bd093ec2e Also fix mouse URXVT_PROTOCOL
Fixes #169
2017-11-12 22:11:20 +05:30
Kovid Goyal
4613e161ce Fix incorrect encoding for mouse events in the UTF8_PROTOCOL
Fixes #167
2017-11-12 22:05:01 +05:30
Kovid Goyal
dad9444db0 Dont crash if harfbuzz return null info or positions pointers 2017-11-12 17:18:49 +05:30
Kovid Goyal
dd0080d3ce Fix #168 2017-11-12 16:14:59 +05:30
Kovid Goyal
6b9303ba7d Dont store standard cursors on the window object 2017-11-12 12:42:09 +05:30
Kovid Goyal
eb32423fb6 oops 2017-11-12 12:33:44 +05:30
Kovid Goyal
9bb2a05a9b Update list of major features 2017-11-12 11:49:42 +05:30
Kovid Goyal
653fc0dd7e Fix #50 2017-11-12 11:42:50 +05:30
Kovid Goyal
cee6ef9941 Center multi-cell glyph runs 2017-11-12 11:04:52 +05:30
Kovid Goyal
67a37f1f41 Adjust the point size of fallback and symbol fonts so that their heights match the current cell height 2017-11-12 10:30:57 +05:30
Kovid Goyal
604e82fd65 oops 2017-11-11 21:15:19 +05:30
Kovid Goyal
5f4e003bed Add a ligature shaping test 2017-11-11 20:55:53 +05:30
Kovid Goyal
53e9f35c1f Add test for harfbuzz shaping 2017-11-11 18:47:34 +05:30
Kovid Goyal
c56a2ed055 Ensure that harfbuzz always uses the OpenType shaper 2017-11-11 18:25:25 +05:30
Kovid Goyal
e5d411b80d Refactor font code
DRYer with global state stored in fewer places. And only round-tripping
through python for font selection, not face creation.
2017-11-11 18:14:22 +05:30
Kovid Goyal
98e93cb4bd Workaround for broken CTFontCreateForString 2017-11-11 10:16:43 +05:30
Kovid Goyal
f5040532c5 Ensure combining chars are zero-width regardless of wcwidth implementation 2017-11-11 09:29:28 +05:30
Kovid Goyal
447a2fe8cf ... 2017-11-11 09:20:34 +05:30
Kovid Goyal
a14defbab7 Change the showcase fonts 2017-11-11 09:13:04 +05:30
Kovid Goyal
3592f82e4f Implement fallback fonts in CoreText 2017-11-11 08:08:03 +05:30
Kovid Goyal
4edfa9f4fd Implement loading of bitmap fonts via FreeType
Needed for some fallback fonts such as Apple Color Emoji
2017-11-11 08:07:18 +05:30
Kovid Goyal
51fe1e4dab ... 2017-11-11 07:12:50 +05:30
Kovid Goyal
2df9f3500c Build with --debug in update-on-ox 2017-11-11 07:12:21 +05:30
Kovid Goyal
289cfe7584 Fix bold-italic variant not being auto-selected on macOS 2017-11-10 22:06:11 +05:30
Kovid Goyal
b603d7abb7 Ensure underline_thickness is not zero 2017-11-10 21:46:50 +05:30
Kovid Goyal
3437433ed4 ... 2017-11-10 17:43:47 +05:30
Kovid Goyal
cccacfdf7c Restore Apple's line height fudge factor on macOS 2017-11-10 17:38:36 +05:30
Kovid Goyal
c6fa0503af Simplify font_units_to_pixels
Make use of the precalculated scaling value in the FT Face metrics
object
2017-11-10 17:23:28 +05:30
Kovid Goyal
579933ac27 ... 2017-11-10 15:55:59 +05:30
Kovid Goyal
541f389a06 Work on using FreeType to render on macOS as well 2017-11-10 15:39:53 +05:30
Kovid Goyal
d2654db6f0 oops 2017-11-10 14:57:44 +05:30
Kovid Goyal
c2b2833a37 API to load FreeType font from path and psname 2017-11-10 14:50:15 +05:30
Kovid Goyal
b0fffad0c2 API to create FreeType face from in memory data 2017-11-10 14:30:54 +05:30
Kovid Goyal
774956053a Allow storing arbitrary data on FreeType Face objects 2017-11-10 14:20:20 +05:30
Kovid Goyal
5c582f7639 Start work on harfbuzz rendering on macs 2017-11-10 12:52:54 +05:30
Kovid Goyal
ccc0433fa1 ... 2017-11-10 11:26:58 +05:30
Kovid Goyal
43bf056f09 Add a command to list fonts 2017-11-10 11:02:32 +05:30
Kovid Goyal
1d7b650fd0 ... 2017-11-10 10:30:34 +05:30
Kovid Goyal
fefe6c9024 Use fc-list instead of fc-match to select fonts
This is because there is no way to force fc-match to return a monospace
font. So if the user specifies a non-existent font we end up with some
non-monospaced font, which looks terrible.

Also, this makes the font selection logic or macOS and Linux similar.
2017-11-10 10:15:37 +05:30
Kovid Goyal
b58e900806 Call prerender() in rendering tests setup 2017-11-10 08:30:35 +05:30
Kovid Goyal
ec58777d01 Fix compilation against old versions of fontconfig 2017-11-10 08:28:44 +05:30
Kovid Goyal
7a0b649cbd Fix resizing of fonts 2017-11-10 07:34:52 +05:30
Kovid Goyal
e15bc71930 Code to list fontconfig fonts 2017-11-09 20:53:10 +05:30
Kovid Goyal
6d02e884d8 oops 2017-11-09 17:30:30 +05:30
Kovid Goyal
6d7546aa8c pre-rendering must happen after layout 2017-11-09 17:11:37 +05:30
Kovid Goyal
ace91f04af More appropriate location for function definition 2017-11-09 17:04:31 +05:30
Kovid Goyal
934d21ac30 Wire up a few remaining pieces 2017-11-09 16:55:46 +05:30
Kovid Goyal
79d8c04b00 Hook up render_line 2017-11-09 16:55:45 +05:30
Kovid Goyal
6c838bbc28 Implement dirty line tracking 2017-11-09 16:55:45 +05:30
Kovid Goyal
0277be5856 Track line dirty status in the line buffer 2017-11-09 16:55:45 +05:30
Kovid Goyal
71dcf13edf Fix compiler warning 2017-11-09 16:55:45 +05:30
Kovid Goyal
bc0a77ee31 Only detect support once when testing rendering 2017-11-09 16:55:45 +05:30
Kovid Goyal
758d315b8e Better fix for test 2017-11-09 16:55:45 +05:30
Kovid Goyal
3ec64a17f8 Dont call the font change machinery when the actual size has not changed 2017-11-09 16:55:45 +05:30
Kovid Goyal
dc7d705c87 Runa simplified version of the font rendering test on macOS 2017-11-09 16:55:45 +05:30
Kovid Goyal
6c98b676bb Fix crash on macOS when changing font size 2017-11-09 16:55:45 +05:30
Kovid Goyal
dd6108de5b DRYer 2017-11-09 16:55:44 +05:30
Kovid Goyal
aa1b94aed0 Ensure descriptor is always set for coretext font objects 2017-11-09 16:55:44 +05:30
Kovid Goyal
75e1b30fc1 DRYer 2017-11-09 16:55:44 +05:30
Kovid Goyal
a8bca1c119 Skip the rendering test on macOS
macOS is underpowered junk.
2017-11-09 16:55:44 +05:30
Kovid Goyal
d05ea312ef Fix crash on macOS when failing to get font_descriptor 2017-11-09 16:55:44 +05:30
Kovid Goyal
e72f153a66 Avoid unneccessary exception when failling to find a fallback font 2017-11-09 16:55:44 +05:30
Kovid Goyal
da8bf5adc7 Add rendering tests 2017-11-09 16:55:44 +05:30
Kovid Goyal
ce0e5a893f Make the showcase output a little nicer 2017-11-09 16:55:44 +05:30
Kovid Goyal
c8b7b49d56 Ensure underline_position is viable 2017-11-09 16:55:44 +05:30
Kovid Goyal
9842a47f85 Install an up-to-date version of harfbuzz on travis 2017-11-09 16:55:44 +05:30
Kovid Goyal
1db4286a12 Fix rendering of wide chars 2017-11-09 16:55:43 +05:30
Kovid Goyal
4234a9d963 Sigh apparently unsafe break is not enough 2017-11-09 16:55:43 +05:30
Kovid Goyal
6da465d7d7 Correct the x_offset calculation 2017-11-09 16:55:43 +05:30
Kovid Goyal
a1cb01b3b2 Fix grouping of combining char glyphs 2017-11-09 16:55:43 +05:30
Kovid Goyal
6920d37042 Rendering ligatures now works 2017-11-09 16:55:43 +05:30
Kovid Goyal
1dcdf9534b ... 2017-11-09 16:55:43 +05:30
Kovid Goyal
f9c21b1cb3 Sigh, legacy linux distros 2017-11-09 16:55:43 +05:30
Kovid Goyal
58be99a27e Work on rendering ligatures correctly 2017-11-09 16:55:43 +05:30
Kovid Goyal
ae06879193 Mark unused pending implementation 2017-11-09 16:55:43 +05:30
Kovid Goyal
f121773276 Fix fallback fonts not being free'd on exit 2017-11-09 16:55:42 +05:30
Kovid Goyal
4726bcd210 Implement rendering of glyphs from font files in Freetype 2017-11-09 16:55:42 +05:30
Kovid Goyal
891942494f Implement laoding of harfbuz buffer 2017-11-09 16:55:42 +05:30
Kovid Goyal
0b8e8bff16 Infra to display rendered strings as images for testing 2017-11-09 16:55:42 +05:30
Kovid Goyal
898e87aa7b Dont allocate space for dummy fonts
Also move sprite_map test into fonts test module
2017-11-09 16:55:42 +05:30
Kovid Goyal
d153794c05 ... 2017-11-09 16:55:42 +05:30
Kovid Goyal
742c60f37f harfbuzz is now needed on macOS as well 2017-11-09 16:55:42 +05:30
Kovid Goyal
81143e0c7e Test to render all box drawing characters under the sanitizers 2017-11-09 16:55:42 +05:30
Kovid Goyal
7f610f3b4e ... 2017-11-09 16:55:42 +05:30
Kovid Goyal
4ba17df570 Forward declaration of Face_Type needed 2017-11-09 16:55:42 +05:30
Kovid Goyal
00a73e4d12 Fix weird crash with clang asan 2017-11-09 16:55:41 +05:30
Kovid Goyal
6501ee45b6 Forgot to add bi info to sm_faces 2017-11-09 16:55:41 +05:30
Kovid Goyal
b0bee2f1f3 oops 2017-11-09 16:55:41 +05:30
Kovid Goyal
5a044c0320 ... 2017-11-09 16:55:41 +05:30
Kovid Goyal
6a2f964123 ... 2017-11-09 16:55:41 +05:30
Kovid Goyal
0518cabef6 Infrastructure for rendering cells in the test suite 2017-11-09 16:55:41 +05:30
Kovid Goyal
7d7d82a68d Start working on actually rendering lines of text 2017-11-09 16:55:38 +05:30
Kovid Goyal
0c4bb6a0d6 ... 2017-11-09 16:45:45 +05:30
Kovid Goyal
f25d2ea540 Rip out the old sprite update code 2017-11-09 16:45:45 +05:30
Kovid Goyal
38a5e76c50 More work on line based rendering
Should now build on all platforms
2017-11-09 16:45:45 +05:30
Kovid Goyal
d873d11202 Remove unused code 2017-11-09 16:45:45 +05:30
Kovid Goyal
729395c887 Release old hb_font when changing font size 2017-11-09 16:45:44 +05:30
Kovid Goyal
5007a82ea6 Install harfbuzz on travis + brew 2017-11-09 16:45:44 +05:30
Kovid Goyal
83e114d211 Implement new font methods for CoreText 2017-11-09 16:45:44 +05:30
Kovid Goyal
0d92ea72e1 Add harfbuzz includes on macOS as well 2017-11-09 16:45:44 +05:30
Kovid Goyal
646e8dab0a Fix regression in handling zero cells caused by refactoring 2017-11-09 16:45:44 +05:30
Kovid Goyal
8fc9f97c12 ... 2017-11-09 16:45:44 +05:30
Kovid Goyal
3643a78b18 Start work on line based rendering 2017-11-09 16:45:44 +05:30
Kovid Goyal
8431eef970 Get rid of no longer needed GPU function indirection 2017-11-09 16:45:02 +05:30
Kovid Goyal
e8798b5bf2 Fix UBSan not available on OS X clang 2017-11-08 17:50:32 +05:30
Kovid Goyal
9bef53459f Fix application icon not being placed in apps sub-directory in linux bundle 2017-11-08 17:38:34 +05:30
Kovid Goyal
c2f008672c Use clang by default on macOS 2017-11-08 17:30:55 +05:30
Kovid Goyal
216a66ec4c Add some .gitattributes to ignore generated files in difss/lang stats 2017-11-08 17:12:39 +05:30
Kovid Goyal
c1a1b06fe7 Use -Og when building in debug mode 2017-11-08 17:12:35 +05:30
Kovid Goyal
802524a17a Update CHANGELOG 2017-11-08 16:06:58 +05:30
Kovid Goyal
ea4edaaddd Remove glew from build script 2017-11-08 16:02:35 +05:30
Kovid Goyal
7941ac1810 Remove no longer needed mac specific OpenGL extensions check 2017-11-08 15:59:55 +05:30
Kovid Goyal
de6967df0d Dont strip symbols when updating on ox 2017-11-08 15:56:09 +05:30
Kovid Goyal
ceef207812 Fix compilation with clang 2017-11-08 15:43:59 +05:30
Kovid Goyal
7ed272e971 Use the glad provided facility for debugging OpenGL 2017-11-08 15:40:07 +05:30
Kovid Goyal
6362499fc2 Switch to using glad instead of glew 2017-11-08 15:15:25 +05:30
Kovid Goyal
ff528604dd Add a akeyboard shortcut to toggle full-screen mode 2017-11-08 11:21:54 +05:30
Kovid Goyal
505ae90fd7 macOS: Add an setting to have the option key not behave as alt 2017-11-08 09:14:19 +05:30
Kovid Goyal
1f9acf99b0 Match extended keyboard protocol modifier bitmask with the CSIu protocol from xterm 2017-11-08 08:24:15 +05:30
Kovid Goyal
5392ceea7d Update CHANGELOG 2017-11-07 23:20:19 +05:30
Kovid Goyal
ba1883c1de X11: Add support for startup notifications
Prevents busy cursor in i3 root window after launching and quitting
kitty immediately.
2017-11-07 23:19:15 +05:30
Kovid Goyal
3a81b186b0 Strip bracketed paste end sequence when pasting 2017-11-07 22:16:35 +05:30
Kovid Goyal
204b6fa3e8 Use nested switch statements for key lookup
Replace giant key look up table with nested switch statements.
A little slower, but reduces memory consumption and makes it easier to
add new keyboard modes in the future, if needed. Key lookup was not a
performance bottleneck, in any case.
2017-11-07 20:58:34 +05:30
Kovid Goyal
f3c99546d7 Update CHANGELOG 2017-11-07 17:20:45 +05:30
Kovid Goyal
f137ea7094 Fix handling of alt (option) key on macOS
It now works just as in linux. i.e. alt+a sends <esc>a to the client.
No longer needs turning off alt to generate unicode at the OS level.
2017-11-07 16:19:37 +05:30
Kovid Goyal
88df0890ae Fix crash when displaying more than 64 images in a single session
Also DRYer
2017-11-07 13:34:31 +05:30
Kovid Goyal
aaf593d2df Add a few bounds checks 2017-11-05 10:27:10 +05:30
Kovid Goyal
a614fe615f Improve error reporting of incomplete SGR codes 2017-11-05 10:17:40 +05:30
Kovid Goyal
3cb74a25ba Fix handling of empty SGR code
Was broken by refactoring to support colons in SGR codes
2017-11-05 10:06:33 +05:30
Kovid Goyal
c0114d5e4e DRYer 2017-11-05 09:22:15 +05:30
Kovid Goyal
e90aaa8470 Add support for colons in SGR codes 2017-11-05 08:47:21 +05:30
Kovid Goyal
c762f6199b ... 2017-11-05 08:43:02 +05:30
Kovid Goyal
7119c04c81 ... 2017-11-03 10:22:36 +05:30
Kovid Goyal
18dde7b26c ... 2017-11-03 10:01:52 +05:30
Kovid Goyal
013fd31493 Output more details about unknown CSI codes 2017-11-02 20:48:30 +05:30
Kovid Goyal
490310a9f1 Drop obsolete dependency on xrdb 2017-11-02 11:07:33 +05:30
Kovid Goyal
d900811a7b Merge branch 'subpixel' of https://github.com/lxcode/kitty 2017-11-02 08:25:36 +05:30
Kovid Goyal
b06a09c01a Merge branch 'osxdpi' of https://github.com/lxcode/kitty 2017-11-02 08:24:56 +05:30
lxcode
81f14edb49 Enable subpixel quantization and positioning 2017-11-01 15:37:43 -07:00
lxcode
d39ba72591 Wrong indent level 2017-11-01 15:23:58 -07:00
Kovid Goyal
f04fbde6ca Free argvw in asan-launcher 2017-11-01 15:00:52 +05:30
Kovid Goyal
d9ff3bce72 Cleanup compiler flags a little 2017-11-01 14:35:57 +05:30
Kovid Goyal
21ed07d7ce Ensure python type objects are declared in onlya single unit 2017-11-01 13:14:50 +05:30
Kovid Goyal
6cbd1d1727 Move the tabbar destroy logic into the tab bar class 2017-11-01 12:49:00 +05:30
Kovid Goyal
27701351e1 Fix double-free at exit if in alternate screen mode 2017-11-01 12:16:30 +05:30
Kovid Goyal
6370dccb1a ASAN build fixes 2017-11-01 12:12:15 +05:30
Kovid Goyal
cc77d06ec7 ... 2017-11-01 12:05:33 +05:30
Kovid Goyal
04a61d0e21 Convert test-launcher into a generic asan-launcher so that it can be used to run kitty as well 2017-11-01 12:03:59 +05:30
Kovid Goyal
96f85b187e Handle request to render zerowidth text more gracefully 2017-11-01 11:16:45 +05:30
Kovid Goyal
27a1f27e59 Fix crash caused if a unicode combing character is sent before any text 2017-11-01 11:12:22 +05:30
Kovid Goyal
4098b33bb7 Handle old harfbuzz versions that dont have hb_ft_font_changed 2017-10-30 10:53:52 +05:30
Kovid Goyal
657d0c4e2d Update harfbuzz font when size of font is changed 2017-10-30 10:20:10 +05:30
Kovid Goyal
b0663c1a3c ... 2017-10-28 13:58:43 +05:30
Kovid Goyal
20ff9ff977 Handle negative x-bearing 2017-10-28 13:54:56 +05:30
Kovid Goyal
ed6049b4be Micro-optimization 2017-10-28 13:45:52 +05:30
Kovid Goyal
76d6d5f94b Update Changelog 2017-10-28 10:22:53 +05:30
Kovid Goyal
d8629a2d5b DRYer
Reuse most of the code from the draw_complex_glyph code path for drawing
simple glyphs. Avoids overhead of harfbuzz for simple glyphs.
2017-10-28 10:17:27 +05:30
Kovid Goyal
0652fa1696 Finish up harfbuzz based rendering 2017-10-28 09:33:43 +05:30
Kovid Goyal
a5e6ab2bee More work on complex glyph rendering 2017-10-27 18:17:39 +05:30
Kovid Goyal
b5d105186c Use width instead of pitch 2017-10-27 14:25:18 +05:30
Kovid Goyal
e274b809e2 oops 2017-10-27 14:11:46 +05:30
Kovid Goyal
a2fdea1a98 ... 2017-10-27 13:06:41 +05:30
Kovid Goyal
855d91d9dd Fix composition of bitmaps 2017-10-27 12:50:49 +05:30
Kovid Goyal
8a049039ef More work on rendering complex glyphs 2017-10-27 12:42:12 +05:30
Kovid Goyal
4bea6b7ad9 More work on complex glyph rendering 2017-10-27 11:19:57 +05:30
Kovid Goyal
5b0e2311e9 Store hinting flags on the Face object 2017-10-27 11:19:57 +05:30
Kovid Goyal
25c6735a5f ... 2017-10-27 11:19:57 +05:30
Kovid Goyal
1356bcbb9a Let harfbuzz compile on Travis 2017-10-27 11:19:57 +05:30
Kovid Goyal
c841106902 Allow querying fontconfig for multiple characters 2017-10-27 11:19:57 +05:30
Kovid Goyal
91963095d0 More work on rendering complex glyphs 2017-10-27 11:19:57 +05:30
Kovid Goyal
692bdd3ad5 Allow testing of rendering combined glyphs 2017-10-27 11:19:57 +05:30
Kovid Goyal
e6f758b986 Simplify line_text_at() 2017-10-27 11:19:57 +05:30
Kovid Goyal
89d5387a52 Link against harfbuzz 2017-10-27 11:19:57 +05:30
Kovid Goyal
2b9034759a ... 2017-10-27 10:29:25 +05:30
Kovid Goyal
b4d824e165 Use the glfw 3.3 content scale API to get DPI on X11/wayland 2017-10-27 10:27:42 +05:30
Kovid Goyal
39bc0cd8c5 Wrap the glfw 3.3 content scale API 2017-10-27 10:17:33 +05:30
Kovid Goyal
a2b2e767c1 Merge branch 'patch-1' of https://github.com/tex/kitty 2017-10-26 16:24:32 +05:30
Milan Svoboda
da2d334b7a Add NixOs / nixpkgs installationinfo 2017-10-26 12:10:01 +02:00
Kovid Goyal
05363ba501 ... 2017-10-25 14:48:28 +05:30
Kovid Goyal
e43a26d64c Better error message when GLEW initialization fails 2017-10-25 14:32:44 +05:30
Kovid Goyal
c5c8a18c99 Script to easily update kitty on my macOS test machine 2017-10-24 10:08:03 +05:30
Kovid Goyal
2f5b110c41 Implement an option to have focus follow the mouse
Fixes #156
2017-10-24 09:29:28 +05:30
Kovid Goyal
2443d76ac3 Apparently pep8 now just does not let you use the name l
This is one of the most hilarious bugs in pep8 I have come across
2017-10-23 17:40:53 +05:30
Kovid Goyal
8b54df31ef Fix new pep8 ambiguous name warning 2017-10-23 17:33:57 +05:30
Kovid Goyal
4e7b957cc7 version 0.4.2 2017-10-23 17:11:04 +05:30
Kovid Goyal
b1424cc4c7 ... 2017-10-23 17:09:52 +05:30
Kovid Goyal
be7d0e2016 forgot to remove debugging printf 2017-10-23 16:46:57 +05:30
Kovid Goyal
7e8d509fdd Fix #153 2017-10-23 16:45:17 +05:30
Kovid Goyal
8672a29503 Use a C based SIGCHLD handler
Running python code in signal handlers makes me nervous
2017-10-23 12:42:03 +05:30
292 changed files with 167710 additions and 42374 deletions

13
.gitattributes vendored Normal file
View File

@@ -0,0 +1,13 @@
kitty/wcwidth-std.h linguist-generated=true
kitty/emoji.h linguist-generated=true
kitty/keys.h linguist-generated=true
kitty/charsets.c linguist-generated=true
kitty/key_encoding.py linguist-generated=true
kitty/unicode-data.c
kitty/rgb.py linguist-generated=true
kitty/gl-wrapper.* linguist-generated=true
kitty/khrplatform.h linguist-generated=true
kitty/glfw-wrapper.* linguist-generated=true
glfw/*.c linguist-vendored=true
glfw/*.h linguist-vendored=true
kittens/unicode_input/names.h linguist-generated=true

10
.gitignore vendored
View File

@@ -4,8 +4,16 @@
tags
build
linux-package
kitty.app
logo/*.iconset
test-launcher
compile_commands.json
glad/out
asan-launcher
asan-launcher.dSYM
kitty-profile
dev
__pycache__
glfw/wayland-*-client-protocol.[ch]
docs/_build
docs/generated
.DS_Store

1
.ignore Normal file
View File

@@ -0,0 +1 @@
kittens/unicode_input/names.h

View File

@@ -1,29 +1,50 @@
git:
depth: false
matrix:
fast_finish: true
include:
- os: linux
dist: trusty
dist: xenial
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:
- libgl1-mesa-dev
- libxi-dev
- libxrandr-dev
- libxinerama-dev
- libxcursor-dev
- libxcb-xkb-dev
- libdbus-1-dev
- os: linux
dist: xenial
group: beta
sudo: false
env:
- CC=gcc SANITIZE_ARG=--sanitize
- CC=gcc CFLAGS=-funsigned-char SANITIZE_ARG=--sanitize
language: python
python: "3.5"
addons:
apt:
packages:
- libgl1-mesa-dev
- libfontconfig1-dev
- libglew-dev
- libharfbuzz-dev
- libxi-dev
- libxrandr-dev
- libxinerama-dev
- libxcursor-dev
- libunistring-dev
- libxcb-xkb-dev
- libpng-dev
- libdbus-1-dev
- python3-pil
- os: linux
dist: trusty
dist: xenial
group: beta
sudo: false
env:
@@ -33,35 +54,39 @@ matrix:
addons:
apt:
packages:
- libgl1-mesa-dev
- libfontconfig1-dev
- libglew-dev
- libharfbuzz-dev
- libxi-dev
- libxrandr-dev
- libxinerama-dev
- libxcursor-dev
- libunistring-dev
- libxcb-xkb-dev
- libpng-dev
- libdbus-1-dev
- python3-pil
- os: linux
dist: trusty
dist: xenial
group: beta
sudo: false
env:
- RUN_FLAKE=1 BUILD_PKG=1
- RUN_FLAKE=1 BUILD_PKG=linux-package
language: python
python: "3.5"
python: "3.6"
addons:
apt:
packages:
- libgl1-mesa-dev
- libfontconfig1-dev
- libglew-dev
- libharfbuzz-dev
- libxi-dev
- libxrandr-dev
- libxinerama-dev
- libxcursor-dev
- libunistring-dev
- libxcb-xkb-dev
- libpng-dev
- libdbus-1-dev
- python3-pil
- clang
- os: osx
@@ -70,13 +95,17 @@ matrix:
- os: osx
language: generic
env: USE_BREW=1 BUILD_PKG=1
addons:
homebrew:
update: true
brewfile: true
env: USE_BREW=1 BUILD_PKG=osx-bundle
env:
global:
- PYTHON=python3
- PKG_CONFIG_PATH=$HOME/glfw/lib/pkgconfig:$PKG_CONFIG_PATH
- LD_LIBRARY_PATH=$HOME/glfw/lib:$LD_LIBRARY_PATH
- 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: |
@@ -84,24 +113,39 @@ install: |
if [[ "$RUN_FLAKE" == "1" ]]; then pip install flake8; fi
if [[ "$TRAVIS_OS_NAME" == 'osx' ]]; then
if [[ "$USE_BREW" == "1" ]]; then
brew update;
brew install python3;
brew install glfw;
brew install libunistring;
logo/make.py
else
mkdir -p $SW;
curl https://download.calibre-ebook.com/travis/kitty/osx.tar.xz | tar xJ -C $SW;
fi
else
wget -O glfw-3.2.1.zip https://github.com/glfw/glfw/archive/3.2.1.zip
unzip -q glfw-3.2.1.zip
cd glfw-3.2.1
cmake -DBUILD_SHARED_LIBS=ON -DGLFW_BUILD_EXAMPLES=OFF -DGLFW_BUILD_TESTS=OFF -DGLFW_BUILD_DOCS=OFF -DCMAKE_INSTALL_PREFIX=$HOME/glfw
make
make install
cd ..
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 glfw3
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`
@@ -109,11 +153,20 @@ install: |
set +e
before_script:
- echo $LD_LIBRARY_PATH
- $PYTHON setup.py build --debug $SANITIZE_ARG;
- if [[ "$TRAVIS_OS_NAME" != 'osx' ]]; then ldd ./test-launcher `which $PYTHON`; fi
- echo LD_LIBRARY_PATH=$LD_LIBRARY_PATH PKG_CONFIG_PATH=$PKG_CONFIG_PATH
- $PYTHON setup.py build --debug --verbose $SANITIZE_ARG;
script:
- ./test-launcher
- if [[ "$RUN_FLAKE" == "1" ]]; then flake8 --count .; fi
- if [[ "$BUILD_PKG" == "1" ]]; then $PYTHON setup.py linux-package; fi
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

View File

@@ -1,5 +0,0 @@
#!/usr/bin/env python
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: %YEAR%, %USER% <%MAIL%>
%HERE%

5
Brewfile Normal file
View File

@@ -0,0 +1,5 @@
brew 'imagemagick'
brew 'optipng'
brew 'librsvg'
brew 'harfbuzz'
brew 'python'

View File

@@ -1,51 +1 @@
Changelog
==============
kitty is a feature full, cross-platform, *fast*, OpenGL based terminal emulator.
version 0.4.1 [2017-10-23]
---------------------------
- Fix a regression in 0.4.0 that broke custom key mappings
- Avoid using threads to reap zombie child processes. Also prevent kitty from
hanging if the open program hangs when clicking on a URL.
version 0.4.0 [2017-10-22]
---------------------------
- Support for drawing arbitrary raster graphics (images) in the terminal via a
new graphics protocol. kitty can draw images with full 32-bit color using both
ssh connections and files/shared memory (when available) for better
performance. The drawing primitives support alpha blending and z-index.
Images can be drawn both above and below text. See
https://github.com/kovidgoyal/kitty/blob/master/graphics-protocol.asciidoc
for details.
- Refactor kitty's internals to make it even faster and more efficient. The CPU
usage of kitty + X server while doing intensive tasks such as scrolling a
file continuously in less has been reduced by 50%. There are now two
configuration options ``repaint_delay`` and ``input_delay`` you can use to
fine tune kitty's performance vs CPU usage profile. The CPU usage of kitty +
X when scrolling in less is now significantly better than most (all?) other
terminals. See https://github.com/kovidgoyal/kitty#performance
- Hovering over URLs with the mouse now underlines them to indicate they
can be clicked. Hold down Ctrl+Shift while clicking to open the URL.
- Selection using the mouse is now more intelligent. It does not add
blank cells (i.e. cells that have no content) after the end of text in a
line to the selection.
- The block cursor in now fully opaque but renders the character under it in
the background color, for enhanced visibility.
- Allow combining multiple independent actions into a single shortcut
- Add a new shortcut to pass the current selection to an external program
- Allow creating shortcuts to open new windows running arbitrary commands. You
can also pass the current selection to the command as an arguments and the
contents of the screen + scrollback buffer as stdin to the command.
See https://sw.kovidgoyal.net/kitty/changelog.html

25
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,25 @@
### Reporting bugs
Please first search existing bug reports (especially closed ones) for a report
that matches your issue.
When reporting a bug, provide full details of your environment, that means, at
a minimum, kitty version, OS and OS version, kitty config (ideally a minimal
config to reproduce the issue with).
### Contributing code
Install [the dependencies](https://sw.kovidgoyal.net/kitty/build.html#dependencies)
using your favorite package manager. Build and run kitty [from
source](https://sw.kovidgoyal.net/kitty/build.html#install-and-run-from-source).
Make a fork, submit your Pull Request. If it's a large/controversial change, open an issue
beforehand to discuss it, so that you don't waste your time making a pull
request that gets rejected.
If the code you are submitting is reasonably easily testable, please contribute
tests as well (see the `kitty_tests/` sub-directory for existing tests, which
can be run with `./test.py`).
That's it.

7
INSTALL.md Normal file
View File

@@ -0,0 +1,7 @@
To build from source:
https://sw.kovidgoyal.net/kitty/build.html
Pre-built binaries:
https://sw.kovidgoyal.net/kitty/binary.html

View File

@@ -1,8 +1,45 @@
ifdef V
VVAL=--verbose
endif
ifdef VERBOSE
VVAL=--verbose
endif
all:
python3 setup.py
python3 setup.py $(VVAL)
test:
python3 setup.py test
python3 setup.py $(VVAL) test
clean:
python3 setup.py clean
python3 setup.py $(VVAL) clean
# A debug build
debug:
python3 setup.py build $(VVAL) --debug
# Build with the ASAN and UBSAN sanitizers
asan:
python3 setup.py build $(VVAL) --debug --sanitize
profile:
python3 setup.py build $(VVAL) --profile
logo/kitty.iconset/icon_256x256.png: logo/kitty.svg logo/make.py
logo/make.py
rendered_logo: logo/kitty.iconset/icon_256x256.png
app: rendered_logo
python3 setup.py kitty.app $(VVAL)
man:
$(MAKE) FAIL_WARN=$(FAIL_WARN) -C docs man
html:
$(MAKE) FAIL_WARN=$(FAIL_WARN) -C docs html
linkcheck:
$(MAKE) FAIL_WARN=$(FAIL_WARN) -C docs linkcheck
docs: man html

View File

@@ -1,394 +1,5 @@
= kitty - A terminal emulator
:toc:
:toc-placement!:
// START_SHORTCUT_BLOCK
:sc_close_tab: pass:quotes[`ctrl+shift+q`]
:sc_close_window: pass:quotes[`ctrl+shift+w`]
:sc_copy_to_clipboard: pass:quotes[`ctrl+shift+c`]
:sc_eighth_window: pass:quotes[`ctrl+shift+8`]
:sc_fifth_window: pass:quotes[`ctrl+shift+5`]
:sc_first_window: pass:quotes[`ctrl+shift+1`]
:sc_fourth_window: pass:quotes[`ctrl+shift+4`]
:sc_move_tab_backward: pass:quotes[`ctrl+shift+,`]
:sc_move_tab_forward: pass:quotes[`ctrl+shift+.`]
:sc_move_window_backward: pass:quotes[`ctrl+shift+b`]
:sc_move_window_forward: pass:quotes[`ctrl+shift+f`]
:sc_move_window_to_top: pass:quotes[`ctrl+shift+``]
:sc_new_tab: pass:quotes[`ctrl+shift+t`]
:sc_new_window: pass:quotes[`ctrl+shift+enter`]
:sc_next_layout: pass:quotes[`ctrl+shift+l`]
:sc_next_tab: pass:quotes[`ctrl+shift+right`]
:sc_next_window: pass:quotes[`ctrl+shift+]`]
:sc_ninth_window: pass:quotes[`ctrl+shift+9`]
:sc_paste_from_clipboard: pass:quotes[`ctrl+shift+v`]
:sc_paste_from_selection: pass:quotes[`ctrl+shift+s` or `shift+insert`]
:sc_previous_tab: pass:quotes[`ctrl+shift+left`]
:sc_previous_window: pass:quotes[`ctrl+shift+[`]
:sc_scroll_end: pass:quotes[`ctrl+shift+end`]
:sc_scroll_home: pass:quotes[`ctrl+shift+home`]
:sc_scroll_line_down: pass:quotes[`ctrl+shift+down` or `ctrl+shift+j`]
:sc_scroll_line_up: pass:quotes[`ctrl+shift+up` or `ctrl+shift+k`]
:sc_scroll_page_down: pass:quotes[`ctrl+shift+page_down`]
:sc_scroll_page_up: pass:quotes[`ctrl+shift+page_up`]
:sc_second_window: pass:quotes[`ctrl+shift+2`]
:sc_seventh_window: pass:quotes[`ctrl+shift+7`]
:sc_show_scrollback: pass:quotes[`ctrl+shift+h`]
:sc_sixth_window: pass:quotes[`ctrl+shift+6`]
:sc_tenth_window: pass:quotes[`ctrl+shift+0`]
:sc_third_window: pass:quotes[`ctrl+shift+3`]
// END_SHORTCUT_BLOCK
= kitty - the fast, featureful, GPU based, terminal emulator
See https://sw.kovidgoyal.net/kitty
++++
<img align="left" role="left" src="logo/kitty.png?raw=true"/>
++++
image::https://travis-ci.org/kovidgoyal/kitty.svg?branch=master[Build status, link=https://travis-ci.org/kovidgoyal/kitty]
== Major Features
* Supports tiling multiple terminal windows side by side in different
layouts without needing to use an extra program like tmux
* Supports all modern terminal features: graphics (images), unicode,
true-color, mouse protocol, focus tracking, bracketed paste and so on.
* Supports startup sessions which allow you to specify the window/tab layout,
working directories and programs to run on startup.
* Uses OpenGL for rendering, offloads rendering to the GPU for lower system
load and buttery smooth scrolling. Uses threaded rendering to minimize input
latency.
* Cross-platform support: kitty currently works on Linux and macOS, but because
it uses only OpenGL for rendering, it should be trivial to port to other
platforms.
* Allows you to view the scrollback buffer in a separate window using your
favorite pager program such as less
* Easily hackable (UI layer written in python, inner loops in C for
speed). Less than fifteen thousand lines of code.
image::screenshot.png?raw=true[Screenshot, showing three programs in the "Tall" layout]
toc::[]
== Installation
kitty is designed to run from source, for easy hackability. Make sure
the following dependencies are installed first.
=== Dependencies
* python >= 3.5
* glfw >= 3.2
* libunistring
* zlib
* libpng
* glew >= 2.0 (not needed on macOS)
* fontconfig (not needed on macOS)
* xrdb (only on X11 based systems)
* xsel (only on X11 systems with glfw < 3.3)
* ImageMagick (optional, needed to use the `kitty icat` tool to display images in the terminal)
* gcc or clang (required only for building)
* pkg-config (required only for building)
=== Install and run from source
....
git clone https://github.com/kovidgoyal/kitty && cd kitty
....
Now build the C parts of kitty with the following command:
....
python3 setup.py build
....
You can run kitty, as:
....
python3 /path/to/kitty/folder
....
=== Linux packages
* Arch linux: AUR git package https://aur.archlinux.org/packages/kitty-git/
=== macOS packages
kitty is available as a macOS `dmg` file for easy installation from the
link:../../releases[releases page]. You can also run kitty directly from
source using the above install from source instructions, after installing its
two dependencies (`python >= 3.5` and `glfw >= 3.2` using http://brew.sh/[brew]
or a similar package manager)
== Design philosophy
kitty is designed for power keyboard users. To that end all its controls
work with the keyboard (although it fully supports mouse interactions as
well). Its configuration is a simple, human editable, single file for
easy reproducibility (I like to store config files in source control).
The code in kitty is designed to be simple, modular and hackable. It is
written in a mix of C (for performance sensitive parts) and Python (for
easy hackability of the UI). It does not depend on any large and complex
UI toolkit, using only OpenGL for rendering everything.
Finally, kitty is designed from the ground up to support all modern
terminal features, such as unicode, true color, bold/italic fonts, text
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.
== Tabs and Windows
kitty is capable of running multiple programs organized into tabs and
windows. The top level of organization is the _Tab_. Each tab consists
of one or more _windows_. The windows can be arranged in multiple
different layouts, like windows are organized in a tiling window
manager. The keyboard controls (which are all customizable) for tabs and
windows are:
[[scrolling-shortcuts]]
[options="header"]
=== 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}
|===
[options="header"]
=== Tabs
|===
|Action |Shortcut
|New tab | {sc_new_tab}
|Close tab | {sc_close_tab}
|Next tab | {sc_next_tab}
|Previous tab | {sc_previous_tab}
|Next layout | {sc_next_layout}
|Move tab forward | {sc_move_tab_forward}
|Move tab backward | {sc_move_tab_backward}
|===
[options="header"]
=== Windows
|===
|Action |Shortcut
|New window | {sc_new_window}
|Close window | {sc_close_window}
|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 (windows are counted clockwise from the top left corner) | {sc_first_window}, {sc_second_window} ... {sc_tenth_window}
|===
== The scrollback buffer
kitty supports scrolling back to view history, just like most terminals. You
can use either the <<scrolling-shortcuts,keyboard shortcuts>> or the mouse
scroll wheel to do so. However, kitty has an extra, neat feature. Sometimes you
need to explore the scrollback buffer in more detail, maybe search for some
text or refer to it side-by-side while typing in a follow-up command. kitty
allows you to do this by pressing the {sc_show_scrollback} key-combination,
which will open the scrollback buffer in a new window, using your favorite
pager program (which is `less` by default). You can then explore the scrollback
buffer using whatever program you normally use. Colors and text formatting are
preserved.
== Miscellaneous features
You can double click to select a word and triple click to select a line. You can also
hold down `ctrl+shift` and click on a URL to open it in a browser.
== Layouts
Currently, there are two layouts available,
* Stack -- Only a single maximized window is shown at a time
* Tall -- One window is shown full height on the left, the rest of the windows are shown one below the other on the right.
You can switch between layouts using the {sc_next_layout} key combination.
Writing a new layout only requires about thirty lines of code, so if there is
some layout you want, take a look at link:kitty/layout.py[layout.py] and submit
a pull request!
== Configuration
kitty is highly customizable, everything from keyboard shortcuts, to
painting frames-per-second. See the heavily commented
link:kitty/kitty.conf[default config file]. By default kitty looks for a
config file in the OS config directory (usually
`~/.config/kitty/kitty.conf` on Linux and
`~/Library/Preferences/kitty/kitty.conf` on macOS) but you can pass a specific
path via the `--config` option.
== Startup Sessions
You can control the tabs, window layout, working directory, startup
programs, etc. by creating a "session" file and using the `--session`
command line flag. For example:
....
# Set the window layout for the current tab
layout tall
# Set the working directory for the current tab
cd ~
# Create a window and run the specified command in it
launch zsh
launch vim
launch irssi --profile x
# Create a new tab (the part after new_tab is the optional tab name which will
# be displayed in the tab bar, if omitted, the title of the active window will
# be used instead)
new_tab my tab
cd ~/somewhere
# Set the layouts allowed in this tab
enabled_layouts tall, stack
# Set the current layout
layout stack
launch zsh
# Make the current window the active (focused) window
focus
launch emacs
....
== Protocol Extensions
kitty has a few extensions to the xterm protocol, to enable advanced features,
see link:protocol-extensions.asciidoc[Protocol Extensions].
== Font control
kitty has extremely flexible and powerful font selection features. You can
specify individual families for the regular, bold, italic and bold+italic
fonts. You can even specify specific font families for specific ranges of
unicode characters. This allows precise control over text rendering. It can
come in handy for applications like powerline, without the need to use patched
fonts. See the various font related configuration directives in the
link:kitty/kitty.conf[config file].
== Performance
The main goals for kitty performance are user perceived latency while typing
and "smoothness" while scrolling as well as CPU usage. kitty tries hard to find
an optimum balance for these. To that end it keeps a cache of each rendered
glyph in video RAM so that font rendering is not a bottleneck. Interaction
with child programs takes place in a separate thread from rendering, to improve
smoothness.
There are two parameters you can tune to adjust the performance. ``repaint_delay``
and ``input_delay``. These control the artificial delays introduced into the
render loop to reduce CPU usage. See the link:kitty/kitty.conf[config file] for details.
You can generate detailed per-function performance data using
link:https://github.com/gperftools/gperftools[gperftools]. Build kitty with the
`--profile` flag which will create an executable called `kitty-profile`. Run
that and perform the task you want to analyse, for example, scrolling a large
file with `less`. After you quit, function call statistics will be printed to
`stdout` and you can use tools like *kcachegrind* for more detailed analysis.
Here are some CPU usage numbers for the task of scrolling a file continuously in less.
The CPU usage is for the terminal process and X together and is measured using htop.
The measurements are taken at the same font and window size for all terminals on a
`Intel(R) Core(TM) i7-4820K CPU @ 3.70GHz` CPU with a
`Advanced Micro Devices, Inc. [AMD/ATI] Cape Verde XT [Radeon HD 7770/8760 / R7 250X]` GPU.
|===
| Terminal | CPU usage (X + terminal)
| kitty | 6 - 8%
| xterm | 5 - 7% (but scrolling was extremely janky)
| termite | 10 - 13%
| urxvt | 12 - 14%
| gnome-terminal | 15 - 17%
| konsole | 29 - 31%
|===
As you can see, kitty uses much less CPU than all terminals, except xterm, but
its scrolling "smoothness" is much better than that of xterm (at least to my,
admittedly biased, eyes).
== Note for Linux/macOS packagers
While kitty does use python, it is not a traditional python package, so please do not install it in site-packages.
Instead run,
```
python3 setup.py linux-package
```
This will install kitty into the directory `linux-package`. You can run kitty
with `linux-package/bin/kitty`. All the files needed to run kitty will be in
`linux-package/lib/kitty`. The terminfo file will be installed into
`linux-package/share/terminfo`. Simply copy these files into `/usr` to install
kitty. In other words, `linux-package` is the staging area into which kitty is
installed. You can choose a different staging area, by passing the `--prefix`
argument to `setup.py`.
You should probably split kitty into two packages, `kitty-terminfo` that
installs the terminfo file and `kitty` that installs the main program.
This allows users to install the terminfo file on servers into which they ssh,
without needing to install all of kitty.
This applies to creating packages for kitty for macOS package managers such as
brew or MacPorts as well.
== A tribute
While over the decades I am sure many people have contributed to the
development of the terminal emulator space, there is one individual in
particular I would like to thank. link:http://invisible-island.net[Thomas E.
Dickey], the creator of xterm. xterm is the most comprehensive and
feature-rich terminal emulator I have had the pleasure of using. As I worked on
kitty, I ran headlong into more and more gnarly corners of terminal behavior.
On all those occasions, either the excellent documentation at
link:http://invisible-island.net/xterm/ctlseqs/ctlseqs.html[xterm-ctlseqs] or
investigating the behavior and code of xterm or vttest were invaluable tools to
aid my understanding.
My achievements, if any, in developing kitty would not have been possible without
his prior work and the generous sharing of knowledge accumulated over decades.
Thank you.
== Resources on terminal behavior
http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
https://en.wikipedia.org/wiki/C0_and_C1_control_codes
http://vt100.net/

View File

@@ -3,11 +3,115 @@
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
import sys
sys.debug_gl = '--debug-kitty-gl' in sys.argv
import os
if len(sys.argv) > 1 and sys.argv[1] == 'icat':
from kitty.icat import main
main(sys.argv[1:])
else:
from kitty.main import main
def icat(args):
from kittens.runner import run_kitten
sys.argv = args
run_kitten('icat')
def list_fonts(args):
from kitty.fonts.list import main
main(args)
def remote_control(args):
from kitty.remote_control import main
main(args)
def runpy(args):
sys.argv = ['kitty'] + args[2:]
exec(args[1])
def hold(args):
import subprocess
ret = subprocess.Popen(args[1:]).wait()
sys.stdin.read()
raise SystemExit(ret)
def complete(args):
from kitty.complete import main
main(args[1:], entry_points, namespaced_entry_points)
def launch(args):
import runpy
sys.argv = args[1:]
exe = args[1]
if exe.startswith(':'):
import shutil
exe = shutil.which(exe[1:])
if not exe:
raise SystemExit('{} not found in PATH'.format(args[1][1:]))
runpy.run_path(exe, run_name='__main__')
def run_kitten(args):
try:
kitten = args[1]
except IndexError:
from kittens.runner import list_kittens
list_kittens()
raise SystemExit(1)
sys.argv = args[1:]
from kittens.runner import run_kitten
run_kitten(kitten)
def namespaced(args):
func = namespaced_entry_points[args[1]]
func(args[1:])
entry_points = {
# These two are here for backwards compat
'icat': icat,
'list-fonts': list_fonts,
'runpy': runpy,
'launch': launch,
'kitten': run_kitten,
'@': remote_control,
'+': namespaced,
}
namespaced_entry_points = {k: v for k, v in entry_points.items() if k[0] not in '+@'}
namespaced_entry_points['hold'] = hold
namespaced_entry_points['complete'] = complete
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
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'
elif os.path.isdir('/etc/ssl/certs'):
os.environ['SSL_CERT_DIR'] = '/etc/ssl/certs'
def main():
if getattr(sys, 'frozen', False) and 'darwin' not in sys.platform.lower():
setup_openssl_environment()
first_arg = '' if len(sys.argv) < 2 else sys.argv[1]
func = entry_points.get(first_arg)
if func is None:
if first_arg.startswith('@'):
remote_control(['@', first_arg[1:]] + sys.argv[2:])
elif first_arg.startswith('+'):
namespaced(['+', first_arg[1:]] + sys.argv[2:])
else:
from kitty.main import main
main()
else:
func(sys.argv[1:])
if __name__ == '__main__':
main()

19
asan-launcher.c Normal file
View File

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

View File

@@ -15,7 +15,7 @@ with open('terminfo/kitty.terminfo', 'w') as f:
f.write(generate_terminfo())
os.environ['TERMINFO'] = os.path.join(base, 'terminfo')
subprocess.check_call(['tic', 'terminfo/kitty.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')

View File

@@ -1,2 +1,2 @@
#!/bin/bash
cloc --exclude-list-file <(echo -e 'kitty/wcwidth9.h\nkitty/glfw.c\nkitty/keys.h\nkitty/charsets.c\nkitty/key_encoding.py\nkitty/rgb.py\nkitty/gl.h') kitty
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

20
docs/Makefile Normal file
View File

@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS = -T $(FAIL_WARN)
SPHINXBUILD = python3 .. +launch :sphinx-build
SPHINXPROJ = kitty
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

120
docs/_static/custom.css vendored Normal file
View File

@@ -0,0 +1,120 @@
/*
* custom.css
* Copyright (C) 2018 Kovid Goyal
*
* Distributed under terms of the MIT license.
*/
.float-left-img {
float: left;
margin-right: 1em;
margin-bottom: 1em;
}
.float-right-img { float: right; margin-left: 1em; margin-bottom: 1em }
.half-with-img { max-width: 50% }
.fit-img { max-width: 95% }
div.body p, div.body dd, div.body li, div.body blockquote {
text-align: justify;
}
pre {
white-space: pre-wrap;
}
pre.pre {
white-space: pre;
}
a[href], input[type="submit"] { cursor: pointer; }
img[style] {
/* Used for :scale: images to have them render properly but still popup when clicked */
width: auto !important;
height: auto !important;
}
a {
text-decoration: none !important;
border-bottom: none !important;
}
body div.document {
margin-top: 1ex;
}
.major-features li {
margin-top: 0.75ex;
margin-bottom: 0.75ex;
}
.support-form input[type=submit] {
border-radius: 6px;
box-shadow: rgb(255, 246, 175) 0px 1px 0px 0px;
background: linear-gradient(rgb(255, 236, 100) 5%, rgb(255, 171, 35) 100%) rgb(255, 236, 100);
border: 1px solid rgb(255, 170, 34);
display: inline-block;
color: rgb(51, 51, 51);
font-family: Arial;
font-size: 15px;
font-weight: bold;
padding: 6px 24px;
text-decoration: none;
text-shadow: rgb(255, 238, 102) 0px 1px 0px;
}
.support-form input[type=submit]:hover {
background: linear-gradient(rgb(255, 171, 35) 5%, rgb(255, 236, 100) 100%) rgb(255, 171, 35);
}
.support-form input[type=submit]:focus {
outline: 0;
}
div.sphinxsidebar {
font-size: inherit;
line-height: inherit;
}
#sidebartoc li {
margin-top: 0.75ex;
margin-bottom: 0.75ex;
}
#sidebartoc ul {
list-style: none !important;
}
#sidebartoc a[href]:hover {
color: red;
}
.green {
color: green;
}
.cyan {
color: blue;
}
.env {
font-style: italic;
}
.italic {
font-style: italic;
}
.bold {
font-weight: bold;
}
.title {
font-size: larger;
font-weight: bold
}

13
docs/_templates/layout.html vendored Normal file
View File

@@ -0,0 +1,13 @@
{% 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 -->
{{ super() }}
{% endblock %}

6
docs/_templates/localtoc.html vendored Normal file
View File

@@ -0,0 +1,6 @@
{%- if display_toc %}
<div>&nbsp;</div>
<div id="sidebartoc">
{{ toc }}
</div>
{%- endif %}

22
docs/_templates/searchbox.html vendored Normal file
View File

@@ -0,0 +1,22 @@
{#
basic/searchbox.html
~~~~~~~~~~~~~~~~~~~~
Sphinx sidebar template: quick search box.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
#}
{%- if pagename != "search" and builder != "singlehtml" %}
<div id="searchbox" style="display: none" role="search">
<div class="searchformwrapper">
<form class="search" action="{{ pathto('search') }}" method="get">
<input type="text" name="q" placeholder="{{ _('Search') }}" />
<input type="submit" value="{{ _('Go') }}" style="cursor: pointer" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
{%- endif %}

7
docs/_templates/support.html vendored Normal file
View File

@@ -0,0 +1,7 @@
{% if pagename != "support" %}
<div id="support" style="text-align: center">
<form class="support-form" action="{{ pathto('support') }}" title="{{ _('Donate to support kitty development') }}">
<input type="submit" value="{{ _('Support kitty') }}">
</form>
</div>
{% endif %}

91
docs/binary.rst Normal file
View File

@@ -0,0 +1,91 @@
kitty - Binary install
========================
.. |ins| replace:: curl -L :literal:`https://sw.kovidgoyal.net/kitty/installer.sh` | sh /dev/stdin
.. highlight:: sh
You can install pre-built binaries of |kitty| if you are on macOS or Linux using
the following simple command:
.. parsed-literal::
:class: pre
|ins|
The binaries will be installed in the standard location for your OS,
:file:`/Applications/kitty.app` on macOS and :file:`~/.local/kitty.app` on
Linux. The installer only touches files in that directory. To update kitty,
simply re-run the command.
Manually installing
---------------------
If something goes wrong or you simply do not want to run the installer, you can
manually download and install |kitty| from the `GitHub releases page
<https://github.com/kovidgoyal/kitty/releases>`_. If you are on macOS, download
the :file:`.dmg` and install as normal. If you are on Linux, download the tarball
and extract it into a directory. The |kitty| executable will be in the
:file:`bin` sub-directory.
Desktop integration on Linux
--------------------------------
If you want the kitty icon to appear in the taskbar and an entry for it to be
present in the menus, you will need to install the :file:`kitty.desktop` file.
The details of the following procedure may need to be adjusted for your
particular desktop, but it should work for most major desktop environments.
.. code-block:: sh
# Create a symbolic link to add kitty to PATH (assuming ~/.local/bin is in
# your PATH)
ln -s ~/.local/kitty.app/bin/kitty ~/.local/bin/
# Place the kitty.desktop file somewhere it can be found by the OS
cp ~/.local/kitty.app/share/applications/kitty.desktop ~/.local/share/applications
# Update the path to the kitty icon in the kitty.desktop file
sed -i "s/Icon\=kitty/Icon\=\/home\/$USER\/.local\/kitty.app\/share\/icons\/hicolor\/256x256\/apps\/kitty.png/g" ~/.local/share/applications/kitty.desktop
Customizing the installation
--------------------------------
* You can specify a different install location, with ``dest``:
.. parsed-literal::
:class: pre
|ins| \\
dest=/some/other/location
* You can tell the installer not to launch |kitty| after installing it with
``launch=n``:
.. parsed-literal::
:class: pre
|ins| \\
launch=n
* You can use a previously downloaded dmg/tarball, with ``installer``:
.. parsed-literal::
:class: pre
|ins| \\
installer=/path/to/dmg or tarball
Uninstalling
----------------
All the installer does is copy the kitty files into the install directory. To
uninstall, simply delete that directory.
Building from source
------------------------
|kitty| is easy to build from source, follow the :doc:`instructions <build>`.

113
docs/build.rst Normal file
View File

@@ -0,0 +1,113 @@
Building kitty from source
==============================
.. image:: https://travis-ci.org/kovidgoyal/kitty.svg?branch=master
:alt: Build status
:target: https://travis-ci.org/kovidgoyal/kitty
|kitty| is designed to run from source, for easy hackability. Make sure
the following dependencies are installed first.
Dependencies
----------------
Run-time dependencies:
* python >= 3.5
* harfbuzz >= 1.5.0
* zlib
* libpng
* freetype (not needed on macOS)
* fontconfig (not needed on macOS)
* ImageMagick (optional, needed to use the ``kitty icat`` tool to display images in the terminal)
* pygments (optional, need for syntax highlighting in ``kitty +kitten diff``)
Build-time dependencies:
* gcc or clang
* pkg-config
* For building on Linux in addition to the above dependencies you might also need to install the ``-dev`` packages for:
``libdbus-1-dev``, ``libxcursor-dev``, ``libxrandr-dev``, ``libxi-dev``, ``libxinerama-dev``, ``libgl1-mesa-dev``, ``libxkbcommon-x11-dev``, ``libfontconfig-dev`` and ``libpython-dev``.
if they are not already installed by your distro.
Install and run from source
------------------------------
.. code-block:: sh
git clone https://github.com/kovidgoyal/kitty && cd kitty
Now build the native code parts of |kitty| with the following command::
make
You can run |kitty|, as::
python3 .
If that works, you can create a script to launch |kitty|:
.. code-block:: sh
#!/usr/bin/env python3
import runpy
runpy.run_path('/path/to/kitty/dir', run_name='__main__')
And place it in :file:`~/bin` or :file:`/usr/bin` so that you can run |kitty| using
just ``kitty``.
Building kitty.app on macOS from source
-------------------------------------------
Install `imagemagick`, `optipng` and `librsvg` using `brew` or similar (needed
for the logo generation step). And run::
make app
This :file:`kitty.app` unlike the released one does not include its own copy of
python and the other dependencies. So if you ever un-install/upgrade those dependencies
you might have to rebuild the app.
Note that the released :file:`kitty.dmg` includes all dependencies, unlike the
:file:`kitty.app` built above and is built automatically by using the :file:`kitty` branch of
`build-calibre <https://github.com/kovidgoyal/build-calibre>`_ however, that
is designed to run on Linux and is not for the faint of heart.
Note for Linux/macOS packagers
----------------------------------
The released |kitty| source code is available as a `tarball`_ from
`the GitHub releases page <https://github.com/kovidgoyal/kitty/releases>`_.
While |kitty| does use python, it is not a traditional python package, so please
do not install it in site-packages.
Instead run::
python3 setup.py linux-package
This will install |kitty| into the directory :file:`linux-package`. You can run |kitty|
with :file:`linux-package/bin/kitty`. All the files needed to run kitty will be in
:file:`linux-package/lib/kitty`. The terminfo file will be installed into
:file:`linux-package/share/terminfo`. Simply copy these files into :file:`/usr` to install
|kitty|. In other words, :file:`linux-package` is the staging area into which |kitty| is
installed. You can choose a different staging area, by passing the ``--prefix``
argument to :file:`setup.py`.
You should probably split |kitty| into two packages, :file:`kitty-terminfo` that
installs the terminfo file and :file:`kitty` that installs the main program.
This allows users to install the terminfo file on servers into which they ssh,
without needing to install all of |kitty|.
.. note::
You need a couple of extra dependencies to build linux-package.
:file:`tic` to compile terminfo files, usually found in the
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/>`_.
This applies to creating packages for |kitty| for macOS package managers such as
brew or MacPorts as well.

1134
docs/changelog.rst Normal file

File diff suppressed because it is too large Load Diff

538
docs/conf.py Normal file
View File

@@ -0,0 +1,538 @@
# -*- 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
import os
import re
import subprocess
import sys
from functools import partial
from docutils import nodes
from docutils.parsers.rst.roles import set_classes
from pygments.lexer import RegexLexer, bygroups
from pygments.token import (
Comment, Keyword, Literal, Name, Number, String, Whitespace
)
from sphinx import addnodes
from sphinx.util.logging import getLogger
from kitty.constants import str_version
# config {{{
# -- Project information -----------------------------------------------------
project = 'kitty'
copyright = '2018, Kovid Goyal'
author = 'Kovid Goyal'
building_man_pages = 'man' in sys.argv
# The short X.Y version
version = str_version
# The full version, including alpha/beta/rc tags
release = str_version
logger = getLogger(__name__)
# -- General configuration ---------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
needs_sphinx = '1.7'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.ifconfig',
'sphinx.ext.viewcode',
'sphinx.ext.githubpages',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path .
exclude_patterns = [
'_build', 'Thumbs.db', '.DS_Store',
'generated/cli-*.rst', 'generated/conf-*.rst'
]
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
rst_prolog = '''
.. |kitty| replace:: *kitty*
.. |version| replace:: VERSION
.. _tarball: https://github.com/kovidgoyal/kitty/releases/download/vVERSION/kitty-VERSION.tar.xz
.. role:: green
.. role:: italic
.. role:: bold
.. role:: cyan
.. role:: title
.. role:: env
'''.replace('VERSION', str_version)
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'alabaster'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
html_theme_options = {
'logo': 'kitty.png',
'show_powered_by': False,
'fixed_sidebar': True,
'sidebar_collapse': True,
'github_button': False,
'github_banner': True,
'github_user': 'kovidgoyal',
'github_repo': 'kitty',
# increase contrast of link color with text color
'link': '#00587d',
'link_hover': 'green',
}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static', '../logo/kitty.png']
html_context = {
'css_files': ['_static/custom.css']
}
html_favicon = '../logo/kitty.png'
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# The default sidebars (for documents that don't match any pattern) are
# defined by theme itself. Builtin themes are using these templates by
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
# 'searchbox.html']``.
#
html_sidebars = {
'**': [
'about.html',
'support.html',
'searchbox.html',
'localtoc.html',
'relations.html',
]
}
html_show_sourcelink = False
# -- Options for manual page output ------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('invocation', 'kitty', 'kitty Documentation',
[author], 1)
]
# -- Options for Texinfo output ----------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'kitty', 'kitty Documentation',
author, 'kitty', 'A cross-platform, fast, feature full, GPU based terminal emulator',
'Miscellaneous'),
]
# }}}
# GitHub linking inlne roles {{{
def num_role(which, name, rawtext, text, lineno, inliner, options={}, content=[]):
' Link to a github issue '
try:
issue_num = int(text)
if issue_num <= 0:
raise ValueError
except ValueError:
msg = inliner.reporter.error(
'GitHub issue number must be a number greater than or equal to 1; '
'"%s" is invalid.' % text, line=lineno)
prb = inliner.problematic(rawtext, rawtext, msg)
return [prb], [msg]
url = f'https://github.com/kovidgoyal/kitty/{which}/{issue_num}'
set_classes(options)
node = nodes.reference(rawtext, f'#{issue_num}', refuri=url, **options)
return [node], []
def commit_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
' Link to a github commit '
try:
commit_id = subprocess.check_output(f'git rev-list --max-count=1 --skip=# {text}'.split()).decode('utf-8').strip()
except Exception:
msg = inliner.reporter.error(
f'GitHub commit id "{text}" not recognized.', line=lineno)
prb = inliner.problematic(rawtext, rawtext, msg)
return [prb], [msg]
url = f'https://github.com/kovidgoyal/kitty/commit/{commit_id}'
set_classes(options)
short_id = subprocess.check_output(f'git rev-list --max-count=1 --abbrev-commit --skip=# {commit_id}'.split()).decode('utf-8').strip()
node = nodes.reference(rawtext, f'commit: {short_id}', refuri=url, **options)
return [node], []
# }}}
# Sidebar ToC {{{
def create_toc(app, pagename):
toctree = app.env.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)
if bl is None:
return # Empty ToC
subtree = subtree[bl]
# for li in subtree.traverse(nodes.list_item):
# modify_li(li)
# subtree['ids'] = [ID]
return app.builder.render_partial(subtree)['fragment']
def add_html_context(app, pagename, templatename, context, *args):
if 'toc' in context:
context['toc'] = create_toc(app, pagename) or context['toc']
# }}}
# CLI docs {{{
def write_cli_docs(all_kitten_names):
from kitty.cli import option_spec_as_rst
with open('generated/cli-kitty.rst', 'w') as f:
f.write(option_spec_as_rst(appname='kitty').replace(
'kitty --to', 'kitty @ --to'))
as_rst = partial(option_spec_as_rst, heading_char='_')
from kitty.remote_control import global_options_spec, cli_msg, cmap, all_commands
with open('generated/cli-kitty-at.rst', 'w') as f:
p = partial(print, file=f)
p('kitty @\n' + '-' * 80)
p('.. program::', 'kitty @')
p('\n\n' + as_rst(
global_options_spec, message=cli_msg, usage='command ...', appname='kitty @'))
from kitty.cmds import cli_params_for
for cmd_name in all_commands:
func = cmap[cmd_name]
p(f'.. _at_{func.name}:\n')
p('kitty @', func.name + '\n' + '-' * 120)
p('.. program::', 'kitty @', func.name)
p('\n\n' + as_rst(*cli_params_for(func)))
from kittens.runner import get_kitten_cli_docs
for kitten in all_kitten_names:
data = get_kitten_cli_docs(kitten)
if data:
with open(f'generated/cli-kitten-{kitten}.rst', 'w') as f:
p = partial(print, file=f)
p('.. program::', f'kitty +kitten {kitten}')
p('\n\n' + option_spec_as_rst(
data['options'], message=data['help_text'], usage=data['usage'], appname=f'kitty +kitten {kitten}',
heading_char='^'))
# }}}
# config file docs {{{
class ConfLexer(RegexLexer):
name = 'Conf'
aliases = ['conf']
filenames = ['*.conf']
tokens = {
'root': [
(r'#.*?$', Comment.Single),
(r'\s+$', Whitespace),
(r'\s+', Whitespace),
(r'(include)(\s+)(.+?)$', bygroups(Comment.Preproc, Whitespace, Name.Namespace)),
(r'(map)(\s+)(\S+)(\s+)', bygroups(
Keyword.Declaration, Whitespace, String, Whitespace), 'action'),
(r'(symbol_map)(\s+)(\S+)(\s+)(.+?)$', bygroups(
Keyword.Declaration, Whitespace, String, Whitespace, Literal)),
(r'([a-zA-Z_0-9]+)(\s+)', bygroups(
Name.Variable, Whitespace), 'args'),
],
'action': [
(r'[a-z_0-9]+$', Name.Function, 'root'),
(r'[a-z_0-9]+', Name.Function, 'args'),
],
'args': [
(r'\s+', Whitespace, 'args'),
(r'\b(yes|no)\b$', Number.Bin, 'root'),
(r'\b(yes|no)\b', Number.Bin, 'args'),
(r'[+-]?[0-9]+\s*$', Number.Integer, 'root'),
(r'[+-]?[0-9.]+\s*$', Number.Float, 'root'),
(r'[+-]?[0-9]+', Number.Integer, 'args'),
(r'[+-]?[0-9.]+', Number.Float, 'args'),
(r'#[a-fA-F0-9]{3,6}\s*$', String, 'root'),
(r'#[a-fA-F0-9]{3,6}\s*', String, 'args'),
(r'.+', String, 'root'),
],
}
class SessionLexer(RegexLexer):
name = 'Session'
aliases = ['session']
filenames = ['*.session']
tokens = {
'root': [
(r'#.*?$', Comment.Single),
(r'[a-z][a-z0-9_]+', Name.Function, 'args'),
],
'args': [
(r'.*?$', Literal, 'root'),
]
}
def link_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
m = re.match(r'(.+)\s+<(.+?)>', text)
if m is None:
msg = inliner.reporter.error(f'link "{text}" not recognized', line=lineno)
prb = inliner.problematic(rawtext, rawtext, msg)
return [prb], [msg]
text, url = m.group(1, 2)
set_classes(options)
node = nodes.reference(rawtext, text, refuri=url, **options)
return [node], []
def expand_opt_references(conf_name, text):
conf_name += '.'
def expand(m):
ref = m.group(1)
if '<' not in ref and '.' not in ref:
full_ref = conf_name + ref
return ':opt:`{} <{}>`'.format(ref, full_ref)
return m.group()
return re.sub(r':opt:`(.+?)`', expand, text)
opt_aliases = {}
shortcut_slugs = {}
def parse_opt_node(env, sig, signode):
"""Transform an option description into RST nodes."""
count = 0
firstname = ''
for potential_option in sig.split(', '):
optname = potential_option.strip()
if count:
signode += addnodes.desc_addname(', ', ', ')
text = optname.split('.', 1)[-1]
signode += addnodes.desc_name(text, text)
if not count:
firstname = optname
signode['allnames'] = [optname]
else:
signode['allnames'].append(optname)
opt_aliases[optname] = firstname
count += 1
if not firstname:
raise ValueError('{} is not a valid opt'.format(sig))
return firstname
def parse_shortcut_node(env, sig, signode):
"""Transform a shortcut description into RST nodes."""
conf_name, text = sig.split('.', 1)
signode += addnodes.desc_name(text, text)
return sig
def render_conf(conf_name, all_options):
from kitty.conf.definition import merged_opts, Option
ans = ['.. default-domain:: conf', '']
a = ans.append
current_group = None
all_options = list(all_options)
kitty_mod = 'kitty_mod'
def render_group(group):
a('')
a(f'.. _conf-{conf_name}-{group.name}:')
a('')
a(group.short_text)
heading_level = '+' if '.' in group.name else '^'
a(heading_level * (len(group.short_text) + 20))
a('')
if group.start_text:
a(group.start_text)
a('')
def handle_group_end(group):
if group.end_text:
a(''), a(current_group.end_text)
def handle_group(new_group, new_group_is_shortcut=False):
nonlocal current_group
if new_group is not current_group:
if current_group:
handle_group_end(current_group)
current_group = new_group
render_group(current_group)
def handle_option(i, opt):
nonlocal kitty_mod
if not opt.long_text or not opt.add_to_docs:
return
handle_group(opt.group)
if opt.name == 'kitty_mod':
kitty_mod = opt.defval_as_string
mopts = list(merged_opts(all_options, opt, i))
a('.. opt:: ' + ', '.join(conf_name + '.' + mo.name for mo in mopts))
a('.. code-block:: conf')
a('')
sz = max(len(x.name) for x in mopts)
for mo in mopts:
a((' {:%ds} {}' % sz).format(mo.name, mo.defval_as_string))
a('')
if opt.long_text:
a(expand_opt_references(conf_name, opt.long_text))
a('')
def handle_shortcuts(shortcuts):
sc = shortcuts[0]
handle_group(sc.group, True)
sc_text = f'{conf_name}.{sc.short_text}'
a('.. shortcut:: ' + sc_text)
shortcuts = [s for s in shortcuts if s.add_to_default]
shortcut_slugs[f'{conf_name}.{sc.name}'] = (sc_text, sc.key.replace('kitty_mod', kitty_mod))
if shortcuts:
a('.. code-block:: conf')
a('')
for x in shortcuts:
if x.add_to_default:
a(' map {} {}'.format(x.key.replace('kitty_mod', kitty_mod), x.action_def))
a('')
if sc.long_text:
a(expand_opt_references(conf_name, sc.long_text))
a('')
for i, opt in enumerate(all_options):
if isinstance(opt, Option):
handle_option(i, opt)
else:
handle_shortcuts(opt)
if current_group:
handle_group_end(current_group)
return '\n'.join(ans)
def process_opt_link(env, refnode, has_explicit_title, title, target):
conf_name, opt = target.partition('.')[::2]
if not opt:
conf_name, opt = 'kitty', conf_name
full_name = conf_name + '.' + opt
return title, opt_aliases.get(full_name, full_name)
def process_shortcut_link(env, refnode, has_explicit_title, title, target):
conf_name, slug = target.partition('.')[::2]
if not slug:
conf_name, slug = 'kitty', conf_name
full_name = conf_name + '.' + slug
try:
target, title = shortcut_slugs[full_name]
except KeyError:
logger.warning('Unknown shortcut: {}'.format(target), location=refnode)
return title, target
def write_conf_docs(app, all_kitten_names):
app.add_lexer('conf', ConfLexer())
app.add_object_type(
'opt', 'opt',
indextemplate="pair: %s; Config Setting",
parse_node=parse_opt_node,
)
# Warn about opt references that could not be resolved
opt_role = app.registry.domain_roles['std']['opt']
opt_role.warn_dangling = True
opt_role.process_link = process_opt_link
app.add_object_type(
'shortcut', 'sc',
indextemplate="pair: %s; Keyboard Shortcut",
parse_node=parse_shortcut_node,
)
sc_role = app.registry.domain_roles['std']['sc']
sc_role.warn_dangling = True
sc_role.process_link = process_shortcut_link
def generate_default_config(all_options, name):
from kitty.conf.definition import as_conf_file
with open(f'generated/conf-{name}.rst', 'w', encoding='utf-8') as f:
print('.. highlight:: conf\n', file=f)
f.write(render_conf(name, all_options.values()))
conf_name = re.sub(r'^kitten-', '', name) + '.conf'
with open(f'generated/conf/{conf_name}', 'w', encoding='utf-8') as f:
text = '\n'.join(as_conf_file(all_options.values()))
print(text, file=f)
from kitty.config_data import all_options
generate_default_config(all_options, 'kitty')
from kittens.runner import get_kitten_conf_docs
for kitten in all_kitten_names:
all_options = get_kitten_conf_docs(kitten)
if all_options:
generate_default_config(all_options, f'kitten-{kitten}')
# }}}
def setup(app):
os.makedirs('generated/conf', exist_ok=True)
from kittens.runner import all_kitten_names
all_kitten_names = all_kitten_names()
write_cli_docs(all_kitten_names)
write_conf_docs(app, all_kitten_names)
app.add_lexer('session', SessionLexer())
app.add_role('link', link_role)
app.add_role('iss', partial(num_role, 'issues'))
app.add_role('pull', partial(num_role, 'pull'))
app.add_role('commit', commit_role)
app.connect('html-page-context', add_html_context)

40
docs/conf.rst Normal file
View File

@@ -0,0 +1,40 @@
:tocdepth: 2
Configuring kitty
===============================
.. highlight:: conf
|kitty| is highly customizable, everything from keyboard shortcuts, to painting
frames-per-second. See below for an overview of all customization
possibilities.
You can open the config file within kitty by pressing :sc:`edit_config_file`.
You can also display the current configuration by running ``kitty
--debug-config``.
.. _confloc:
|kitty| looks for a config file in the OS config directories (usually
:file:`~/.config/kitty/kitty.conf`) but you can pass a specific path via the
:option:`kitty --config` option or use the ``KITTY_CONFIG_DIRECTORY``
environment variable. See the :option:`kitty --config` option for full details.
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
expanded, so :code:`${USER}.conf` becomes :file:`name.conf` if
:code:`USER=name`. For example::
include other.conf
.. include:: /generated/conf-kitty.rst
Sample kitty.conf
^^^^^^^^^^^^^^^^^^^^^
You can download a sample :file:`kitty.conf` file with all default settings and
comments describing each setting by clicking: :download:`sample kitty.conf
</generated/conf/kitty.conf>`.

134
docs/faq.rst Normal file
View File

@@ -0,0 +1,134 @@
Frequently Asked Questions
==============================
.. highlight:: sh
.. 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
standard says they should be rendered in two cells. When a symbol does not fit,
it will either be rescaled to be smaller or truncated (depending on how much
extra space it needs). This is often different from other terminals which just
let the character overflow into neighboring cells, which is fine if the
neighboring cell is empty, but looks terrible if it is not.
Some programs, like powerline, vim with fancy gutter symbols/status-bar, etc.
misuse unicode characters from the private use area to represent symbols. Often
these symbols are square and should be rendered in two cells. However, since
private use area symbols all have their width set to one in the unicode
standard, |kitty| renders them either smaller or truncated. The exception is if
these characters are followed by a space or empty cell in which case kitty
makes use of the extra cell to render them in two cells.
Using a color theme with a background color does not work well in vim?
-----------------------------------------------------------------------
First make sure you have not changed the TERM environment variable, it should
be ``xterm-kitty``. vim uses *background color erase* even if the terminfo file
does not contain the ``bce`` capability. This is a bug in vim. You can work around
it by adding the following to your vimrc::
let &t_ut=''
See :ref:`here <ext_styles>` for why |kitty| does not support background color erase.
I get errors about the terminal being unknown or opening the terminal failing when SSHing into a different computer?
-----------------------------------------------------------------------------------------------------------------------
This happens because the |kitty| terminfo files are not available on the server.
You can ssh in using the following command which will automatically copy the
terminfo files to the server::
kitty +kitten ssh myserver
If for some reason that does not work (typically because the server is using a
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, 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
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>`_
to set colors or you can enable :doc:`remote control <remote-control>`
for |kitty| and use :ref:`at_set-colors`.
How do I specify command line options for kitty on macOS?
---------------------------------------------------------------
Apple does not want you to use command line options with GUI applications. To
workaround that limitation, |kitty| will read command line options from the file
:file:`<kitty config dir>/macos-launch-services-cmdline` when it is launched
from the GUI, i.e. by clicking the |kitty| application icon or using ``open -a kitty``.
Note that this file is *only read* when running via the GUI.
You can, of course, also run |kitty| from a terminal with command line options, using:
:file:`/Applications/kitty.app/Contents/MacOS/kitty`.
And within |kitty| itself, you can always run |kitty| using just `kitty` as it
cleverly adds itself to the ``PATH``.
kitty is not able to use my favorite font?
---------------------------------------------
|kitty| achieves its stellar performance by caching alpha masks of each rendered
character on the GPU, so that every character needs to be rendered only once.
This means it is a strictly character cell based display. As such it can use
only monospace fonts, since every cell in the grid has to be the same size. If
your font is not listed in ``kitty list-fonts`` it means that it is not
monospace. On Linux you can list all monospace fonts with::
fc-list : family spacing | grep spacing=100
How can I assign a single global shortcut to bring up the kitty terminal?
-----------------------------------------------------------------------------
Bringing up applications on a single key press is the job of the window
manager/desktop environment. For ways to do it with kitty (or indeed any
terminal) in different environments,
see `here <https://github.com/kovidgoyal/kitty/issues/45>`_.

443
docs/graphics-protocol.rst Normal file
View File

@@ -0,0 +1,443 @@
:tocdepth: 3
The terminal graphics protocol
==================================
The goal of this specification is to create a flexible and performant protocol
that allows the program running in the terminal, hereafter called the *client*,
to render arbitrary pixel (raster) graphics to the screen of the terminal
emulator. The major design goals are
* Should not require terminal emulators to understand image formats.
* Should allow specifying graphics to be drawn at individual pixel positions.
* The graphics should integrate with the text, in particular it should be possible to draw graphics
below as well as above the text, with alpha blending. The graphics should also scroll with the text, automatically.
* Should use optimizations when the client is running on the same computer as the terminal emulator.
For some discussion regarding the design choices, see `#33
<https://github.com/kovidgoyal/kitty/issues/33>`_.
To see a quick demo, inside a |kitty| terminal run::
kitty +kitten icat path/to/some/image.png
You can also see a screenshot with more sophisticated features such as
alpha-blending and text over graphics.
.. image:: https://user-images.githubusercontent.com/1308621/31647475-1188ab66-b326-11e7-8d26-24b937f1c3e8.png
:alt: Demo of graphics rendering in kitty
:align: center
Some programs that use the kitty graphics protocol:
* `termpdf <https://github.com/dsanson/termpdf>`_ - a terminal PDF/DJVU/CBR viewer
* `ranger <https://github.com/ranger/ranger>`_ - a terminal file manager, with
image previews, see this `PR <https://github.com/ranger/ranger/pull/1077>`_
* :doc:`kitty-diff <kittens/diff>` - a side-by-side terminal diff program with support for images
* `neofetch <https://github.com/dylanaraps/neofetch>`_ - A command line system
information tool
.. contents::
Getting the window size
-------------------------
In order to know what size of images to display and how to position them, the
client must be able to get the window size in pixels and the number of cells
per row and column. This can be done by using the ``TIOCGWINSZ`` ioctl. Some
code to demonstrate its use
In C:
.. code-block:: c
struct ttysize ts;
ioctl(0, TIOCGWINSZ, &ts);
printf("number of columns: %i, number of rows: %i, screen width: %i, screen height: %i\n", sz.ws_col, sz.ws_row, sz.ws_xpixel, sz.ws_ypixel);
In Python:
.. code-block:: python
import array, fcntl, termios
buf = array.array('H', [0, 0, 0, 0])
fcntl.ioctl(sys.stdout, termios.TIOCGWINSZ, buf)
print('number of columns: {}, number of rows: {}, screen width: {}, screen height: {}'.format(*buf))
Note that some terminals return ``0`` for the width and height values. Such
terminals should be modified to return the correct values. Examples of
terminals that return correct values: ``kitty, xterm``
You can also use the *CSI t* escape code to get the screen size. Send
``<ESC>[14t`` to *stdout* and kitty will reply on *stdin* with
``<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
---------------------------
All graphics escape codes are of the form::
<ESC>_G<control data>;<payload><ESC>\
This is a so-called *Application Programming Command (APC)*. Most terminal
emulators ignore APC codes, making it safe to use.
The control data is a comma-separated list of ``key=value`` pairs. The payload
is arbitrary binary data, base64-encoded to prevent interoperation problems
with legacy terminals that get confused by control codes within an APC code.
The meaning of the payload is interpreted based on the control data.
The first step is to transmit the actual image data.
Transferring pixel data
--------------------------
The first consideration when transferring data between the client and the
terminal emulator is the format in which to do so. Since there is a vast and
growing number of image formats in existence, it does not make sense to have
every terminal emulator implement support for them. Instead, the client should
send simple pixel data to the terminal emulator. The obvious downside to this
is performance, especially when the client is running on a remote machine.
Techniques for remedying this limitation are discussed later. The terminal
emulator must understand pixel data in three formats, 24-bit RGB, 32-bit RGBA and
PNG. This is specified using the ``f`` key in the control data. ``f=32`` (which is the
default) indicates 32-bit RGBA data and ``f=24`` indicates 24-bit RGB data and ``f=100``
indicates PNG data. The PNG format is supported for convenience and a compact way
of transmitting paletted images.
RGB and RGBA data
~~~~~~~~~~~~~~~~~~~
In these formats the pixel data is stored directly as 3 or 4 bytes per pixel, respectively.
When specifying images in this format, the image dimensions **must** be sent in the control data.
For example::
<ESC>_Gf=24,s=10,v=20;<payload><ESC>\
Here the width and height are specified using the ``s`` and ``v`` keys respectively. Since
``f=24`` there are three bytes per pixel and therefore the pixel data must be ``3 * 10 * 20 = 600``
bytes.
PNG data
~~~~~~~~~~~~~~~
In this format any PNG image can be transmitted directly. For example::
<ESC>_Gf=100;<payload><ESC>\
The PNG format is specified using the ``f=100`` key. The width and height of
the image will be read from the PNG data itself. Note that if you use both PNG and
compression, then you must provide the ``S`` key with the size of the PNG data.
Compression
~~~~~~~~~~~~~
The client can send compressed image data to the terminal emulator, by specifying the
``o`` key. Currently, only zlib based deflate compression is supported, which is specified using
``o=z``. For example::
<ESC>_Gf=24,s=10,v=20,o=z;<payload><ESC>\
This is the same as the example from the RGB data section, except that the
payload is now compressed using deflate. The terminal emulator will decompress
it before rendering. You can specify compression for any format. The terminal
emulator will decompress before interpreting the pixel data.
The transmission medium
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The transmission medium is specified using the ``t`` key. The ``t`` key defaults to ``d``
and can take the values:
================== ============
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. 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
================== ============
Local client
^^^^^^^^^^^^^^
First let us consider the local client techniques (files and shared memory). Some examples::
<ESC>_Gf=100,t=f;<encoded /path/to/file.png><ESC>\
Here we tell the terminal emulator to read PNG data from the specified file of
the specified size::
<ESC>_Gs=10,v=2,t=s,o=z;<encoded /some-shared-memory-name><ESC>\
Here we tell the terminal emulator to read compressed image data from
the specified shared memory object.
The client can also specify a size and offset to tell the terminal emulator
to only read a part of the specified file. The is done using the ``S`` and ``O``
keys respectively. For example::
<ESC>_Gs=10,v=2,t=s,S=80,O=10;<encoded /some-shared-memory-name><ESC>\
This tells the terminal emulator to read ``80`` bytes starting from the offset ``10``
inside the specified shared memory buffer.
Remote client
^^^^^^^^^^^^^^^^
Remote clients, those that are unable to use the filesystem/shared memory to
transmit data, must send the pixel data directly using escape codes. Since
escape codes are of limited maximum length, the data will need to be chunked up
for transfer. This is done using the ``m`` key. The pixel data must first be
base64 encoded then chunked up into chunks no larger than ``4096`` bytes. The client
then sends the graphics escape code as usual, with the addition of an ``m`` key that
must have the value ``1`` for all but the last chunk, where it must be ``0``. For example,
if the data is split into three chunks, the client would send the following
sequence of escape codes to the terminal emulator::
<ESC>_Gs=100,v=30,m=1;<encoded pixel data first chunk><ESC>\
<ESC>_Gm=1;<encoded pixel data second chunk><ESC>\
<ESC>_Gm=0;<encoded pixel data last chunk><ESC>\
Note that only the first escape code needs to have the full set of control
codes such as width, height, format etc. Subsequent chunks must have
only the ``m`` key. The client **must** finish sending all chunks for a single image
before sending any other graphics related escape codes.
Detecting available transmission mediums
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Since a client has no a-priori knowledge of whether it shares a filesystem/shared memory
with the terminal emulator, it can send an id with the control data, using the ``i`` key
(which can be an arbitrary positive integer up to 4294967295, it must not be zero).
If it does so, the terminal emulator will reply after trying to load the image, saying
whether loading was successful or not. For example::
<ESC>_Gi=31,s=10,v=2,t=s;<encoded /some-shared-memory-name><ESC>\
to which the terminal emulator will reply (after trying to load the data)::
<ESC>_Gi=31;error message or OK<ESC>\
Here the ``i`` value will be the same as was sent by the client in the original
request. The message data will be a ASCII encoded string containing only
printable characters and spaces. The string will be ``OK`` if reading the pixel
data succeeded or an error message.
Sometimes, using an id is not appropriate, for example, if you do not want to
replace a previously sent image with the same id, or if you are sending a dummy
image and do not want it stored by the terminal emulator. In that case, you can
use the *query action*, set ``a=q``. Then the terminal emulator will try to load
the image and respond with either OK or an error, as above, but it will not
replace an existing image with the same id, nor will it store the image.
Display images on screen
-----------------------------
Every transmitted image can be displayed an arbitrary number of times on the
screen, in different locations, using different parts of the source image, as
needed. You can either simultaneously transmit and display an image using the
action ``a=T``, or first transmit the image with a id, such as ``i=10`` and then display
it with ``a=p,i=10`` which will display the previously transmitted image at the current
cursor position. When specifying an image id, the terminal emulator will reply with an
acknowledgement code, which will be either::
<ESC>_Gi=<id>;OK<ESC>\
when the image referred to by id was found, or::
<ESC>_Gi=<id>;ENOENT:<some detailed error msg><ESC>\
when the image with the specified id was not found. This is similar to the
scheme described above for querying available transmission media, except that
here we are querying if the image with the specified id is available or needs to
be re-transmitted.
Controlling displayed image layout
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The image is rendered at the current cursor position, from the upper left corner of
the current cell. You can also specify extra ``X=3`` and ``Y=4`` pixel offsets to display from
a different origin within the cell. Note that the offsets must be smaller that the size of the cell.
By default, the entire image will be displayed (images wider than the available
width will be truncated on the right edge). You can choose a source rectangle (in pixels)
as the part of the image to display. This is done with the keys: ``x, y, w, h`` which specify
the top-left corner, width and height of the source rectangle.
You can also ask the terminal emulator to display the image in a specified rectangle
(num of columns / num of lines), using the control codes ``c,r``. ``c`` is the number of columns
and `r` the number of rows. The image will be scaled (enlarged/shrunk) as needed to fit
the specified area. Note that if you specify a start cell offset via the ``X,Y`` keys, it is not
added to the number of rows/columns.
Finally, you can specify the image *z-index*, i.e. the vertical stacking order. Images
placed in the same location with different z-index values will be blended if
they are semi-transparent. You can specify z-index values using the ``z`` key.
Negative z-index values mean that the images will be drawn under the text. This
allows rendering of text on top of images.
Deleting images
---------------------
Images can be deleted by using the delete action ``a=d``. If specified without any
other keys, it will delete all images visible on screen. To delete specific images,
use the `d` key as described in the table below. Note that each value of d has
both a lowercase and an uppercase variant. The lowercase variant only deletes the
images without necessarily freeing up the stored image data, so that the images can be
re-displayed without needing to resend the data. The uppercase variants will delete
the image data as well, provided that the image is not referenced elsewhere, such as in the
scrollback buffer. The values of the ``x`` and ``y`` keys are the same as cursor positions (i.e.
``x=1, y=1`` is the top left cell).
================= ============
Value of ``d`` Meaning
================= ============
``a`` or ``A`` Delete all images visible on screen
``i`` or ``I`` Delete all images with the specified id, specified using the ``i`` key.
``c`` or ``C`` Delete all images that intersect with the current cursor position.
``p`` or ``P`` Delete all images that intersect a specific cell, the cell is specified using the ``x`` and ``y`` keys
``q`` or ``Q`` Delete all images that intersect a specific cell having a specific z-index. The cell and z-index is specified using the ``x``, ``y`` and ``z`` keys.
``x`` or ``X`` Delete all images that intersect the specified column, specified using the ``x`` key.
``y`` or ``Y`` Delete all images that intersect the specified row, specified using the ``y`` key.
``z`` or ``Z`` Delete all images that have the specified z-index, specified using the ``z`` key.
================= ============
Some examples::
<ESC>_Ga=d<ESC>\ # delete all visible images
<ESC>_Ga=d,i=10<ESC>\ # delete the image with id=10
<ESC>_Ga=Z,z=-1<ESC>\ # delete the images with z-index -1, also freeing up image data
<ESC>_Ga=P,x=3,y=4<ESC>\ # delete all images that intersect the cell at (3, 4)
Image persistence and storage quotas
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In order to avoid *Denial-of-Service* attacks, terminal emulators should have a
maximum storage quota for image data. It should allow at least a few full
screen images. For example the quota in kitty is 320MB per buffer. When adding
a new image, if the total size exceeds the quota, the terminal emulator should
delete older images to make space for the new one.
Control data reference
---------------------------
The table below shows all the control data keys as well as what values they can
take, and the default value they take when missing. All integers are 32-bit.
======= ==================== ========= =================
Key Value Default Description
======= ==================== ========= =================
``a`` Single character. ``t`` The overall action this graphics command is performing.
``(t, T, q, p, d)``
**Keys for image transmission**
-----------------------------------------------------------
``f`` Positive integer. ``32`` The format in which the image data is sent.
``(24, 32, 100)``.
``t`` Single character. ``d`` The transmission medium used.
``(d, f, t, s)``.
``s`` Positive integer. ``0`` The width of the image being sent.
``v`` Positive integer. ``0`` The height of the image being sent.
``S`` Positive integer. ``0`` The size of data to read from a file.
``O`` Positive integer. ``0`` The offset from which to read data from a file.
``i`` Positive integer.
``(0 - 4294967295)`` ``0`` The image id
``o`` Single character. ``null`` The type of data compression.
``only z``
``m`` zero or one ``0`` Whether there is more chunked data available.
**Keys for image display**
-----------------------------------------------------------
``x`` Positive integer ``0`` The left edge (in pixels) of the image area to display
``y`` Positive integer ``0`` The top edge (in pixels) of the image area to display
``w`` Positive integer ``0`` The width (in pixels) of the image area to display. By default, the entire width is used.
``h`` Positive integer ``0`` The height (in pixels) of the image area to display. By default, the entire height is used
``X`` Positive integer ``0`` The x-offset within the first cell at which to start displaying the image
``Y`` Positive integer ``0`` The y-offset within the first cell at which to start displaying the image
``c`` Positive integer ``0`` The number of columns to display the image over
``r`` Positive integer ``0`` The number of rows to display the image over
``z`` Integer ``0`` The *z-index* vertical stacking order of the image
**Keys for deleting images**
-----------------------------------------------------------
``d`` Single character. ``a`` What to delete.
``(a, A, c, C, i,
I, p, P, q, Q, x, X,
y, Y, z, Z)``.
======= ==================== ========= =================
Interaction with other terminal actions
--------------------------------------------
When resetting the terminal, all images that are visible on the screen must be
cleared. When switching from the main screen to the alternate screen buffer
(1049 private mode) all images in the alternate screen must be cleared, just as
all text is cleared. The clear screen escape code (usually ``<ESC>[2J``) should
also clear all images. This is so that the clear command works.
The other commands to erase text must have no effect on graphics.
The dedicated delete graphics commands must be used for those.
When scrolling the screen (such as when using index cursor movement commands,
or scrolling through the history buffer), images must be scrolled along with
text. When page margins are defined and the index commands are used, only
images that are entirely within the page area (between the margins) must be
scrolled. When scrolling them would cause them to extend outside the page area,
they must be clipped.

456
docs/index.rst Normal file
View File

@@ -0,0 +1,456 @@
:tocdepth: 2
==========================================================
kitty - the fast, featureful, GPU based terminal emulator
==========================================================
.. container:: major-features
* Offloads rendering to the GPU for :doc:`lower system load <performance>` and
buttery smooth scrolling. Uses threaded rendering to minimize input latency.
* Supports all modern terminal features: :doc:`graphics (images)
<graphics-protocol>`, unicode, true-color, OpenType ligatures, mouse
protocol, focus tracking, `bracketed paste
<https://cirw.in/blog/bracketed-paste>`_ and several :doc:`new terminal
protocol extensions <protocol-extensions>`.
* Supports tiling multiple terminal windows side by side in different
:ref:`layouts <layouts>` without needing to use an extra program like tmux
* Can be :doc:`controlled from scripts or the shell prompt <remote-control>`,
even over SSH.
* Has a framework for :ref:`kittens`, small terminal programs that can be used to
extend |kitty|'s functionality. For example, they are used for
:doc:`Unicode input <kittens/unicode-input>`, :doc:`Hints <kittens/hints>` and
:doc:`Side-by-side diff <kittens/diff>`.
* Supports :ref:`startup sessions <sessions>` which allow you to specify
the window/tab layout, working directories and programs to run on startup.
* Cross-platform: |kitty| works on Linux and macOS, but because it uses only
OpenGL for rendering, it should be trivial to port to other Unix-like platforms.
* Allows you to open :ref:`the scrollback buffer <scrollback>` in a
separate window using arbitrary programs of your choice. This is useful for
browsing the history comfortably in a pager or editor.
.. figure:: screenshots/screenshot.png
:alt: Screenshot, showing three programs in the 'Tall' layout
:align: center
:scale: 100%
Screenshot, showing vim, tig and git running in |kitty| with the 'Tall' layout
.. _quickstart:
Quickstart
--------------
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.
|kitty| packages are available for:
`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>`_.
See :doc:`Configuring kitty <conf>` for help on configuring |kitty| and
:doc:`Invocation <invocation>` for the command line arguments |kitty| supports.
.. contents::
Design philosophy
-------------------
|kitty| is designed for power keyboard users. To that end all its controls
work with the keyboard (although it fully supports mouse interactions as
well). Its configuration is a simple, human editable, single file for
easy reproducibility (I like to store configuration in source control).
The code in |kitty| is designed to be simple, modular and hackable. It is
written in a mix of C (for performance sensitive parts) and Python (for
easy hackability of the UI). It does not depend on any large and complex
UI toolkit, using only OpenGL for rendering everything.
Finally, |kitty| is designed from the ground up to support all modern
terminal features, such as unicode, true color, bold/italic fonts, text
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.
Tabs and Windows
-------------------
|kitty| is capable of running multiple programs organized into tabs and
windows. The top level of organization is the *Tab*. Each tab consists
of one or more *windows*. The windows can be arranged in multiple
different layouts, like windows are organized in a tiling window
manager. The keyboard controls (which are all customizable) for tabs and
windows are:
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`
======================== =======================
Tabs
~~~~~~~~~~~
======================== =======================
Action Shortcut
======================== =======================
New tab :sc:`new_tab` (also :kbd:`⌘+t` on macOS)
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)
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`
======================== =======================
Windows
~~~~~~~~~~~~~~~~~~
======================== =======================
Action Shortcut
======================== =======================
New window :sc:`new_window`
New OS window :sc:`new_os_window` (also :kbd:`⌘+n` on macOS)
Close window :sc:`close_window` (also :kbd:`⌘+w` 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`
(clockwise from the top-left)
======================== =======================
Additionally, you can define shortcuts in :file:`kitty.conf` to focus neighboring
windows and move windows around (similar to window movement in vim)::
map ctrl+left neighboring_window left
map shift+left move_window right
map ctrl+down neighboring_window down
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
----------------------------------
================================== =======================
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
Input unicode character :sc:`input_unicode_character`
Click URL using the keyboard :sc:`open_url`
Reset the terminal :sc:`reset_terminal`
Pass current selection to program :sc:`pass_selection_to_program`
Edit |kitty| config file :sc:`edit_config_file`
Open a |kitty| shell :sc:`kitty_shell`
Increase background opacity :sc:`increase_background_opacity`
Decrease background opacity :sc:`decrease_background_opacity`
Full background opacity :sc:`full_background_opacity`
Reset background opacity :sc:`reset_background_opacity`
================================== =======================
.. _layouts:
Layouts
----------
A layout is an arrangement of multiple *windows*. You can create a new window
using the :sc:`new_window` key combination.
Currently, there are five layouts available,
* **Stack** -- Only a single maximized window is shown at a time
* **Tall** -- One window is shown full height on the left, the rest of the windows are shown one below the other on the right
* **Fat** -- One window is shown full width on the top, the rest of the windows are shown side-by-side on the bottom
* **Grid** -- All windows are shown in a grid
* **Horizontal** -- All windows are shown side-by-side
* **Vertical** -- All windows are shown one below the other
You can switch between layouts using the :sc:`next_layout` key combination. You can
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
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::
enabled_layouts tall:bias=70
This will make the tall window occupy ``70%`` of available width. ``bias`` can be
any number between 10 and 90.
Writing a new layout only requires about a hundred lines of code, so if there
is some layout you want, take a look at `layout.py
<https://github.com/kovidgoyal/kitty/blob/master/kitty/layout.py>`_ and submit
a pull request!
.. _kittens:
Kittens
------------------
|kitty| has a framework for easily creating terminal programs that make use of
its advanced features. These programs are called kittens. They are used both
to add features to |kitty| itself and to create useful standalone programs.
Some prominent kittens:
:doc:`icat <kittens/icat>`
Display images in the terminal
:doc:`diff <kittens/diff>`
A fast, side-by-side diff for the terminal with syntax highlighting and
images
:doc:`Unicode Input <kittens/unicode-input>`
Easily input arbitrary unicode characters in |kitty| by name or hex code.
:doc:`Hints <kittens/hints>`
Select and open/paste/insert arbitrary text snippets such as URLs,
filenames, words, lines, etc from the terminal screen.
:doc:`Panel <kittens/panel>`
Draw a GPU accelerated dock panel on your desktop showing the output
from an arbitrary terminal program.
:doc:`Clipboard <kittens/clipboard>`
Copy/paste to the clipboard from shell scripts, even over SSH.
You can also :doc:`Learn to create your own kittens <kittens/custom>`.
Configuring kitty
-------------------
|kitty| is highly configurable, everything from keyboard shortcuts to
painting frames-per-second. For details and a sample :file:`kitty.conf`,
see the :doc:`configuration docs <conf>`.
Remote control
------------------
|kitty| has a very powerful system that allows you to control it from the
:doc:`shell prompt, even over SSH <remote-control>`. You can change colors,
fonts, open new windows, tabs, set their titles, change window layout, get text
from one window and send text to another, etc, etc. The possibilities are
endless. See the :doc:`tutorial <remote-control>` to get started.
.. _sessions:
Startup Sessions
------------------
You can control the tabs, window layout, working directory, startup programs,
etc. by creating a "session" file and using the :option:`kitty --session`
command line flag or the :opt:`startup_session` option in :file:`kitty.conf`.
For example:
.. code-block:: session
# Set the window layout for the current tab
layout tall
# Set the working directory for windows in the current tab
cd ~
# Create a window and run the specified command in it
launch zsh
# Create a window with some environment variables set and run
# vim in it
launch env FOO=BAR vim
# Set the title for the next window
title Chat with x
launch irssi --profile x
# Create a new tab (the part after new_tab is the optional tab
# name which will be displayed in the tab bar, if omitted, the
# title of the active window will be used instead)
new_tab my tab
cd ~/somewhere
# Set the layouts allowed in this tab
enabled_layouts tall, stack
# Set the current layout
layout stack
launch zsh
# Make the current window the active (focused) window
focus
launch emacs
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+alt` and drag with the mouse to select in
columns
Font control
-----------------
|kitty| has extremely flexible and powerful font selection features. You can
specify individual families for the regular, bold, italic and bold+italic
fonts. You can even specify specific font families for specific ranges of
unicode characters. This allows precise control over text rendering. It can
come in handy for applications like powerline, without the need to use patched
fonts. See the various font related configuration directives in
:ref:`conf-kitty-fonts`.
.. _scrollback:
The scrollback buffer
-----------------------
|kitty| supports scrolling back to view history, just like most terminals. You
can use either keyboard shortcuts or the mouse scroll wheel to do so. However,
|kitty| has an extra, neat feature. Sometimes you need to explore the
scrollback buffer in more detail, maybe search for some text or refer to it
side-by-side while typing in a follow-up command. |kitty| allows you to do this
by pressing the :sc:`show_scrollback` key-combination, which will open the
scrollback buffer in your favorite pager program (which is ``less`` by default).
Colors and text formatting are preserved. You can explore the scrollback buffer
comfortably within the pager.
Additionally, you can pipe the contents of the scrollback buffer to an
arbitrary, command running in a new window, tab or overlay, for example::
map f1 pipe @ansi window less +G -R
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.
Frequently Asked Questions
---------------------------------
The list of Frequently Asked Questions (*FAQ*) is :doc:`available here <faq>`.
.. _completion:
Completion for kitty
---------------------------------
|kitty| comes with completion for the ``kitty`` command for popular shells.
bash
~~~~~~~~
Add the following to your :file:`~/.bashrc`
.. code-block:: sh
source <(kitty + complete setup bash)
zsh
~~~~~~~~~
Add the following to your :file:`~/.zshrc`
.. code-block:: sh
autoload -Uz compinit
compinit
# Completion for kitty
kitty + complete setup zsh | source /dev/stdin
The important thing above is to make sure the call to |kitty| to load the zsh
completions happens after the call to :file:`compinit`.
fish
~~~~~~~~
Add the following to your :file:`~/.config/fish/config.fish`
.. code-block:: sh
kitty + complete setup fish | source
Changelog
------------------
See :doc:`changelog`.
.. toctree::
:hidden:
:glob:
*
kittens/*

241
docs/installer.py Normal file
View File

@@ -0,0 +1,241 @@
#!/usr/bin/env python
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
from __future__ import (
absolute_import, division, print_function, unicode_literals
)
import atexit
import json
import os
import platform
import re
import shlex
import shutil
import subprocess
import sys
import tempfile
py3 = sys.version_info[0] > 2
is64bit = platform.architecture()[0] == '64bit'
is_macos = 'darwin' in sys.platform.lower()
try:
__file__
from_file = True
except NameError:
from_file = False
if py3:
unicode = str
raw_input = input
import urllib.request as urllib
def encode_for_subprocess(x):
return x
else:
from future_builtins import map
import urllib2 as urllib
def encode_for_subprocess(x):
if isinstance(x, unicode):
x = x.encode('utf-8')
return x
def run(*args):
if len(args) == 1:
args = shlex.split(args[0])
args = list(map(encode_for_subprocess, args))
ret = subprocess.Popen(args).wait()
if ret != 0:
raise SystemExit(ret)
class Reporter: # {{{
def __init__(self, fname):
self.fname = fname
self.last_percent = 0
def __call__(self, blocks, block_size, total_size):
percent = (blocks*block_size)/float(total_size)
report = '\rDownloaded {:.1%} '.format(percent)
if percent - self.last_percent > 0.05:
self.last_percent = percent
print(report, end='')
sys.stdout.flush()
# }}}
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')
data = json.loads(res)
html_url = data['html_url'].replace('/tag/', '/download/').rstrip('/')
for asset in data.get('assets', ()):
name = asset['name']
if is_macos:
if name.endswith('.dmg'):
return html_url + '/' + name, asset['size']
else:
if name.endswith('.txz'):
if is64bit:
if name.endswith('-x86_64.txz'):
return html_url + '/' + name, asset['size']
else:
if name.endswith('-i686.txz'):
return html_url + '/' + name, asset['size']
raise SystemExit('Failed to find the installer package on github')
def do_download(url, size, dest):
print('Will download and install', os.path.basename(dest))
reporter = Reporter(os.path.basename(dest))
# Get content length and check if range is supported
rq = urllib.urlopen(url)
headers = rq.info()
sent_size = int(headers['content-length'])
if sent_size != size:
raise SystemExit('Failed to download from {} Content-Length ({}) != {}'.format(url, sent_size, size))
with open(dest, 'wb') as f:
while f.tell() < size:
raw = rq.read(8192)
if not raw:
break
f.write(raw)
reporter(f.tell(), 1, size)
rq.close()
if os.path.getsize(dest) < size:
raise SystemExit('Download failed, try again later')
print('\rDownloaded {} bytes'.format(os.path.getsize(dest)))
def clean_cache(cache, fname):
for x in os.listdir(cache):
if fname not in x:
os.remove(os.path.join(cache, x))
def download_installer(url, size):
fname = url.rpartition('/')[-1]
tdir = tempfile.gettempdir()
cache = os.path.join(tdir, 'kitty-installer-cache')
if not os.path.exists(cache):
os.makedirs(cache)
clean_cache(cache, fname)
dest = os.path.join(cache, fname)
if os.path.exists(dest) and os.path.getsize(dest) == size:
print('Using previously downloaded', fname)
return dest
if os.path.exists(dest):
os.remove(dest)
do_download(url, size, dest)
return dest
def macos_install(dmg, dest='/Applications', launch=True):
mp = tempfile.mkdtemp()
atexit.register(shutil.rmtree, mp)
run('hdiutil', 'attach', dmg, '-mountpoint', mp)
try:
os.chdir(mp)
app = 'kitty.app'
d = os.path.join(dest, app)
if os.path.exists(d):
shutil.rmtree(d)
dest = os.path.join(dest, app)
run('ditto', '-v', app, dest)
print('Successfully installed kitty into', dest)
if launch:
run('open', dest)
finally:
os.chdir('/')
run('hdiutil', 'detach', mp)
def linux_install(installer, dest=os.path.expanduser('~/.local'), launch=True):
dest = os.path.join(dest, 'kitty.app')
if os.path.exists(dest):
shutil.rmtree(dest)
os.makedirs(dest)
print('Extracting tarball...')
run('tar', '-C', dest, '-xJof', installer)
print('kitty successfully installed to', dest)
kitty = os.path.join(dest, 'bin', 'kitty')
print('Use', kitty, 'to run kitty')
if launch:
run(kitty, '--detach')
def main(dest=None, launch=True, installer=None):
if not dest:
if is_macos:
dest = '/Applications'
else:
dest = os.path.expanduser('~/.local')
machine = os.uname()[4]
if machine and machine.lower().startswith('arm'):
raise SystemExit(
'You are running on an ARM system. The kitty binaries are only'
' available for x86 systems. You will have to build from'
' source.')
if not installer:
url, size = get_latest_release_data()
installer = download_installer(url, size)
else:
installer = os.path.abspath(installer)
if not os.access(installer, os.R_OK):
raise SystemExit('Could not read from: {}'.format(installer))
if is_macos:
macos_install(installer, dest=dest, launch=launch)
else:
linux_install(installer, dest=dest, launch=launch)
def script_launch():
# To test: python3 -c "import runpy; runpy.run_path('installer.py', run_name='script_launch')"
def path(x):
return os.path.expandvars(os.path.expanduser(x))
def to_bool(x):
return x.lower() in {'y', 'yes', '1', 'true'}
type_map = {x: path for x in 'dest installer'.split()}
type_map['launch'] = to_bool
kwargs = {}
for arg in sys.argv[1:]:
if arg:
m = re.match('([a-z_]+)=(.+)', arg)
if m is None:
raise SystemExit('Unrecognized command line argument: ' + arg)
k = m.group(1)
if k not in type_map:
raise SystemExit('Unrecognized command line argument: ' + arg)
kwargs[k] = type_map[k](m.group(2))
main(**kwargs)
def update_intaller_wrapper():
# To run: python3 -c "import runpy; runpy.run_path('installer.py', run_name='update_wrapper')" installer.sh
src = open(__file__, 'rb').read().decode('utf-8')
wrapper = sys.argv[-1]
with open(wrapper, 'r+b') as f:
raw = f.read().decode('utf-8')
nraw = re.sub(r'^# HEREDOC_START.+^# HEREDOC_END', lambda m: '# HEREDOC_START\n{}\n# HEREDOC_END'.format(src), raw, flags=re.MULTILINE | re.DOTALL)
if 'update_intaller_wrapper()' not in nraw:
raise SystemExit('regex substitute of HEREDOC failed')
f.seek(0), f.truncate()
f.write(nraw.encode('utf-8'))
if __name__ == '__main__' and from_file:
main()
elif __name__ == 'update_wrapper':
update_intaller_wrapper()
elif __name__ == 'script_launch':
script_launch()

30
docs/installer.sh Normal file
View File

@@ -0,0 +1,30 @@
#!/bin/sh
#
# installer.sh
# Copyright (C) 2018 Kovid Goyal <kovid at kovidgoyal.net>
#
# Distributed under terms of the GPLv3 license.
#
python=$(command -v python3)
if [ -z "$python" ]; then
python=$(command -v python2)
fi
if [ -z "$python" ]; then
python=$(command -v python2.7)
fi
if [ -z "$python" ]; then
python=$(command -v python)
fi
if [ -z "$python" ]; then
python=python
fi
echo Using python executable: $python
$python -c "import sys; script_launch=lambda:sys.exit('Download of installer failed!'); exec(sys.stdin.read()); script_launch()" "$@" <<'INSTALLER_HEREDOC'
# {{{
# HEREDOC_START
# HEREDOC_END
# }}}
INSTALLER_HEREDOC

6
docs/invocation.rst Normal file
View File

@@ -0,0 +1,6 @@
The kitty command line interface
====================================
.. program:: kitty
.. include:: generated/cli-kitty.rst

128
docs/key-encoding.rst Normal file
View File

@@ -0,0 +1,128 @@
Key encoding for extended keyboard protocol
===============================================
See :ref:`extended-key-protocol` for more information and `this table in JSON
format <https://github.com/kovidgoyal/kitty/blob/master/key_encoding.json>`_.
===================== ======================
Name Encoded representation
0 ``G``
1 ``H``
2 ``I``
3 ``J``
4 ``K``
5 ``L``
6 ``M``
7 ``N``
8 ``O``
9 ``P``
A ``S``
APOSTROPHE ``B``
B ``T``
BACKSLASH ``t``
BACKSPACE ``1``
C ``U``
CAPS LOCK ``:``
COMMA ``C``
D ``V``
DELETE ``3``
DOWN ``6``
E ``W``
END ``-``
ENTER ``z``
EQUAL ``R``
ESCAPE ``y``
F ``X``
F1 ``/``
F10 ``]``
F11 ``{``
F12 ``}``
F13 ``@``
F14 ``%``
F15 ``$``
F16 ``#``
F17 ``BA``
F18 ``BB``
F19 ``BC``
F2 ``*``
F20 ``BD``
F21 ``BE``
F22 ``BF``
F23 ``BG``
F24 ``BH``
F25 ``BI``
F3 ``?``
F4 ``&``
F5 ``<``
F6 ``>``
F7 ``(``
F8 ``)``
F9 ``[``
G ``Y``
GRAVE ACCENT ``v``
H ``Z``
HOME ``.``
I ``a``
INSERT ``2``
J ``b``
K ``c``
KP 0 ``BJ``
KP 1 ``BK``
KP 2 ``BL``
KP 3 ``BM``
KP 4 ``BN``
KP 5 ``BO``
KP 6 ``BP``
KP 7 ``BQ``
KP 8 ``BR``
KP 9 ``BS``
KP ADD ``BX``
KP DECIMAL ``BT``
KP DIVIDE ``BU``
KP ENTER ``BY``
KP EQUAL ``BZ``
KP MULTIPLY ``BV``
KP SUBTRACT ``BW``
L ``d``
LEFT ``5``
LEFT ALT ``Bc``
LEFT BRACKET ``s``
LEFT CONTROL ``Bb``
LEFT SHIFT ``Ba``
LEFT SUPER ``Bd``
M ``e``
MINUS ``D``
N ``f``
NUM LOCK ``=``
O ``g``
P ``h``
PAGE DOWN ``9``
PAGE UP ``8``
PAUSE ``!``
PERIOD ``E``
PRINT SCREEN ``^``
Q ``i``
R ``j``
RIGHT ``4``
RIGHT ALT ``Bg``
RIGHT BRACKET ``u``
RIGHT CONTROL ``Bf``
RIGHT SHIFT ``Be``
RIGHT SUPER ``Bh``
S ``k``
SCROLL LOCK ``+``
SEMICOLON ``Q``
SLASH ``F``
SPACE ``A``
T ``l``
TAB ``0``
U ``m``
UP ``7``
V ``n``
W ``o``
WORLD 1 ``w``
WORLD 2 ``x``
X ``p``
Y ``q``
Z ``r``
===================== ======================

View File

@@ -0,0 +1,27 @@
clipboard - copy/paste to the system clipboard
==================================================
.. highlight:: sh
The ``clipboard`` kitten can be used to read or write to the system clipboard
from the shell. It even works over SSH. Using it is as simple as::
echo hooray | kitty +kitten clipboard
All text received on :file:`stdin` is copied to the clipboard.
To get text from the clipboard you have to enable reading of the clipboard
in :opt:`clipboard_control` in :file:`kitty.conf`. Once you do that, you can
use::
kitty +kitten clipboard --get-clipboard
.. program:: kitty +kitten clipboard
Command Line Interface
--------------------------
.. include:: /generated/cli-kitten-clipboard.rst

146
docs/kittens/custom.rst Normal file
View File

@@ -0,0 +1,146 @@
Custom kittens
=================
You can easily create your own kittens to extend kitty. They are just
terminal programs written in Python. When launching a kitten, kitty will
open an overlay window over the current window and optionally pass the
contents of the current window/scrollback to the kitten over its :file:`STDIN`.
The kitten can then perform whatever actions it likes, just as a normal
terminal program. After execution of the kitten is complete, it has access
to the running kitty instance so it can perform arbitrary actions
such as closing windows, pasting text, etc.
Let's see a simple example of creating a kitten. It will ask the user for some
input and paste it into the terminal window.
Create a file in the kitty config folder, :file:`~/.config/kitty/mykitten.py`
(you might need to adjust the path to wherever the kitty config folder is on
your machine).
.. code-block:: python
def main(args):
# this is the main entry point of the kitten, it will be executed in
# the overlay window when the kitten is launched
answer = input('Enter some text: ')
# whatever this function returns will be available in the
# handle_result() function
return answer
def handle_result(args, answer, target_window_id, boss):
# get the kitty window into which to paste answer
w = boss.window_id_map.get(target_window_id)
if w is not None:
w.paste(answer)
Now in :file:`kitty.conf` add the lines::
map ctrl+k kitten mykitten.py
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
------------------------------
You can pass arguments to kittens by defining them in the map directive in
:file:`kitty.conf`. For example::
map ctrl+k kitten mykitten.py arg1 arg2
These will be available as the ``args`` parameter in the ``main()`` and
``handle_result()`` functions. Note also that the current working directory
of the kitten is set to the working directory of whatever program is
running in the active kitty window.
Passing the contents of the screen to the kitten
---------------------------------------------------
If you would like your kitten to have access to the contents of the screen
and/or the scrollback buffer, you just need to add an annotation to the ``handle_result()``
function, telling kitty what kind of input your kitten would like. For example:
.. code-block:: py
# 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'
This will send the plain text of the active window to the kitten's
:file:`STDIN`. For text with formatting escape codes, use ``ansi``
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.

157
docs/kittens/diff.rst Normal file
View File

@@ -0,0 +1,157 @@
kitty-diff - A fast side-by-side diff tool with syntax highlighting and images
================================================================================
.. highlight:: sh
Major Features
-----------------
.. container:: major-features
* Displays diffs side-by-side in the kitty terminal
* Does syntax highlighting of the displayed diffs, asynchronously, for maximum
speed
* Displays images as well as text diffs, even over SSH
* Does recursive directory diffing
.. figure:: ../screenshots/diff.png
:alt: Screenshot, showing a sample diff
:align: center
:scale: 100%
Screenshot, showing a sample diff
.. contents::
Installation
---------------
Simply :ref:`install kitty <quickstart>`. You also need
to have either the `git <https://git-scm.com/>`_ program or the ``diff`` program
installed. Additionally, for syntax highlighting to work,
`pygments <http://pygments.org/>`_ must be installed (note that pygments is
included in the macOS kitty app).
Usage
--------
In the kitty terminal, run::
kitty +kitten diff file1 file2
to see the diff between file1 and file2.
Create an alias in your shell's startup file to shorten the command, for example:
.. code-block:: sh
alias d="kitty +kitten diff"
Now all you need to do to diff two files is::
d file1 file2
You can also pass directories instead of files to see the recursive diff of the
directory contents.
Keyboard controls
----------------------
========================= ===========================
Action Shortcut
========================= ===========================
Quit :kbd:`q, Ctrl+c, Esc`
Scroll line up :kbd:`k, up`
Scroll line down :kbd:`j, down`
Scroll page up :kbd:`PgUp`
Scroll page down :kbd:`PgDn`
Scroll to top :kbd:`Home`
Scroll to bottom :kbd:`End`
Scroll to next page :kbd:`Space, PgDn`
Scroll to previous page :kbd:`PgUp`
Scroll to next change :kbd:`n`
Scroll to previous change :kbd:`p`
Increase lines of context :kbd:`+`
Decrease lines of context :kbd:`-`
All lines of context :kbd:`a`
Restore default context :kbd:`=`
Search forwards :kbd:`/`
Search backwards :kbd:`?`
Clear search :kbd:`Esc`
Scroll to next match :kbd:`>, .`
Scroll to previous match :kbd:`<, ,`
========================= ===========================
Integrating with git
-----------------------
Add the following to `~/.gitconfig`:
.. code-block:: ini
[diff]
tool = kitty
guitool = kitty.gui
[difftool]
prompt = false
trustExitCode = true
[difftool "kitty"]
cmd = kitty +kitten diff $LOCAL $REMOTE
[difftool "kitty.gui"]
cmd = kitty kitty +kitten diff $LOCAL $REMOTE
Now to use kitty-diff to view git diffs, you can simply do::
git difftool --no-symlinks --dir-diff
Once again, creating an alias for this command is useful.
Why does this work only in kitty?
----------------------------------------
The diff kitten makes use of various features that are :doc:`kitty only
</protocol-extensions>`, such as the :doc:`kitty graphics protocol
</graphics-protocol>`, the :ref:`extended keyboard protocol
<extended-key-protocol>`, etc. It also leverages terminal program
infrastructure I created for all of kitty's other kittens to reduce the amount
of code needed (the entire implementation is under 2000 lines of code).
And fundamentally, it's kitty only because I wrote it for myself, and I am
highly unlikely to use any other terminals :)
Configuration
------------------------
You can configure the colors used, keyboard shortcuts, the diff implementation,
the default lines of context, etc. by creating a :file:`diff.conf` file in
your :ref:`kitty config folder <confloc>`. See below for the supported
configuration directives.
.. include:: /generated/conf-kitten-diff.rst
Command Line Interface
-------------------------
.. include:: /generated/cli-kitten-diff.rst
Sample diff.conf
-----------------
You can download a sample :file:`diff.conf` file with all default settings and
comments describing each setting by clicking: :download:`sample diff.conf
</generated/conf/diff.conf>`.

29
docs/kittens/hints.rst Normal file
View File

@@ -0,0 +1,29 @@
Hints
==========
|kitty| has a *hints mode* to select and act on arbitrary text snippets currently
visible on the screen. For example, you can press :sc:`open_url`
to choose any URL visible on the screen and then open it using your system
browser.
.. figure:: ../screenshots/hints_mode.png
:alt: URL hints mode
:align: center
:scale: 100%
URL hints mode
Similarly, you can press :sc:`insert_selected_path` to
select anything that looks like a path or filename and then insert it into the
terminal, very useful for picking files from the output of a ``git`` or ``ls`` command and
adding them to the command line for the next command.
The hints kitten is very powerful to see more detailed help on its various
options and modes of operation, see below. You can use these options to
create mappings in :file:`kitty.conf` to select various different text
snippets. See :sc:`insert_selected_path` for examples.
Command Line Interface
-------------------------
.. include:: ../generated/cli-kitten-hints.rst

35
docs/kittens/icat.rst Normal file
View File

@@ -0,0 +1,35 @@
icat - Display images in the terminal
========================================
The ``icat`` kitten can be used to display arbitrary images in the |kitty|
terminal. Using it is as simple as::
kitty +kitten icat image.jpeg
It supports all image types supported by `ImageMagick
<https://www.imagemagick.org>`_. It even works over SSH. For details, see
the :doc:`kitty graphics protocol </graphics-protocol>`.
You might want to create an alias in your shell's configuration files::
alias icat="kitty +kitten icat"
Then you can simply use ``icat image.png`` to view images.
.. note::
`ImageMagick <https://www.imagemagick.org>`_ must be installed for ``icat`` to
work.
.. program:: kitty +kitten icat
The ``icat`` kitten has various command line arguments to allow it to be used
from inside other programs to display images. In particular, :option:`--place`,
:option:`--detect-support` and :option:`--print-window-size`.
Command Line Interface
--------------------------
.. include:: /generated/cli-kitten-icat.rst

43
docs/kittens/panel.rst Normal file
View File

@@ -0,0 +1,43 @@
Draw a GPU accelerated dock panel on your desktop
====================================================================================================
.. highlight:: sh
You can use this kitten to draw a GPU accelerated panel on the edge
of your screen, that shows the output from an arbitrary terminal program.
It is useful for showing status information or notifications on your desktop
using terminal programs instead of GUI toolkits.
.. figure:: ../screenshots/panel.png
:alt: Screenshot, showing a sample panel
:align: center
:scale: 100%
Screenshot, showing a sample panel
The screenshot above shows a sample panel that displays the current desktop and
window title as well as miscellaneous system information such as network
activity, CPU load, date/time, etc.
.. note::
This kitten currently only works on X11 desktops
Using this kitten is simple, for example::
kitty +kitten panel sh -c 'printf "\n\n\nHello, world."; sleep 5s'
This will show ``Hello, world.`` at the top edge of your screen for five
seconds. Here the terminal program we are running is ``sh`` with a script to
print out ``Hello, world!``. You can make the terminal program as complex as
you like, as demonstrated in the screenshot above.
Command Line Interface
-------------------------
.. include:: ../generated/cli-kitten-panel.rst

View File

@@ -0,0 +1,22 @@
Unicode input
================
You can input unicode characters by name, hex code, recently used and even an editable favorites list.
Press :sc:`input_unicode_character` to start the unicode input widget, shown below.
.. figure:: ../screenshots/unicode.png
:alt: A screenshot of the unicode input widget
:align: center
:scale: 100%
A screenshot of the unicode input widget
In :guilabel:`Code` mode, you enter a unicode character by typing in the hex code for the
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.
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
a leading period and the index for the match if you don't like to use arrow
keys.

59
docs/performance.rst Normal file
View File

@@ -0,0 +1,59 @@
|kitty| Performance
===================
The main goals for |kitty| performance are user perceived latency while typing
and "smoothness" while scrolling as well as CPU usage. |kitty| tries hard to find
an optimum balance for these. To that end it keeps a cache of each rendered
glyph in video RAM so that font rendering is not a bottleneck. Interaction
with child programs takes place in a separate thread from rendering, to improve
smoothness.
There are two parameters you can tune to adjust the performance. :opt:`repaint_delay`
and :opt:`input_delay`. These control the artificial delays introduced into the
render loop to reduce CPU usage. See :ref:`conf-kitty-performance` for details.
See also the :opt:`sync_to_monitor` option to further decrease latency at the cost
of some `tearing <https://en.wikipedia.org/wiki/Screen_tearing>`_ while scrolling.
You can generate detailed per-function performance data using
`gperftools <https://github.com/gperftools/gperftools>`_. Build |kitty| with
`make profile` which will create an executable called `kitty-profile`. Run
that and perform the task you want to analyse, for example, scrolling a large
file with `less`. After you quit, function call statistics will be printed to
`stdout` and you can use tools like *kcachegrind* for more detailed analysis.
Here are some CPU usage numbers for the task of scrolling a file continuously
in less. The CPU usage is for the terminal process and X together and is
measured using htop. The measurements are taken at the same font and window
size for all terminals on a ``Intel(R) Core(TM) i7-4820K CPU @ 3.70GHz`` CPU
with a ``Advanced Micro Devices, Inc. [AMD/ATI] Cape Verde XT [Radeon HD
7770/8760 / R7 250X]`` GPU.
============== =========================
Terminal CPU usage (X + terminal)
============== =========================
|kitty| 6 - 8%
xterm 5 - 7% (but scrolling was extremely janky)
termite 10 - 13%
urxvt 12 - 14%
gnome-terminal 15 - 17%
konsole 29 - 31%
============== =========================
As you can see, |kitty| uses much less CPU than all terminals, except xterm, but
its scrolling "smoothness" is much better than that of xterm (at least to my,
admittedly biased, eyes).
.. _perf-cat:
.. note::
Some people have asked why kitty does not perform better than terminal XXX in
the test of sinking large amounts of data, such as catting a large text
file. The answer is because this is not a goal for kitty. kitty
deliberately throttles input parsing and output rendering to minimize
resource usage while still being able to sink output faster than any real
world program can produce it. Reducing CPU usage, and hence battery drain
while achieving instant response times and smooth scrolling to a human eye
is a far more important goal.

88
docs/pipe.rst Normal file
View File

@@ -0,0 +1,88 @@
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
``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

@@ -0,0 +1,210 @@
Extensions to the xterm protocol
===================================
|kitty| has a few extensions to the xterm protocol, to enable advanced features.
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 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
received as a simple byte stream. Another objective is to only move the minimum
possible amount of extra functionality into the terminal program itself. This
is to make it as easy to implement these protocol extensions as possible,
thereby hopefully encouraging their widespread adoption.
If you wish to discuss these extensions, propose additions/changes to them
please do so by opening issues in the github bug tracker.
.. contents::
Colored and styled underlines
-------------------------------
|kitty| supports colored and styled (wavy) underlines. This is of particular
use in terminal editors such as vim and emacs to display red, wavy underlines
under mis-spelled words and/or syntax errors. This is done by re-purposing some
SGR escape codes that are not used in modern terminals (`CSI codes
<https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences>`_)
To set the underline style::
<ESC>[4:0m # this is no underline
<ESC>[4:1m # this is a straight underline
<ESC>[4:2m # this is a double underline
<ESC>[4:3m # this is a curly underline
<ESC>[4:4m # this is a dotted underline (not implemented in kitty)
<ESC>[4:5m # this is a dashed underline (not implemented in kitty)
<ESC>[4m # this is a straight underline (for backwards compat)
<ESC>[24m # this is no underline (for backwards compat)
To set the underline color (this is reserved and as far as I can tell not actually used for anything)::
<ESC>[58...m
This works exactly like the codes ``38, 48`` that are used to set foreground and
background color respectively.
To reset the underline color (also previously reserved and unused)::
<ESC>[59m
To detect support for this feature in a terminal emulator, query the terminfo database
for the ``Su`` boolean capability.
Graphics rendering
---------------------
See :doc:`/graphics-protocol` for a description
of this protocol to enable drawing of arbitrary raster images in the terminal.
.. _extended-key-protocol:
Keyboard handling
-------------------
There are various problems with the current state of keyboard handling. They
include:
* No way to use modifiers other than ``Ctrl`` and ``Alt``
* No way to reliably use multiple modifier keys, other than, ``Shift+Alt``.
* No way to handle different types of keyboard events, such as press, release or repeat
* No reliable way to distinguish single ``Esc`` keypresses from the start of a
escape sequence. Currently, client programs use fragile timing related hacks
for this, leading to bugs, for example:
`neovim #2035 <https://github.com/neovim/neovim/issues/2035>`_.
There are already two distinct keyboard handling modes, *normal mode* and
*application mode*. These modes generate different escape sequences for the
various special keys (arrow keys, function keys, home/end etc.) Most terminals
start out in normal mode, however, most shell programs like ``bash`` switch them to
application mode. We propose adding a third mode, named *full mode* that addresses
the shortcomings listed above.
Switching to the new *full mode* is accomplished using the standard private
mode DECSET escape sequence::
<ESC>[?2017h
and to leave *full mode*, use DECRST::
<ESC>[?2017l
The number ``2017`` above is not used for any existing modes, as far as I know.
Client programs can query if the terminal emulator is in *full mode* by using
the standard `DECRQM <https://vt100.net/docs/vt510-rm/DECRQM.html>`_ escape sequence.
The new mode works as follows:
* All printable key presses without modifier keys are sent just as in the
*normal mode*. This means all printable ASCII characters and in addition,
``Enter``, ``Space`` and ``Backspace``. Also any unicode characters generated by
platform specific extended input modes, such as using the ``AltGr`` key. This
is done so that client programs that are not aware of this mode can still
handle basic text entry, so if a *full mode* using program crashes and does
not reset, the user can still issue a ``reset`` command in the shell to restore
normal key handling. Note that this includes pressing the ``Shift`` modifier
and printable keys. Note that this means there are no repeat and release
events for these keys and also for the left and right shift keys.
* For non printable keys and key combinations including one or more modifiers,
an escape sequence encoding the key event is sent. For details on the
escape sequence, see below.
The escape sequence encodes the following properties:
* Type of event: ``press,repeat,release``
* Modifiers pressed at the time of the event
* The actual key being pressed
Schematically::
<ESC>_K<type><modifiers><key><ESC>\
Where ``<type>`` is one of ``p`` -- press, ``r`` -- release and ``t`` -- repeat.
Modifiers is a bitmask represented as a single base64 digit. Shift -- ``0x1``,
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>`.
For example::
<ESC>_KpGp<ESC>\ is <Ctrl>+<Alt>+x (press)
<ESC>_KrP8<ESC>\ is <Ctrl>+<Alt>+<Shift>+<Super>+PageUp (release)
This encoding means each key event is represented by 8 or 9 printable ascii
only bytes, for maximum robustness.
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:
Setting text styles/colors in arbitrary regions of the screen
------------------------------------------------------------------
There already exists an escape code to set *some* text attributes in arbitrary
regions of the screen, `DECCARA
<https://vt100.net/docs/vt510-rm/DECCARA.html>`_. However, it is limited to
only a few attributes. |kitty| extends this to work with *all* SGR attributes.
So, for example, this can be used to set the background color in an arbitrary
region of the screen.
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>`_
for a summary of problems with *bce*.
For example, to set the background color to blue in a
rectangular region of the screen from (3, 4) to (10, 11), you use::
<ESC>[2*x<ESC>[4;3;11;10;44$r<ESC>[*x
Saving and restoring the default foreground/background/selection/cursor colors
---------------------------------------------------------------------------------
It is often useful for a full screen application with its own color themes
to set the default foreground, background, selection and cursor colors. This
allows for various performance optimizations when drawing the screen. The
problem is that if the user previously used the escape codes to change these
colors herself, then running the full screen application will lose her
changes even after it exits. To avoid this, kitty introduces a new pair of
*OSC* escape codes to push and pop the current color values from a stack::
<ESC>]30001<ESC>\ # push onto stack
<ESC>]30101<ESC>\ # pop from stack
These escape codes save/restore the so called *dynamic colors*, default
background, default foreground, selection background, selection foreground and
cursor color.
Pasting to clipboard
----------------------
|kitty| implements the OSC 52 escape code protocol to get/set the clipboard
contents (controlled via the :opt:`clipboard_control` setting). There is one
difference in kitty's implementation compared to some other terminal emulators.
|kitty| allows sending arbitrary amounts of text to the clipboard. It does so
by modifying the protocol slightly. Successive OSC 52 escape codes to set the
clipboard will concatenate, so::
<ESC>]52;c;<payload1><ESC>\
<ESC>]52;c;<payload2><ESC>\
will result in the clipboard having the contents ``payload1 + payload2``. To
send a new string to the clipboard send an OSC 52 sequence with an invalid payload
first, for example::
<ESC>]52;c;!<ESC>\
Here ``!`` is not valid base64 encoded text, so it clears the clipboard.

138
docs/remote-control.rst Normal file
View File

@@ -0,0 +1,138 @@
:tocdepth: 2
Controlling kitty from scripts or the shell
==============================================
.. highlight:: sh
Tutorial
----------
|kitty| can be controlled from scripts or the shell prompt. You can open new
windows, send arbitrary text input to any window, name windows and tabs, etc.
Let's walk through a few examples of controlling |kitty|.
Start by running |kitty| as::
kitty -o allow_remote_control=yes -o enabled_layouts=tall
In order for control to work, :opt:`allow_remote_control` must be enabled in
:file:`kitty.conf`. Here we turn it on explicitly at the command line.
Now, in the new |kitty| window, enter the command::
kitty @ new-window --title Output --keep-focus cat
This will open a new window, running the ``cat`` program that will appear next
to the current window.
Let's send some text to this new window::
kitty @ send-text --match cmdline:cat Hello, World
This will make ``Hello, World`` show up in the window running the ``cat`` program.
The :option:`kitty @ send-text --match` option is very powerful, it allows selecting windows by their
titles, the command line of the program running in the window, the working
directory of the program running in the window, etc. See ``kitty @ send-text
--help`` for details.
More usefully, you can pipe the output of a command running in one window to
another window, for example::
ls | kitty @ send-text --match title:Output --stdin
This will show the output of ls in the output window instead of the current
window. You can use this technique to, for example, show the output of running
``make`` in your editor in a different window. The possibilities are endless.
You can even have things you type show up in a different window. Run::
kitty @ send-text --match title:Output --stdin
And type some text, it will show up in the output window, instead of the current
window. Type ``Ctrl+D`` when you are ready to stop.
Now, let's open a new tab::
kitty @ new-window --new-tab --tab-title "My Tab" --keep-focus bash
This will open a new tab running the bash shell with the title "My Tab".
We can change the title of the tab with::
kitty @ set-tab-title --match title:My New Title
Let's change the title of the current tab::
kitty @ set-tab-title Master Tab
Now lets switch to the newly opened tab::
kitty @ focus-tab --match title:New
Similarly, to focus the previously opened output window (which will also switch
back to the old tab, automatically)::
kitty @ focus-window --match title:Output
You can get a listing of available tabs and windows, by running::
kitty @ ls
This outputs a tree of data in JSON format. The top level of the tree is all
operating system kitty windows. Each OS window has an id and a list of tabs.
Each tab has its own id, a title and a list of windows. Each window has an id,
title, current working directory, process id (PID) and command-line of the
process running in the window. You can use this information with :option:`kitty @ focus-window --match`
to control individual windows.
As you can see, it is very easy to control |kitty| using the
``kitty @`` messaging system. This tutorial touches only the
surface of what is possible. See ``kitty @ --help`` for more details.
Note that in the example's above, ``kitty @`` messaging works only when run inside a |kitty| window,
not anywhere. But, within a |kitty| window it even works over SSH. If you want to control
|kitty| from programs/scripts not running inside a |kitty| window, you have to implement a couple of
extra steps. First start |kitty| as::
kitty -o allow_remote_control=yes --listen-on unix:/tmp/mykitty
The :option:`kitty --listen-on` option tells |kitty| to listen for control messages at the
specified path. See ``kitty --help`` for details. Now you can control this
instance of |kitty| using the :option:`kitty @ --to` command line argument to ``kitty @``. For example::
kitty @ --to unix:/tmp/mykitty ls
Note that if all you want to do is run a single |kitty| "daemon" and have subsequent
|kitty| invocations appear as new top-level windows, you can use the simpler :option:`kitty --single-instance`
option, see ``kitty --help`` for that.
The builtin kitty shell
--------------------------
You can explore the |kitty| command language more easily using the builtin |kitty|
shell. Run ``kitty @`` with no arguments and you will be dropped into the |kitty|
shell with completion for |kitty| command names and options.
You can even open the |kitty| shell inside a running |kitty| using a simple
keyboard shortcut (:sc:`kitty_shell` by default). This has the added
advantage that you don't need to use ``allow_remote_control`` to make it work.
Allowing only some windows to control kitty
----------------------------------------------
If you do not want to allow all programs running in |kitty| to control it, you can selectively
enable remote control for only some |kitty| windows. Simply create a shortcut
such as::
map ctrl+k new_window @ some_program
Then programs running in windows created with that shortcut can use ``kitty @``
to control kitty. Note that any program with the right level of permissions can
still write to the pipes of any other program on the same computer and
therefore can control |kitty|. It can, however, be useful to block programs
running on other computers (for example, over ssh) or as other users.
.. include:: generated/cli-kitty-at.rst

BIN
docs/screenshots/diff.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
docs/screenshots/panel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

69
docs/support.html Normal file
View File

@@ -0,0 +1,69 @@
<style>
.support-button {
border-radius: 6px;
box-shadow: rgb(255, 246, 175) 0px 1px 0px 0px;
display: inline-block;
cursor: pointer;
color: rgb(51, 51, 51);
font-size: inherit;
font-family: Arial;
font-weight: bold;
padding: 8px 24px;
text-decoration: none;
}
.support-button:hover {
transform: scale(1.5);
}
.support-button {
outline: 0;
}
.support-button:visited {
color: rgb(51, 51, 51);
outline: 0;
}
#support-buttons > div {
margin-top: 3ex;
text-align: center;
}
#paypal input[type=submit] {
background: linear-gradient(rgb(255, 236, 100) 5%, rgb(255, 171, 35) 100%) rgb(255, 236, 100);
border: 1px solid rgb(255, 171, 35);
}
#liberapay a {
background: linear-gradient(rgb(92, 184, 92) 5%, rgb(62, 142, 62) 100%) rgb(92, 184, 92);
border: 1px solid rgb(62, 142, 62);
color: rgb(51, 51, 51);
}
#patreon a {
background: linear-gradient(rgb(11, 100, 163) 5%, rgb(5, 45, 73) 100%) rgb(11, 100, 163);
border: 1px solid rgb(5, 45, 73);
color: #eee;
}
</style>
<div id="support-buttons">
<div id="patreon">
<a class="support-button" href="https://www.patreon.com/bePatron?u=917933">Patronage via Patreon</a>
</div>
<div>
<form id="paypal" action="https://www.paypal.com/cgi-bin/webscr" method="post" title="Contribute to support calibre development">
<input type="hidden" name="cmd" value="_s-xclick" />
<input type="hidden" name="hosted_button_id" value="FEELASHWEL5HS" />
<input class="support-button" type="submit" name="submit" value="One time support via PayPal" />
<img alt="" border="0" src="https://www.paypalobjects.com/en_GB/i/scr/pixel.gif" width="1" height="1" />
</form>
</div>
<div id="liberapay">
<a class="support-button" href="https://liberapay.com/kovidgoyal/donate">Patronage via Liberapay</a>
</div>
</div>

23
docs/support.rst Normal file
View File

@@ -0,0 +1,23 @@
Support kitty development
===========================
My goal with |kitty| is to move the stagnant terminal ecosystem forward. To that
end kitty has many foundational features, such as: :doc:`image support
<graphics-protocol>`, :doc:`superlative performance <performance>`,
:doc:`various enhancements to the terminal protocol <protocol-extensions>`,
etc. These features allow the development of rich terminal applications, such
as :doc:`Side-by-side diff <kittens/diff>` and :doc:`Unicode input
<kittens/unicode-input>`.
If you wish to support this mission and see the terminal ecosystem evolve,
consider donating so that I can devote more time to |kitty| development.
I have personally written `almost all kitty code
<https://github.com/kovidgoyal/kitty/graphs/contributors>`_.
You can choose to make either a one-time payment via PayPal or become a
*patron* of kitty development via the Patreon or Liberapay services
below:
.. raw:: html
:file: support.html

264
gen-apc-parsers.py Executable file
View File

@@ -0,0 +1,264 @@
#!/usr/bin/env python
# vim:fileencoding=utf-8
# License: GPLv3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
import subprocess
from collections import defaultdict
def resolve_keys(keymap):
ans = defaultdict(list)
for ch, (attr, atype) in keymap.items():
if atype not in ('int', 'uint'):
atype = 'flag'
ans[atype].append(ch)
return ans
def enum(keymap):
lines = []
for ch, (attr, atype) in keymap.items():
lines.append(f"{attr}='{ch}'")
return '''
enum KEYS {{
{}
}};
'''.format(',\n'.join(lines))
def parse_key(keymap):
lines = []
for attr, atype in keymap.values():
vs = atype.upper() if atype in ('uint', 'int') else 'FLAG'
lines.append(f'case {attr}: value_state = {vs}; break;')
return ' \n'.join(lines)
def parse_flag(keymap, type_map, command_class):
lines = []
for ch in type_map['flag']:
attr, allowed_values = keymap[ch]
q = ' && '.join(f"g.{attr} != '{x}'" for x in allowed_values)
lines.append(f'''
case {attr}: {{
g.{attr} = screen->parser_buf[pos++] & 0xff;
if ({q}) {{
REPORT_ERROR("Malformed {command_class} control block, unknown flag value for {attr}: 0x%x", g.{attr});
return;
}};
}}
break;
''')
return ' \n'.join(lines)
def parse_number(keymap):
int_keys = [f'I({attr})' for attr, atype in keymap.values() if atype == 'int']
uint_keys = [f'U({attr})' for attr, atype in keymap.values() if atype == 'uint']
return '; '.join(int_keys), '; '.join(uint_keys)
def cmd_for_report(report_name, keymap, type_map, payload_allowed):
def group(atype, conv):
flag_fmt, flag_attrs = [], []
cv = {'flag': 'c', 'int': 'i', 'uint': 'I'}[atype]
for ch in type_map[atype]:
flag_fmt.append('s' + cv)
attr = keymap[ch][0]
flag_attrs.append(f'"{attr}", {conv}g.{attr}')
return ' '.join(flag_fmt), ', '.join(flag_attrs)
flag_fmt, flag_attrs = group('flag', '')
int_fmt, int_attrs = group('int', '(int)')
uint_fmt, uint_attrs = group('uint', '(unsigned int)')
fmt = f'{flag_fmt} {uint_fmt} {int_fmt}'
if payload_allowed:
ans = [f'REPORT_VA_COMMAND("s {{{fmt} sI}} y#", "{report_name}",']
else:
ans = [f'REPORT_VA_COMMAND("s {{{fmt}}}", "{report_name}",']
ans.append(',\n '.join((flag_attrs, uint_attrs, int_attrs)))
if payload_allowed:
ans.append(', "payload_sz", g.payload_sz, payload, g.payload_sz')
ans.append(');')
return '\n'.join(ans)
def generate(function_name, callback_name, report_name, keymap, command_class, initial_key='a', payload_allowed=True):
type_map = resolve_keys(keymap)
keys_enum = enum(keymap)
handle_key = parse_key(keymap)
flag_keys = parse_flag(keymap, type_map, command_class)
int_keys, uint_keys = parse_number(keymap)
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'
parr = 'static uint8_t payload[4096];'
payload_case = f'''
case PAYLOAD: {{
sz = screen->parser_buf_pos - pos;
const char *err = base64_decode(screen->parser_buf + pos, sz, payload, sizeof(payload), &g.payload_sz);
if (err != NULL) {{ REPORT_ERROR("Failed to parse {command_class} command payload with error: %s", err); return; }}
pos = screen->parser_buf_pos;
}}
break;
'''
callback = f'{callback_name}(screen, &g, payload)'
else:
payload_after_value = payload = parr = payload_case = ''
callback = f'{callback_name}(screen, &g)'
return f'''
static inline void
{function_name}(Screen *screen, PyObject UNUSED *dump_callback) {{
unsigned int pos = 1;
enum PARSER_STATES {{ KEY, EQUAL, UINT, INT, FLAG, AFTER_VALUE {payload} }};
enum PARSER_STATES state = KEY, value_state = FLAG;
static {command_class} g;
unsigned int i, code;
uint64_t lcode;
bool is_negative;
memset(&g, 0, sizeof(g));
size_t sz;
{parr}
{keys_enum}
enum KEYS key = '{initial_key}';
while (pos < screen->parser_buf_pos) {{
switch(state) {{
case KEY:
key = screen->parser_buf[pos++];
state = EQUAL;
switch(key) {{
{handle_key}
default:
REPORT_ERROR("Malformed {command_class} control block, invalid key character: 0x%x", key);
return;
}}
break;
case EQUAL:
if (screen->parser_buf[pos++] != '=') {{
REPORT_ERROR("Malformed {command_class} control block, no = after key, found: 0x%x instead", screen->parser_buf[pos-1]);
return;
}}
state = value_state;
break;
case FLAG:
switch(key) {{
{flag_keys}
default:
break;
}}
state = AFTER_VALUE;
break;
case INT:
#define READ_UINT \\
for (i = pos; i < MIN(screen->parser_buf_pos, pos + 10); i++) {{ \\
if (screen->parser_buf[i] < '0' || screen->parser_buf[i] > '9') break; \\
}} \\
if (i == pos) {{ REPORT_ERROR("Malformed {command_class} control block, expecting an integer value for key: %c", key & 0xFF); return; }} \\
lcode = utoi(screen->parser_buf + pos, i - pos); pos = i; \\
if (lcode > UINT32_MAX) {{ REPORT_ERROR("Malformed {command_class} control block, number is too large"); return; }} \\
code = lcode;
is_negative = false;
if(screen->parser_buf[pos] == '-') {{ is_negative = true; pos++; }}
#define I(x) case x: g.x = is_negative ? 0 - (int32_t)code : (int32_t)code; break
READ_UINT;
switch(key) {{
{int_keys};
default: break;
}}
state = AFTER_VALUE;
break;
#undef I
case UINT:
READ_UINT;
#define U(x) case x: g.x = code; break
switch(key) {{
{uint_keys};
default: break;
}}
state = AFTER_VALUE;
break;
#undef U
#undef READ_UINT
case AFTER_VALUE:
switch (screen->parser_buf[pos++]) {{
default:
REPORT_ERROR("Malformed {command_class} control block, expecting a comma or semi-colon after a value, found: 0x%x",
screen->parser_buf[pos - 1]);
return;
case ',':
state = KEY;
break;
{payload_after_value}
}}
break;
{payload_case}
}} // end switch
}} // end while
switch(state) {{
case EQUAL:
REPORT_ERROR("Malformed {command_class} control block, no = after key"); return;
case INT:
case UINT:
REPORT_ERROR("Malformed {command_class} control block, expecting an integer value"); return;
case FLAG:
REPORT_ERROR("Malformed {command_class} control block, expecting a flag value"); return;
default:
break;
}}
{report_cmd}
{callback};
}}
'''
def write_header(text, path):
with open(path, 'w') as f:
print(f'// This file is generated by {__file__} do not edit!', file=f, end='\n\n')
print('#pragma once', file=f)
print(text, file=f)
subprocess.check_call(['clang-format', '-i', path])
def graphics_parser():
flag = frozenset
keymap = {
'a': ('action', flag('tTqpd')),
'd': ('delete_action', flag('aAiIcCpPqQxXyYzZ')),
't': ('transmission_type', flag('dfts')),
'o': ('compressed', flag('z')),
'f': ('format', 'uint'),
'm': ('more', 'uint'),
'i': ('id', 'uint'),
'w': ('width', 'uint'),
'h': ('height', 'uint'),
'x': ('x_offset', 'uint'),
'y': ('y_offset', 'uint'),
'v': ('data_height', 'uint'),
's': ('data_width', 'uint'),
'S': ('data_sz', 'uint'),
'O': ('data_offset', 'uint'),
'c': ('num_cells', 'uint'),
'r': ('num_lines', 'uint'),
'X': ('cell_x_offset', 'uint'),
'Y': ('cell_y_offset', 'uint'),
'z': ('z_index', 'int'),
}
text = generate('parse_graphics_code', 'screen_handle_graphics_command', 'graphics_command', keymap, 'GraphicsCommand')
write_header(text, 'kitty/parse-graphics-command.h')
graphics_parser()

440
gen-wcwidth.py Executable file
View File

@@ -0,0 +1,440 @@
#!/usr/bin/env python3
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
import os
import sys
from collections import defaultdict
from contextlib import contextmanager
from datetime import date
from functools import partial
from html.entities import html5
from itertools import groupby
from operator import itemgetter
from urllib.request import urlopen
os.chdir(os.path.dirname(os.path.abspath(__file__)))
non_characters = frozenset(range(0xfffe, 0x10ffff, 0x10000))
non_characters |= frozenset(range(0xffff, 0x10ffff + 1, 0x10000))
non_characters |= frozenset(range(0xfdd0, 0xfdf0))
if len(non_characters) != 66:
raise SystemExit('non_characters table incorrect')
emoji_skin_tone_modifiers = frozenset(range(0x1f3fb, 0x1F3FF + 1))
def get_data(fname, folder='UCD'):
url = f'https://www.unicode.org/Public/{folder}/latest/{fname}'
bn = os.path.basename(url)
local = os.path.join('/tmp', bn)
if os.path.exists(local):
data = open(local, 'rb').read()
else:
data = urlopen(url).read()
open(local, 'wb').write(data)
for line in data.decode('utf-8').splitlines():
line = line.strip()
if line and not line.startswith('#'):
yield line
# Map of class names to set of codepoints in class
class_maps = {}
name_map = {}
word_search_map = defaultdict(set)
zwj = 0x200d
marks = set(emoji_skin_tone_modifiers) | {zwj}
not_assigned = set(range(0, sys.maxunicode))
def parse_ucd():
def add_word(w, c):
if c <= 32 or c == 127 or 128 <= c <= 159:
return
if len(w) > 1:
word_search_map[w.lower()].add(c)
first = None
for word, c in html5.items():
if len(c) == 1:
add_word(word.rstrip(';'), ord(c))
word_search_map['nnbsp'].add(0x202f)
for line in get_data('ucd/UnicodeData.txt'):
parts = [x.strip() for x in line.split(';')]
codepoint = int(parts[0], 16)
name = parts[1] or parts[10]
if name == '<control>':
name = parts[10]
if name:
name_map[codepoint] = name
for word in name.lower().split():
add_word(word, codepoint)
category = parts[2]
s = class_maps.setdefault(category, set())
desc = parts[1]
codepoints = (codepoint,)
if first is None:
if desc.endswith(', First>'):
first = codepoint
continue
else:
codepoints = range(first, codepoint + 1)
first = None
for codepoint in codepoints:
s.add(codepoint)
not_assigned.discard(codepoint)
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)
spec, rest = spec.strip(), rest.strip().split(' ', 1)[0].strip()
if '..' in spec:
chars = tuple(map(lambda x: int(x, 16), filter(None, spec.split('.'))))
chars = set(range(chars[0], chars[1] + 1))
else:
chars = {int(spec, 16)}
return chars, rest
all_emoji = set()
emoji_categories = {}
emoji_presentation_bases = set()
def parse_emoji():
for line in get_data('emoji-data.txt', 'emoji'):
chars, rest = split_two(line)
s = emoji_categories.setdefault(rest, set())
s.update(chars)
all_emoji.update(chars)
for line in get_data('emoji-variation-sequences.txt', 'emoji'):
base, var, *rest = line.split()
if base.startswith('#'):
continue
base = int(base, 16)
if var.upper() == 'FE0F':
emoji_presentation_bases.add(base)
doublewidth, ambiguous = set(), set()
def parse_eaw():
global doublewidth, ambiguous
seen = set()
for line in get_data('ucd/EastAsianWidth.txt'):
chars, eaw = split_two(line)
if eaw == 'A':
ambiguous |= chars
seen |= chars
elif eaw == 'W' or eaw == 'F':
doublewidth |= chars
seen |= chars
doublewidth |= set(range(0x3400, 0x4DBF + 1)) - seen
doublewidth |= set(range(0x4E00, 0x9FFF + 1)) - seen
doublewidth |= set(range(0xF900, 0xFAFF + 1)) - seen
doublewidth |= set(range(0x20000, 0x2FFFD + 1)) - seen
doublewidth |= set(range(0x30000, 0x3FFFD + 1)) - seen
def get_ranges(items):
items.sort()
for k, g in groupby(enumerate(items), lambda m: m[0]-m[1]):
group = tuple(map(itemgetter(1), g))
a, b = group[0], group[-1]
if a == b:
yield a
else:
yield a, b
def write_case(spec, p):
if isinstance(spec, tuple):
p('\t\tcase 0x{:x} ... 0x{:x}:'.format(*spec))
else:
p('\t\tcase 0x{:x}:'.format(spec))
@contextmanager
def create_header(path, include_data_types=True):
f = open(path, 'w')
p = partial(print, file=f)
p('// unicode data, built from the unicode standard on:', date.today())
p('// see gen-wcwidth.py')
if path.endswith('.h'):
p('#pragma once')
if include_data_types:
p('#include "data-types.h"\n')
p('START_ALLOW_CASE_RANGE')
p()
yield p
p()
if include_data_types:
p('END_ALLOW_CASE_RANGE')
f.close()
def gen_emoji():
with create_header('kitty/emoji.h') as p:
p('static inline bool\nis_emoji(char_type code) {')
p('\tswitch(code) {')
for spec in get_ranges(list(all_emoji)):
write_case(spec, p)
p('\t\t\treturn true;')
p('\t\tdefault: return false;')
p('\t}')
p('\treturn false;\n}')
p('static inline bool\nis_emoji_modifier(char_type code) {')
p('\tswitch(code) {')
for spec in get_ranges(list(emoji_categories['Emoji_Modifier'])):
write_case(spec, p)
p('\t\t\treturn true;')
p('\t\tdefault: return false;')
p('\t}')
p('\treturn false;\n}')
def category_test(name, p, classes, comment, static=False, extra_chars=frozenset(), exclude=frozenset()):
static = 'static inline ' if static else ''
chars = set()
for c in classes:
chars |= class_maps[c]
chars |= extra_chars
chars -= exclude
p(f'{static}bool\n{name}(char_type code) {{')
p(f'\t// {comment} ({len(chars)} codepoints)' + ' {{' '{')
p('\tswitch(code) {')
for spec in get_ranges(list(chars)):
write_case(spec, p)
p(f'\t\t\treturn true;')
p('\t} // }}}\n')
p('\treturn false;\n}\n')
def codepoint_to_mark_map(p, mark_map):
p('\tswitch(c) { // {{{')
rmap = {c: m for m, c in enumerate(mark_map)}
for spec in get_ranges(mark_map):
if isinstance(spec, tuple):
s = rmap[spec[0]]
cases = ' '.join(f'case {i}:' for i in range(spec[0], spec[1]+1))
p(f'\t\t{cases} return {s} + c - {spec[0]};')
else:
p(f'\t\tcase {spec}: return {rmap[spec]};')
p('default: return 0;')
p('\t} // }}}')
return rmap
def classes_to_regex(classes, exclude=''):
chars = set()
for c in classes:
chars |= class_maps[c]
for c in map(ord, exclude):
chars.discard(c)
def as_string(codepoint):
if codepoint < 256:
return r'\x{:02x}'.format(codepoint)
if codepoint <= 0xffff:
return r'\u{:04x}'.format(codepoint)
return r'\U{:08x}'.format(codepoint)
for spec in get_ranges(list(chars)):
if isinstance(spec, tuple):
yield '{}-{}'.format(*map(as_string, (spec[0], spec[1])))
else:
yield as_string(spec)
def gen_ucd():
cz = {c for c in class_maps if c[0] in 'CZ'}
with create_header('kitty/unicode-data.c') as p:
p('#include "unicode-data.h"')
category_test(
'is_combining_char', p,
{c for c in class_maps if c.startswith('M')},
'M category (marks)',
# See https://github.com/harfbuzz/harfbuzz/issues/169
extra_chars=emoji_skin_tone_modifiers | {zwj}
)
category_test(
'is_ignored_char', p, 'Cc Cf Cs'.split(),
'Control characters and non-characters', extra_chars=non_characters, exclude={zwj})
category_test('is_word_char', p, {c for c in class_maps if c[0] in 'LN'}, 'L and N categories')
category_test('is_CZ_category', p, cz, 'C and Z categories')
category_test('is_P_category', p, {c for c in class_maps if c[0] == 'P'}, 'P category (punctuation)')
mark_map = [0] + list(sorted(marks))
p('char_type codepoint_for_mark(combining_type m) {')
p(f'\tstatic char_type map[{len(mark_map)}] =', '{', ', '.join(map(str, mark_map)), '}; // {{{ mapping }}}')
p('\tif (m < arraysz(map)) return map[m];')
p('\treturn 0;')
p('}\n')
p('combining_type mark_for_codepoint(char_type c) {')
rmap = codepoint_to_mark_map(p, mark_map)
p('}\n')
if rmap[0xfe0e] != 1281:
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]
))
with open('kittens/hints/url_regex.py', 'w') as f:
f.write("url_delimiters = '{}' # noqa".format(''.join(classes_to_regex(cz, exclude='\n'))))
def gen_names():
with create_header('kittens/unicode_input/names.h') as p:
mark_to_cp = list(sorted(name_map))
cp_to_mark = {cp: m for m, cp in enumerate(mark_to_cp)}
# Mapping of mark to codepoint name
p(f'static const char* name_map[{len(mark_to_cp)}] = {{' ' // {{{')
for cp in mark_to_cp:
w = name_map[cp].replace('"', '\\"')
p(f'\t"{w}",')
p("}; // }}}\n")
# Mapping of mark to codepoint
p(f'static const char_type mark_to_cp[{len(mark_to_cp)}] = {{' ' // {{{')
p(', '.join(map(str, mark_to_cp)))
p('}; // }}}\n')
# Function to get mark number for codepoint
p('static char_type mark_for_codepoint(char_type c) {')
codepoint_to_mark_map(p, mark_to_cp)
p('}\n')
p('static inline const char* name_for_codepoint(char_type cp) {')
p('\tchar_type m = mark_for_codepoint(cp); if (m == 0) return NULL;')
p('\treturn name_map[m];')
p('}\n')
# Array of all words
word_map = tuple(sorted(word_search_map))
word_rmap = {w: i for i, w in enumerate(word_map)}
p(f'static const char* all_words_map[{len(word_map)}] = {{' ' // {{{')
cwords = (w.replace('"', '\\"') for w in word_map)
p(', '.join(f'"{w}"' for w in cwords))
p('}; // }}}\n')
# Array of sets of marks for each word
word_to_marks = {word_rmap[w]: frozenset(map(cp_to_mark.__getitem__, cps)) for w, cps in word_search_map.items()}
all_mark_groups = frozenset(word_to_marks.values())
array = [0]
mg_to_offset = {}
for mg in all_mark_groups:
mg_to_offset[mg] = len(array)
array.append(len(mg))
array.extend(sorted(mg))
p(f'static const char_type mark_groups[{len(array)}] = {{' ' // {{{')
p(', '.join(map(str, array)))
p('}; // }}}\n')
offsets_array = []
for wi, w in enumerate(word_map):
mg = word_to_marks[wi]
offsets_array.append(mg_to_offset[mg])
p(f'static const char_type mark_to_offset[{len(offsets_array)}] = {{' ' // {{{')
p(', '.join(map(str, offsets_array)))
p('}; // }}}\n')
# The trie
p(f'typedef struct {{ uint32_t children_offset; uint32_t match_offset; }} word_trie;\n')
all_trie_nodes = []
class TrieNode:
def __init__(self):
self.match_offset = 0
self.children_offset = 0
self.children = {}
def add_letter(self, letter):
if letter not in self.children:
self.children[letter] = len(all_trie_nodes)
all_trie_nodes.append(TrieNode())
return self.children[letter]
def __str__(self):
return f'{{ .children_offset={self.children_offset}, .match_offset={self.match_offset} }}'
root = TrieNode()
all_trie_nodes.append(root)
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, word in enumerate(word_map):
add_word(i, word)
children_array = [0]
for node in all_trie_nodes:
if node.children:
node.children_offset = len(children_array)
children_array.append(len(node.children))
for letter, child_offset in node.children.items():
children_array.append((child_offset << 8) | (letter & 0xff))
p(f'static const word_trie all_trie_nodes[{len(all_trie_nodes)}] = {{' ' // {{{')
p(',\n'.join(map(str, all_trie_nodes)))
p('\n}; // }}}\n')
p(f'static const uint32_t children_array[{len(children_array)}] = {{' ' // {{{')
p(', '.join(map(str, children_array)))
p('}; // }}}\n')
def gen_wcwidth():
seen = set()
def add(p, comment, chars_, ret):
chars = chars_ - seen
seen.update(chars)
p(f'\t\t// {comment} ({len(chars)} codepoints)' + ' {{' '{')
for spec in get_ranges(list(chars)):
write_case(spec, p)
p(f'\t\t\treturn {ret};')
p('\t\t// }}}\n')
with create_header('kitty/wcwidth-std.h') as p:
p('static int\nwcwidth_std(int32_t code) {')
p('\tswitch(code) {')
non_printing = class_maps['Cc'] | class_maps['Cf'] | class_maps['Cs']
add(p, 'Marks', marks | {0}, 0)
add(p, 'Non-printing characters', non_printing, -1)
add(p, 'Private use', class_maps['Co'], -3)
add(p, 'Text Presentation', emoji_categories['Emoji'] - emoji_categories['Emoji_Presentation'], 1)
add(p, 'East Asian ambiguous width', ambiguous, -2)
add(p, 'East Asian double width', doublewidth, 2)
add(p, 'Emoji Presentation', emoji_categories['Emoji_Presentation'], 2)
add(p, 'Not assigned in the unicode character database', not_assigned, -4)
p('\t\tdefault: return 1;')
p('\t}')
p('\treturn 1;\n}')
p('static bool\nis_emoji_presentation_base(uint32_t code) {')
p('\tswitch(code) {')
for spec in get_ranges(list(emoji_presentation_bases)):
write_case(spec, p)
p('\t\t\treturn true;')
p('\t\tdefault: return false;')
p('\t}')
p('\treturn 1;\n}')
parse_ucd()
parse_emoji()
parse_eaw()
gen_ucd()
gen_wcwidth()
gen_emoji()
gen_names()

67
glad/generate.py Executable file
View File

@@ -0,0 +1,67 @@
#!/usr/bin/env python3
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
import os
import re
import shlex
import shutil
import subprocess
cmdline = (
'glad --profile core --out-path {dest} --api gl=3.3 --generator {generator} --spec gl'
' --extensions GL_ARB_texture_storage,GL_ARB_copy_image,GL_ARB_multisample,GL_ARB_robustness,GL_KHR_debug'
)
def clean(x):
if os.path.exists(x):
shutil.rmtree(x)
def regenerate():
clean('out')
subprocess.check_call(
shlex.split(cmdline.format(dest='out', generator='c-debug'))
)
def strip_trailing_whitespace(c):
return re.sub(r'\s+$', '', c, flags=re.MULTILINE) + '\n'
def export():
c = open('out/src/glad.c', 'rb').read().decode('utf-8')
functions = []
def sub(m):
functions.append(m.group(2))
return m.group()
c = re.sub(r'^([A-Z0-9]+) glad_debug_([a-zA-Z0-9]+) = glad_debug_impl_\2;$', sub, c, flags=re.M)
switch = ['glad_debug_{0} = glad_{0}'.format(f) for f in functions]
c = c.replace('<glad/glad.h>', '"gl-wrapper.h"', 1)
c = '#pragma GCC diagnostic ignored "-Wpedantic"\n' + c
c += '''
int
init_glad(GLADloadproc load, int debug) {
int ret = gladLoadGLLoader(load);
if (ret && !debug) {
SUB;
}
return ret;
}'''.replace('SUB', ';\n '.join(switch), 1)
open('../kitty/gl-wrapper.c', 'w').write(strip_trailing_whitespace(c))
raw = open('out/include/glad/glad.h').read()
raw = raw.replace('<KHR/khrplatform.h>', '"khrplatform.h"')
raw += '\nint init_glad(GLADloadproc, int);\n'
open('../kitty/gl-wrapper.h', 'w').write(strip_trailing_whitespace(raw))
raw = open('out/include/KHR/khrplatform.h', 'rb').read().decode('utf-8')
open('../kitty/khrplatform.h', 'w').write(strip_trailing_whitespace(raw))
if __name__ == '__main__':
os.chdir(os.path.dirname(os.path.abspath(__file__)))
regenerate()
export()

314
glfw/backend_utils.c vendored Normal file
View File

@@ -0,0 +1,314 @@
/*
* backend_utils.c
* Copyright (C) 2018 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#define _GNU_SOURCE
#include "backend_utils.h"
#include "internal.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <float.h>
#include <time.h>
#include <stdio.h>
#ifdef __NetBSD__
#define ppoll pollts
#endif
static inline double
monotonic() {
struct timespec ts = {0};
#ifdef CLOCK_HIGHRES
clock_gettime(CLOCK_HIGHRES, &ts);
#elif CLOCK_MONOTONIC_RAW
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
#else
clock_gettime(CLOCK_MONOTONIC, &ts);
#endif
return (((double)ts.tv_nsec) / 1e9) + (double)ts.tv_sec;
}
void
update_fds(EventLoopData *eld) {
for (nfds_t i = 0; i < eld->watches_count; i++) {
Watch *w = eld->watches + i;
eld->fds[i].fd = w->fd;
eld->fds[i].events = w->enabled ? w->events : 0;
}
}
static id_type watch_counter = 0;
id_type
addWatch(EventLoopData *eld, const char* name, int fd, int events, int enabled, watch_callback_func cb, void *cb_data) {
if (eld->watches_count >= sizeof(eld->watches)/sizeof(eld->watches[0])) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Too many watches added");
return 0;
}
Watch *w = eld->watches + eld->watches_count++;
w->name = name;
w->fd = fd; w->events = events; w->enabled = enabled;
w->callback = cb;
w->callback_data = cb_data;
w->id = ++watch_counter;
update_fds(eld);
return w->id;
}
#define removeX(which, item_id, update_func) {\
for (nfds_t i = 0; i < eld->which##_count; i++) { \
if (eld->which[i].id == item_id) { \
eld->which##_count--; \
if (i < eld->which##_count) { \
memmove(eld->which + i, eld->which + i + 1, sizeof(eld->which[0]) * (eld->which##_count - i)); \
} \
update_func(eld); break; \
}}}
void
removeWatch(EventLoopData *eld, id_type watch_id) {
removeX(watches, watch_id, update_fds);
}
void
toggleWatch(EventLoopData *eld, id_type watch_id, int enabled) {
for (nfds_t i = 0; i < eld->watches_count; i++) {
if (eld->watches[i].id == watch_id) {
if (eld->watches[i].enabled != enabled) {
eld->watches[i].enabled = enabled;
update_fds(eld);
}
break;
}
}
}
static id_type timer_counter = 0;
static int
compare_timers(const void *a_, const void *b_) {
const Timer *a = (const Timer*)a_, *b = (const Timer*)b_;
return (a->trigger_at > b->trigger_at) ? 1 : (a->trigger_at < b->trigger_at) ? -1 : 0;
}
static inline void
update_timers(EventLoopData *eld) {
if (eld->timers_count > 1) qsort(eld->timers, eld->timers_count, sizeof(eld->timers[0]), compare_timers);
}
id_type
addTimer(EventLoopData *eld, const char *name, double interval, int enabled, timer_callback_func cb, void *cb_data) {
if (eld->timers_count >= sizeof(eld->timers)/sizeof(eld->timers[0])) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Too many timers added");
return 0;
}
Timer *t = eld->timers + eld->timers_count++;
t->interval = interval;
t->name = name;
t->trigger_at = enabled ? monotonic() + interval : DBL_MAX;
t->callback = cb;
t->callback_data = cb_data;
t->id = ++timer_counter;
update_timers(eld);
return t->id;
}
void
removeTimer(EventLoopData *eld, id_type timer_id) {
removeX(timers, timer_id, update_timers);
}
void
toggleTimer(EventLoopData *eld, id_type timer_id, int enabled) {
for (nfds_t i = 0; i < eld->timers_count; i++) {
if (eld->timers[i].id == timer_id) {
double trigger_at = enabled ? (monotonic() + eld->timers[i].interval) : DBL_MAX;
if (trigger_at != eld->timers[i].trigger_at) {
eld->timers[i].trigger_at = trigger_at;
update_timers(eld);
}
break;
}
}
}
void
changeTimerInterval(EventLoopData *eld, id_type timer_id, double interval) {
for (nfds_t i = 0; i < eld->timers_count; i++) {
if (eld->timers[i].id == timer_id) {
eld->timers[i].interval = interval;
break;
}
}
}
double
prepareForPoll(EventLoopData *eld, double timeout) {
for (nfds_t i = 0; i < eld->watches_count; i++) eld->fds[i].revents = 0;
if (!eld->timers_count || eld->timers[0].trigger_at == DBL_MAX) return timeout;
double now = monotonic(), next_repeat_at = eld->timers[0].trigger_at;
if (timeout < 0 || now + timeout > next_repeat_at) {
timeout = next_repeat_at <= now ? 0 : next_repeat_at - now;
}
return timeout;
}
int
pollWithTimeout(struct pollfd *fds, nfds_t nfds, double timeout) {
const long seconds = (long) timeout;
const long nanoseconds = (long) ((timeout - seconds) * 1e9);
struct timespec tv = { seconds, nanoseconds };
return ppoll(fds, nfds, &tv, NULL);
}
static void
dispatchEvents(EventLoopData *eld) {
for (nfds_t i = 0; i < eld->watches_count; i++) {
Watch *ww = eld->watches + i;
struct pollfd *pfd = eld->fds + i;
if (pfd->revents & ww->events) {
ww->ready = 1;
if (ww->callback) ww->callback(ww->fd, pfd->revents, ww->callback_data);
} else ww->ready = 0;
}
}
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])];
unsigned num_dispatches = 0;
double now = monotonic();
for (nfds_t i = 0; i < eld->timers_count && eld->timers[i].trigger_at <= now; i++) {
eld->timers[i].trigger_at = now + eld->timers[i].interval;
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;
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 (num_dispatches) update_timers(eld);
return num_dispatches;
}
static void
drain_wakeup_fd(int fd, int events, void* data) {
static char drain_buf[64];
while(read(fd, drain_buf, sizeof(drain_buf)) < 0 && errno == EINTR);
}
void
initPollData(EventLoopData *eld, int wakeup_fd, int display_fd) {
addWatch(eld, "display", display_fd, POLLIN, 1, NULL, NULL);
addWatch(eld, "wakeup", wakeup_fd, POLLIN, 1, drain_wakeup_fd, NULL);
}
int
pollForEvents(EventLoopData *eld, double timeout) {
int read_ok = 0;
timeout = prepareForPoll(eld, timeout);
int result;
double end_time = monotonic() + timeout;
while(1) {
if (timeout >= 0) {
errno = 0;
result = pollWithTimeout(eld->fds, eld->watches_count, timeout);
int saved_errno = errno;
dispatchTimers(eld);
if (result > 0) {
dispatchEvents(eld);
read_ok = eld->watches[0].ready;
break;
}
timeout = end_time - monotonic();
if (timeout <= 0) break;
if (result < 0 && (saved_errno == EINTR || saved_errno == EAGAIN)) continue;
break;
} else {
errno = 0;
result = poll(eld->fds, eld->watches_count, -1);
int saved_errno = errno;
dispatchTimers(eld);
if (result > 0) {
dispatchEvents(eld);
read_ok = eld->watches[0].ready;
}
if (result < 0 && (saved_errno == EINTR || saved_errno == EAGAIN)) continue;
break;
}
}
return read_ok;
}
void
closeFds(int *fds, size_t count) {
while(count--) {
if (*fds > 0) {
close(*fds);
*fds = -1;
}
fds++;
}
}
// Splits and translates a text/uri-list into separate file paths
// NOTE: This function destroys the provided string
//
char** parseUriList(char* text, int* count)
{
const char* prefix = "file://";
char** paths = NULL;
char* line;
*count = 0;
while ((line = strtok(text, "\r\n")))
{
text = NULL;
if (line[0] == '#')
continue;
if (strncmp(line, prefix, strlen(prefix)) == 0)
{
line += strlen(prefix);
// TODO: Validate hostname
while (*line != '/')
line++;
}
(*count)++;
char* path = calloc(strlen(line) + 1, 1);
paths = realloc(paths, *count * sizeof(char*));
paths[*count - 1] = path;
while (*line)
{
if (line[0] == '%' && line[1] && line[2])
{
const char digits[3] = { line[1], line[2], '\0' };
*path = strtol(digits, NULL, 16);
line += 2;
}
else
*path = *line;
path++;
line++;
}
}
return paths;
}

74
glfw/backend_utils.h vendored Normal file
View File

@@ -0,0 +1,74 @@
//========================================================================
// GLFW 3.3 Wayland - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
//
// 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.
//
//========================================================================
#pragma once
#include <poll.h>
#include <unistd.h>
typedef unsigned long long id_type;
typedef void(*watch_callback_func)(int, int, void*);
typedef void(*timer_callback_func)(id_type, void*);
typedef struct {
int fd, events, enabled, ready;
watch_callback_func callback;
void *callback_data;
id_type id;
const char *name;
} Watch;
typedef struct {
id_type id;
double interval, trigger_at;
timer_callback_func callback;
void *callback_data;
const char *name;
} Timer;
typedef struct {
struct pollfd fds[32];
int wakeupFds[2];
nfds_t watches_count, timers_count;
Watch watches[32];
Timer timers[128];
} EventLoopData;
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);
void removeTimer(EventLoopData *eld, id_type timer_id);
void toggleTimer(EventLoopData *eld, id_type timer_id, int enabled);
void changeTimerInterval(EventLoopData *eld, id_type timer_id, double interval);
double prepareForPoll(EventLoopData *eld, double timeout);
int pollWithTimeout(struct pollfd *fds, nfds_t nfds, double timeout);
int pollForEvents(EventLoopData *eld, double timeout);
unsigned dispatchTimers(EventLoopData *eld);
void closeFds(int *fds, size_t count);
void initPollData(EventLoopData *eld, int wakeup_fd, int display_fd);
char** parseUriList(char* text, int* count);

434
glfw/cocoa_init.m Normal file
View File

@@ -0,0 +1,434 @@
//========================================================================
// GLFW 3.3 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-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 <sys/param.h> // For MAXPATHLEN
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200
#define NSEventMaskKeyUp NSKeyUpMask
#define NSEventMaskKeyDown NSKeyDownMask
#define NSEventModifierFlagCommand NSCommandKeyMask
#endif
// Change to our application bundle's resources directory, if present
//
static void changeToResourcesDirectory(void)
{
char resourcesPath[MAXPATHLEN];
CFBundleRef bundle = CFBundleGetMainBundle();
if (!bundle)
return;
CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(bundle);
CFStringRef last = CFURLCopyLastPathComponent(resourcesURL);
if (CFStringCompare(CFSTR("Resources"), last, 0) != kCFCompareEqualTo)
{
CFRelease(last);
CFRelease(resourcesURL);
return;
}
CFRelease(last);
if (!CFURLGetFileSystemRepresentation(resourcesURL,
true,
(UInt8*) resourcesPath,
MAXPATHLEN))
{
CFRelease(resourcesURL);
return;
}
CFRelease(resourcesURL);
chdir(resourcesPath);
}
// Create key code translation tables
//
static void createKeyTables(void)
{
int scancode;
memset(_glfw.ns.keycodes, -1, sizeof(_glfw.ns.keycodes));
memset(_glfw.ns.scancodes, -1, sizeof(_glfw.ns.scancodes));
_glfw.ns.keycodes[0x1D] = GLFW_KEY_0;
_glfw.ns.keycodes[0x12] = GLFW_KEY_1;
_glfw.ns.keycodes[0x13] = GLFW_KEY_2;
_glfw.ns.keycodes[0x14] = GLFW_KEY_3;
_glfw.ns.keycodes[0x15] = GLFW_KEY_4;
_glfw.ns.keycodes[0x17] = GLFW_KEY_5;
_glfw.ns.keycodes[0x16] = GLFW_KEY_6;
_glfw.ns.keycodes[0x1A] = GLFW_KEY_7;
_glfw.ns.keycodes[0x1C] = GLFW_KEY_8;
_glfw.ns.keycodes[0x19] = GLFW_KEY_9;
_glfw.ns.keycodes[0x00] = GLFW_KEY_A;
_glfw.ns.keycodes[0x0B] = GLFW_KEY_B;
_glfw.ns.keycodes[0x08] = GLFW_KEY_C;
_glfw.ns.keycodes[0x02] = GLFW_KEY_D;
_glfw.ns.keycodes[0x0E] = GLFW_KEY_E;
_glfw.ns.keycodes[0x03] = GLFW_KEY_F;
_glfw.ns.keycodes[0x05] = GLFW_KEY_G;
_glfw.ns.keycodes[0x04] = GLFW_KEY_H;
_glfw.ns.keycodes[0x22] = GLFW_KEY_I;
_glfw.ns.keycodes[0x26] = GLFW_KEY_J;
_glfw.ns.keycodes[0x28] = GLFW_KEY_K;
_glfw.ns.keycodes[0x25] = GLFW_KEY_L;
_glfw.ns.keycodes[0x2E] = GLFW_KEY_M;
_glfw.ns.keycodes[0x2D] = GLFW_KEY_N;
_glfw.ns.keycodes[0x1F] = GLFW_KEY_O;
_glfw.ns.keycodes[0x23] = GLFW_KEY_P;
_glfw.ns.keycodes[0x0C] = GLFW_KEY_Q;
_glfw.ns.keycodes[0x0F] = GLFW_KEY_R;
_glfw.ns.keycodes[0x01] = GLFW_KEY_S;
_glfw.ns.keycodes[0x11] = GLFW_KEY_T;
_glfw.ns.keycodes[0x20] = GLFW_KEY_U;
_glfw.ns.keycodes[0x09] = GLFW_KEY_V;
_glfw.ns.keycodes[0x0D] = GLFW_KEY_W;
_glfw.ns.keycodes[0x07] = GLFW_KEY_X;
_glfw.ns.keycodes[0x10] = GLFW_KEY_Y;
_glfw.ns.keycodes[0x06] = GLFW_KEY_Z;
_glfw.ns.keycodes[0x27] = GLFW_KEY_APOSTROPHE;
_glfw.ns.keycodes[0x2A] = GLFW_KEY_BACKSLASH;
_glfw.ns.keycodes[0x2B] = GLFW_KEY_COMMA;
_glfw.ns.keycodes[0x18] = GLFW_KEY_EQUAL;
_glfw.ns.keycodes[0x32] = GLFW_KEY_GRAVE_ACCENT;
_glfw.ns.keycodes[0x21] = GLFW_KEY_LEFT_BRACKET;
_glfw.ns.keycodes[0x1B] = GLFW_KEY_MINUS;
_glfw.ns.keycodes[0x2F] = GLFW_KEY_PERIOD;
_glfw.ns.keycodes[0x1E] = GLFW_KEY_RIGHT_BRACKET;
_glfw.ns.keycodes[0x29] = GLFW_KEY_SEMICOLON;
_glfw.ns.keycodes[0x2C] = GLFW_KEY_SLASH;
_glfw.ns.keycodes[0x0A] = GLFW_KEY_WORLD_1;
_glfw.ns.keycodes[0x33] = GLFW_KEY_BACKSPACE;
_glfw.ns.keycodes[0x39] = GLFW_KEY_CAPS_LOCK;
_glfw.ns.keycodes[0x75] = GLFW_KEY_DELETE;
_glfw.ns.keycodes[0x7D] = GLFW_KEY_DOWN;
_glfw.ns.keycodes[0x77] = GLFW_KEY_END;
_glfw.ns.keycodes[0x24] = GLFW_KEY_ENTER;
_glfw.ns.keycodes[0x35] = GLFW_KEY_ESCAPE;
_glfw.ns.keycodes[0x7A] = GLFW_KEY_F1;
_glfw.ns.keycodes[0x78] = GLFW_KEY_F2;
_glfw.ns.keycodes[0x63] = GLFW_KEY_F3;
_glfw.ns.keycodes[0x76] = GLFW_KEY_F4;
_glfw.ns.keycodes[0x60] = GLFW_KEY_F5;
_glfw.ns.keycodes[0x61] = GLFW_KEY_F6;
_glfw.ns.keycodes[0x62] = GLFW_KEY_F7;
_glfw.ns.keycodes[0x64] = GLFW_KEY_F8;
_glfw.ns.keycodes[0x65] = GLFW_KEY_F9;
_glfw.ns.keycodes[0x6D] = GLFW_KEY_F10;
_glfw.ns.keycodes[0x67] = GLFW_KEY_F11;
_glfw.ns.keycodes[0x6F] = GLFW_KEY_F12;
_glfw.ns.keycodes[0x69] = GLFW_KEY_F13;
_glfw.ns.keycodes[0x6B] = GLFW_KEY_F14;
_glfw.ns.keycodes[0x71] = GLFW_KEY_F15;
_glfw.ns.keycodes[0x6A] = GLFW_KEY_F16;
_glfw.ns.keycodes[0x40] = GLFW_KEY_F17;
_glfw.ns.keycodes[0x4F] = GLFW_KEY_F18;
_glfw.ns.keycodes[0x50] = GLFW_KEY_F19;
_glfw.ns.keycodes[0x5A] = GLFW_KEY_F20;
_glfw.ns.keycodes[0x73] = GLFW_KEY_HOME;
_glfw.ns.keycodes[0x72] = GLFW_KEY_INSERT;
_glfw.ns.keycodes[0x7B] = GLFW_KEY_LEFT;
_glfw.ns.keycodes[0x3A] = GLFW_KEY_LEFT_ALT;
_glfw.ns.keycodes[0x3B] = GLFW_KEY_LEFT_CONTROL;
_glfw.ns.keycodes[0x38] = GLFW_KEY_LEFT_SHIFT;
_glfw.ns.keycodes[0x37] = GLFW_KEY_LEFT_SUPER;
_glfw.ns.keycodes[0x6E] = GLFW_KEY_MENU;
_glfw.ns.keycodes[0x47] = GLFW_KEY_NUM_LOCK;
_glfw.ns.keycodes[0x79] = GLFW_KEY_PAGE_DOWN;
_glfw.ns.keycodes[0x74] = GLFW_KEY_PAGE_UP;
_glfw.ns.keycodes[0x7C] = GLFW_KEY_RIGHT;
_glfw.ns.keycodes[0x3D] = GLFW_KEY_RIGHT_ALT;
_glfw.ns.keycodes[0x3E] = GLFW_KEY_RIGHT_CONTROL;
_glfw.ns.keycodes[0x3C] = GLFW_KEY_RIGHT_SHIFT;
_glfw.ns.keycodes[0x36] = GLFW_KEY_RIGHT_SUPER;
_glfw.ns.keycodes[0x31] = GLFW_KEY_SPACE;
_glfw.ns.keycodes[0x30] = GLFW_KEY_TAB;
_glfw.ns.keycodes[0x7E] = GLFW_KEY_UP;
_glfw.ns.keycodes[0x52] = GLFW_KEY_KP_0;
_glfw.ns.keycodes[0x53] = GLFW_KEY_KP_1;
_glfw.ns.keycodes[0x54] = GLFW_KEY_KP_2;
_glfw.ns.keycodes[0x55] = GLFW_KEY_KP_3;
_glfw.ns.keycodes[0x56] = GLFW_KEY_KP_4;
_glfw.ns.keycodes[0x57] = GLFW_KEY_KP_5;
_glfw.ns.keycodes[0x58] = GLFW_KEY_KP_6;
_glfw.ns.keycodes[0x59] = GLFW_KEY_KP_7;
_glfw.ns.keycodes[0x5B] = GLFW_KEY_KP_8;
_glfw.ns.keycodes[0x5C] = GLFW_KEY_KP_9;
_glfw.ns.keycodes[0x45] = GLFW_KEY_KP_ADD;
_glfw.ns.keycodes[0x41] = GLFW_KEY_KP_DECIMAL;
_glfw.ns.keycodes[0x4B] = GLFW_KEY_KP_DIVIDE;
_glfw.ns.keycodes[0x4C] = GLFW_KEY_KP_ENTER;
_glfw.ns.keycodes[0x51] = GLFW_KEY_KP_EQUAL;
_glfw.ns.keycodes[0x43] = GLFW_KEY_KP_MULTIPLY;
_glfw.ns.keycodes[0x4E] = GLFW_KEY_KP_SUBTRACT;
for (scancode = 0; scancode < 256; scancode++)
{
// Store the reverse translation for faster key name lookup
if (_glfw.ns.keycodes[scancode] >= 0)
_glfw.ns.scancodes[_glfw.ns.keycodes[scancode]] = scancode;
}
}
// Retrieve Unicode data for the current keyboard layout
//
static GLFWbool updateUnicodeDataNS(void)
{
if (_glfw.ns.inputSource)
{
CFRelease(_glfw.ns.inputSource);
_glfw.ns.inputSource = NULL;
_glfw.ns.unicodeData = nil;
}
for (_GLFWwindow *window = _glfw.windowListHead; window; window = window->next)
window->ns.deadKeyState = 0;
_glfw.ns.inputSource = TISCopyCurrentKeyboardLayoutInputSource();
if (!_glfw.ns.inputSource)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to retrieve keyboard layout input source");
return GLFW_FALSE;
}
_glfw.ns.unicodeData =
TISGetInputSourceProperty(_glfw.ns.inputSource,
kTISPropertyUnicodeKeyLayoutData);
if (!_glfw.ns.unicodeData)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to retrieve keyboard layout Unicode data");
return GLFW_FALSE;
}
return GLFW_TRUE;
}
// Load HIToolbox.framework and the TIS symbols we need from it
//
static GLFWbool initializeTIS(void)
{
// This works only because Cocoa has already loaded it properly
_glfw.ns.tis.bundle =
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.HIToolbox"));
if (!_glfw.ns.tis.bundle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to load HIToolbox.framework");
return GLFW_FALSE;
}
CFStringRef* kPropertyUnicodeKeyLayoutData =
CFBundleGetDataPointerForName(_glfw.ns.tis.bundle,
CFSTR("kTISPropertyUnicodeKeyLayoutData"));
_glfw.ns.tis.CopyCurrentKeyboardLayoutInputSource =
CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
CFSTR("TISCopyCurrentKeyboardLayoutInputSource"));
_glfw.ns.tis.GetInputSourceProperty =
CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
CFSTR("TISGetInputSourceProperty"));
_glfw.ns.tis.GetKbdType =
CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
CFSTR("LMGetKbdType"));
if (!kPropertyUnicodeKeyLayoutData ||
!TISCopyCurrentKeyboardLayoutInputSource ||
!TISGetInputSourceProperty ||
!LMGetKbdType)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to load TIS API symbols");
return GLFW_FALSE;
}
_glfw.ns.tis.kPropertyUnicodeKeyLayoutData =
*kPropertyUnicodeKeyLayoutData;
return updateUnicodeDataNS();
}
@interface GLFWHelper : NSObject
@end
@implementation GLFWHelper
- (void)selectedKeyboardInputSourceChanged:(NSObject* )object
{
updateUnicodeDataNS();
}
- (void)doNothing:(id)object
{
}
@end // GLFWHelper
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
static inline bool
is_ctrl_tab(NSEvent *event) {
NSEventModifierFlags modifierFlags = [event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
return event.keyCode == kVK_Tab && (modifierFlags == NSEventModifierFlagControl || modifierFlags == (
NSEventModifierFlagControl | NSEventModifierFlagShift));
}
int _glfwPlatformInit(void)
{
_glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init];
_glfw.ns.helper = [[GLFWHelper alloc] init];
[NSThread detachNewThreadSelector:@selector(doNothing:)
toTarget:_glfw.ns.helper
withObject:nil];
[NSApplication sharedApplication];
NSEvent* (^keydown_block)(NSEvent*) = ^ NSEvent* (NSEvent* event)
{
if (is_ctrl_tab(event)) {
// Cocoa swallows Ctrl+Tab to cycle between views
[[NSApp keyWindow].contentView keyDown:event];
}
return event;
};
NSEvent* (^keyup_block)(NSEvent*) = ^ NSEvent* (NSEvent* event)
{
if ([event 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)) {
// 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();
[[NSNotificationCenter defaultCenter]
addObserver:_glfw.ns.helper
selector:@selector(selectedKeyboardInputSourceChanged:)
name:NSTextInputContextKeyboardSelectionDidChangeNotification
object:nil];
createKeyTables();
_glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
if (!_glfw.ns.eventSource)
return GLFW_FALSE;
CGEventSourceSetLocalEventsSuppressionInterval(_glfw.ns.eventSource, 0.0);
if (!initializeTIS())
return GLFW_FALSE;
_glfwInitTimerNS();
_glfwInitJoysticksNS();
_glfwPollMonitorsNS();
return GLFW_TRUE;
}
void _glfwPlatformTerminate(void)
{
if (_glfw.ns.inputSource)
{
CFRelease(_glfw.ns.inputSource);
_glfw.ns.inputSource = NULL;
_glfw.ns.unicodeData = nil;
}
if (_glfw.ns.eventSource)
{
CFRelease(_glfw.ns.eventSource);
_glfw.ns.eventSource = NULL;
}
if (_glfw.ns.delegate)
{
[NSApp setDelegate:nil];
[_glfw.ns.delegate release];
_glfw.ns.delegate = nil;
}
if (_glfw.ns.helper)
{
[[NSNotificationCenter defaultCenter]
removeObserver:_glfw.ns.helper
name:NSTextInputContextKeyboardSelectionDidChangeNotification
object:nil];
[[NSNotificationCenter defaultCenter]
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"
#if defined(_GLFW_BUILD_DLL)
" dynamic"
#endif
;
}

50
glfw/cocoa_joystick.h vendored Normal file
View File

@@ -0,0 +1,50 @@
//========================================================================
// GLFW 3.3 Cocoa - 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.
//
//========================================================================
#include <IOKit/IOKitLib.h>
#include <IOKit/IOCFPlugIn.h>
#include <IOKit/hid/IOHIDLib.h>
#include <IOKit/hid/IOHIDKeys.h>
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickNS ns
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE
#define _GLFW_PLATFORM_MAPPING_NAME "Mac OS X"
// Cocoa-specific per-joystick data
//
typedef struct _GLFWjoystickNS
{
IOHIDDeviceRef device;
CFMutableArrayRef axes;
CFMutableArrayRef buttons;
CFMutableArrayRef hats;
} _GLFWjoystickNS;
void _glfwInitJoysticksNS(void);
void _glfwTerminateJoysticksNS(void);

462
glfw/cocoa_joystick.m Normal file
View File

@@ -0,0 +1,462 @@
//========================================================================
// GLFW 3.3 Cocoa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net>
//
// This software is provided 'as-is', without any express or implied
// 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 <unistd.h>
#include <ctype.h>
#include <string.h>
#include <mach/mach.h>
#include <mach/mach_error.h>
#include <CoreFoundation/CoreFoundation.h>
#include <Kernel/IOKit/hidsystem/IOHIDUsageTables.h>
// Joystick element information
//
typedef struct _GLFWjoyelementNS
{
IOHIDElementRef native;
uint32_t usage;
int index;
long minimum;
long maximum;
} _GLFWjoyelementNS;
// Returns the value of the specified element of the specified joystick
//
static long getElementValue(_GLFWjoystick* js, _GLFWjoyelementNS* element)
{
IOHIDValueRef valueRef;
long value = 0;
if (js->ns.device)
{
if (IOHIDDeviceGetValue(js->ns.device,
element->native,
&valueRef) == kIOReturnSuccess)
{
value = IOHIDValueGetIntegerValue(valueRef);
}
}
return value;
}
// Comparison function for matching the SDL element order
//
static CFComparisonResult compareElements(const void* fp,
const void* sp,
void* user)
{
const _GLFWjoyelementNS* fe = fp;
const _GLFWjoyelementNS* se = sp;
if (fe->usage < se->usage)
return kCFCompareLessThan;
if (fe->usage > se->usage)
return kCFCompareGreaterThan;
if (fe->index < se->index)
return kCFCompareLessThan;
if (fe->index > se->index)
return kCFCompareGreaterThan;
return kCFCompareEqualTo;
}
// Removes the specified joystick
//
static void closeJoystick(_GLFWjoystick* js)
{
int i;
if (!js->present)
return;
for (i = 0; i < CFArrayGetCount(js->ns.axes); i++)
free((void*) CFArrayGetValueAtIndex(js->ns.axes, i));
CFRelease(js->ns.axes);
for (i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
free((void*) CFArrayGetValueAtIndex(js->ns.buttons, i));
CFRelease(js->ns.buttons);
for (i = 0; i < CFArrayGetCount(js->ns.hats); i++)
free((void*) CFArrayGetValueAtIndex(js->ns.hats, i));
CFRelease(js->ns.hats);
_glfwFreeJoystick(js);
_glfwInputJoystick(js, GLFW_DISCONNECTED);
}
// Callback for user-initiated joystick addition
//
static void matchCallback(void* context,
IOReturn result,
void* sender,
IOHIDDeviceRef device)
{
int jid;
char name[256];
char guid[33];
CFIndex i;
CFTypeRef property;
uint32_t vendor = 0, product = 0, version = 0;
_GLFWjoystick* js;
CFMutableArrayRef axes, buttons, hats;
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
if (_glfw.joysticks[jid].ns.device == device)
return;
}
axes = CFArrayCreateMutable(NULL, 0, NULL);
buttons = CFArrayCreateMutable(NULL, 0, NULL);
hats = CFArrayCreateMutable(NULL, 0, NULL);
property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
if (property)
{
CFStringGetCString(property,
name,
sizeof(name),
kCFStringEncodingUTF8);
}
else
strncpy(name, "Unknown", sizeof(name));
property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey));
if (property)
CFNumberGetValue(property, kCFNumberSInt32Type, &vendor);
property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductIDKey));
if (property)
CFNumberGetValue(property, kCFNumberSInt32Type, &product);
property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVersionNumberKey));
if (property)
CFNumberGetValue(property, kCFNumberSInt32Type, &version);
// Generate a joystick GUID that matches the SDL 2.0.5+ one
if (vendor && product)
{
sprintf(guid, "03000000%02x%02x0000%02x%02x0000%02x%02x0000",
(uint8_t) vendor, (uint8_t) (vendor >> 8),
(uint8_t) product, (uint8_t) (product >> 8),
(uint8_t) version, (uint8_t) (version >> 8));
}
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]);
}
CFArrayRef elements =
IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
for (i = 0; i < CFArrayGetCount(elements); i++)
{
IOHIDElementRef native = (IOHIDElementRef)
CFArrayGetValueAtIndex(elements, i);
if (CFGetTypeID(native) != IOHIDElementGetTypeID())
continue;
const IOHIDElementType type = IOHIDElementGetType(native);
if ((type != kIOHIDElementTypeInput_Axis) &&
(type != kIOHIDElementTypeInput_Button) &&
(type != kIOHIDElementTypeInput_Misc))
{
continue;
}
CFMutableArrayRef target = NULL;
const uint32_t usage = IOHIDElementGetUsage(native);
const uint32_t page = IOHIDElementGetUsagePage(native);
if (page == kHIDPage_GenericDesktop)
{
switch (usage)
{
case kHIDUsage_GD_X:
case kHIDUsage_GD_Y:
case kHIDUsage_GD_Z:
case kHIDUsage_GD_Rx:
case kHIDUsage_GD_Ry:
case kHIDUsage_GD_Rz:
case kHIDUsage_GD_Slider:
case kHIDUsage_GD_Dial:
case kHIDUsage_GD_Wheel:
target = axes;
break;
case kHIDUsage_GD_Hatswitch:
target = hats;
break;
}
}
else if (page == kHIDPage_Button)
target = buttons;
if (target)
{
_GLFWjoyelementNS* element = calloc(1, sizeof(_GLFWjoyelementNS));
element->native = native;
element->usage = usage;
element->index = (int) CFArrayGetCount(target);
element->minimum = IOHIDElementGetLogicalMin(native);
element->maximum = IOHIDElementGetLogicalMax(native);
CFArrayAppendValue(target, element);
}
}
CFRelease(elements);
CFArraySortValues(axes, CFRangeMake(0, CFArrayGetCount(axes)),
compareElements, NULL);
CFArraySortValues(buttons, CFRangeMake(0, CFArrayGetCount(buttons)),
compareElements, NULL);
CFArraySortValues(hats, CFRangeMake(0, CFArrayGetCount(hats)),
compareElements, NULL);
js = _glfwAllocJoystick(name, guid,
(int) CFArrayGetCount(axes),
(int) CFArrayGetCount(buttons),
(int) CFArrayGetCount(hats));
js->ns.device = device;
js->ns.axes = axes;
js->ns.buttons = buttons;
js->ns.hats = hats;
_glfwInputJoystick(js, GLFW_CONNECTED);
}
// Callback for user-initiated joystick removal
//
static void removeCallback(void* context,
IOReturn result,
void* sender,
IOHIDDeviceRef device)
{
int jid;
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
if (_glfw.joysticks[jid].ns.device == device)
{
closeJoystick(_glfw.joysticks + jid);
break;
}
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Initialize joystick interface
//
void _glfwInitJoysticksNS(void)
{
CFMutableArrayRef matching;
const long usages[] =
{
kHIDUsage_GD_Joystick,
kHIDUsage_GD_GamePad,
kHIDUsage_GD_MultiAxisController
};
_glfw.ns.hidManager = IOHIDManagerCreate(kCFAllocatorDefault,
kIOHIDOptionsTypeNone);
matching = CFArrayCreateMutable(kCFAllocatorDefault,
0,
&kCFTypeArrayCallBacks);
if (!matching)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to create array");
return;
}
for (int i = 0; i < sizeof(usages) / sizeof(long); i++)
{
const long page = kHIDPage_GenericDesktop;
CFMutableDictionaryRef dict =
CFDictionaryCreateMutable(kCFAllocatorDefault,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
if (!dict)
continue;
CFNumberRef pageRef = CFNumberCreate(kCFAllocatorDefault,
kCFNumberLongType,
&page);
CFNumberRef usageRef = CFNumberCreate(kCFAllocatorDefault,
kCFNumberLongType,
&usages[i]);
if (pageRef && usageRef)
{
CFDictionarySetValue(dict,
CFSTR(kIOHIDDeviceUsagePageKey),
pageRef);
CFDictionarySetValue(dict,
CFSTR(kIOHIDDeviceUsageKey),
usageRef);
CFArrayAppendValue(matching, dict);
}
if (pageRef)
CFRelease(pageRef);
if (usageRef)
CFRelease(usageRef);
CFRelease(dict);
}
IOHIDManagerSetDeviceMatchingMultiple(_glfw.ns.hidManager, matching);
CFRelease(matching);
IOHIDManagerRegisterDeviceMatchingCallback(_glfw.ns.hidManager,
&matchCallback, NULL);
IOHIDManagerRegisterDeviceRemovalCallback(_glfw.ns.hidManager,
&removeCallback, NULL);
IOHIDManagerScheduleWithRunLoop(_glfw.ns.hidManager,
CFRunLoopGetMain(),
kCFRunLoopDefaultMode);
IOHIDManagerOpen(_glfw.ns.hidManager, kIOHIDOptionsTypeNone);
// Execute the run loop once in order to register any initially-attached
// joysticks
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false);
}
// Close all opened joystick handles
//
void _glfwTerminateJoysticksNS(void)
{
int jid;
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
closeJoystick(_glfw.joysticks + jid);
CFRelease(_glfw.ns.hidManager);
_glfw.ns.hidManager = NULL;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
{
if (mode & _GLFW_POLL_AXES)
{
CFIndex i;
for (i = 0; i < CFArrayGetCount(js->ns.axes); i++)
{
_GLFWjoyelementNS* axis = (_GLFWjoyelementNS*)
CFArrayGetValueAtIndex(js->ns.axes, i);
const long raw = getElementValue(js, axis);
// Perform auto calibration
if (raw < axis->minimum)
axis->minimum = raw;
if (raw > axis->maximum)
axis->maximum = raw;
const long delta = axis->maximum - axis->minimum;
if (delta == 0)
_glfwInputJoystickAxis(js, (int) i, 0.f);
else
{
const float value = (2.f * (raw - axis->minimum) / delta) - 1.f;
_glfwInputJoystickAxis(js, (int) i, value);
}
}
}
if (mode & _GLFW_POLL_BUTTONS)
{
CFIndex i;
for (i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
{
_GLFWjoyelementNS* button = (_GLFWjoyelementNS*)
CFArrayGetValueAtIndex(js->ns.buttons, i);
const char value = getElementValue(js, button) - button->minimum;
_glfwInputJoystickButton(js, (int) i, value);
}
for (i = 0; i < CFArrayGetCount(js->ns.hats); i++)
{
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
};
_GLFWjoyelementNS* hat = (_GLFWjoyelementNS*)
CFArrayGetValueAtIndex(js->ns.hats, i);
long state = getElementValue(js, hat) - hat->minimum;
if (state < 0 || state > 8)
state = 8;
_glfwInputJoystickHat(js, (int) i, states[state]);
}
}
return js->present;
}
void _glfwPlatformUpdateGamepadGUID(char* guid)
{
if ((strncmp(guid + 4, "000000000000", 12) == 0) &&
(strncmp(guid + 20, "000000000000", 12) == 0))
{
char original[33];
strcpy(original, guid);
sprintf(guid, "03000000%.4s0000%.4s000000000000",
original, original + 16);
}
}

526
glfw/cocoa_monitor.m Normal file
View File

@@ -0,0 +1,526 @@
//========================================================================
// GLFW 3.3 macOS - 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 <limits.h>
#include <IOKit/graphics/IOGraphicsLib.h>
#include <CoreVideo/CVBase.h>
#include <CoreVideo/CVDisplayLink.h>
#include <ApplicationServices/ApplicationServices.h>
// Get the name of the specified display, or NULL
//
static char* getDisplayName(CGDirectDisplayID displayID)
{
io_iterator_t it;
io_service_t service;
CFDictionaryRef info;
if (IOServiceGetMatchingServices(kIOMasterPortDefault,
IOServiceMatching("IODisplayConnect"),
&it) != 0)
{
// This may happen if a desktop Mac is running headless
return NULL;
}
while ((service = IOIteratorNext(it)) != 0)
{
info = IODisplayCreateInfoDictionary(service,
kIODisplayOnlyPreferredName);
CFNumberRef vendorIDRef =
CFDictionaryGetValue(info, CFSTR(kDisplayVendorID));
CFNumberRef productIDRef =
CFDictionaryGetValue(info, CFSTR(kDisplayProductID));
if (!vendorIDRef || !productIDRef)
{
CFRelease(info);
continue;
}
unsigned int vendorID, productID;
CFNumberGetValue(vendorIDRef, kCFNumberIntType, &vendorID);
CFNumberGetValue(productIDRef, kCFNumberIntType, &productID);
if (CGDisplayVendorNumber(displayID) == vendorID &&
CGDisplayModelNumber(displayID) == productID)
{
// Info dictionary is used and freed below
break;
}
CFRelease(info);
}
IOObjectRelease(it);
if (!service)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to find service port for display");
return NULL;
}
CFDictionaryRef names =
CFDictionaryGetValue(info, CFSTR(kDisplayProductName));
CFStringRef nameRef;
if (!names || !CFDictionaryGetValueIfPresent(names, CFSTR("en_US"),
(const void**) &nameRef))
{
// This may happen if a desktop Mac is running headless
CFRelease(info);
return NULL;
}
const CFIndex size =
CFStringGetMaximumSizeForEncoding(CFStringGetLength(nameRef),
kCFStringEncodingUTF8);
char* name = calloc(size + 1, 1);
CFStringGetCString(nameRef, name, size, kCFStringEncodingUTF8);
CFRelease(info);
return name;
}
// Check whether the display mode should be included in enumeration
//
static GLFWbool modeIsGood(CGDisplayModeRef mode)
{
uint32_t flags = CGDisplayModeGetIOFlags(mode);
if (!(flags & kDisplayModeValidFlag) || !(flags & kDisplayModeSafeFlag))
return GLFW_FALSE;
if (flags & kDisplayModeInterlacedFlag)
return GLFW_FALSE;
if (flags & kDisplayModeStretchedFlag)
return GLFW_FALSE;
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) &&
CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0))
{
CFRelease(format);
return GLFW_FALSE;
}
CFRelease(format);
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
return GLFW_TRUE;
}
// Convert Core Graphics display mode to GLFW video mode
//
static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode,
CVDisplayLinkRef link)
{
GLFWvidmode result;
result.width = (int) CGDisplayModeGetWidth(mode);
result.height = (int) CGDisplayModeGetHeight(mode);
result.refreshRate = (int) CGDisplayModeGetRefreshRate(mode);
if (result.refreshRate == 0)
{
const CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(link);
if (!(time.flags & kCVTimeIsIndefinite))
result.refreshRate = (int) (time.timeScale / (double) time.timeValue);
}
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0)
{
result.redBits = 5;
result.greenBits = 5;
result.blueBits = 5;
}
else
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
{
result.redBits = 8;
result.greenBits = 8;
result.blueBits = 8;
}
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
CFRelease(format);
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
return result;
}
// Starts reservation for display fading
//
static CGDisplayFadeReservationToken beginFadeReservation(void)
{
CGDisplayFadeReservationToken token = kCGDisplayFadeReservationInvalidToken;
if (CGAcquireDisplayFadeReservation(5, &token) == kCGErrorSuccess)
{
CGDisplayFade(token, 0.3,
kCGDisplayBlendNormal,
kCGDisplayBlendSolidColor,
0.0, 0.0, 0.0,
TRUE);
}
return token;
}
// Ends reservation for display fading
//
static void endFadeReservation(CGDisplayFadeReservationToken token)
{
if (token != kCGDisplayFadeReservationInvalidToken)
{
CGDisplayFade(token, 0.5,
kCGDisplayBlendSolidColor,
kCGDisplayBlendNormal,
0.0, 0.0, 0.0,
FALSE);
CGReleaseDisplayFadeReservation(token);
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Poll for changes in the set of connected monitors
//
void _glfwPollMonitorsNS(void)
{
uint32_t i, j, displayCount, disconnectedCount;
CGDirectDisplayID* displays;
_GLFWmonitor** disconnected = NULL;
CGGetOnlineDisplayList(0, NULL, &displayCount);
displays = calloc(displayCount, sizeof(CGDirectDisplayID));
CGGetOnlineDisplayList(displayCount, displays, &displayCount);
for (i = 0; i < _glfw.monitorCount; i++)
_glfw.monitors[i]->ns.screen = nil;
disconnectedCount = _glfw.monitorCount;
if (disconnectedCount)
{
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
memcpy(disconnected,
_glfw.monitors,
_glfw.monitorCount * sizeof(_GLFWmonitor*));
}
for (i = 0; i < displayCount; i++)
{
_GLFWmonitor* monitor;
const uint32_t unitNumber = CGDisplayUnitNumber(displays[i]);
if (CGDisplayIsAsleep(displays[i]))
continue;
for (j = 0; j < disconnectedCount; j++)
{
// HACK: Compare unit numbers instead of display IDs to work around
// display replacement on machines with automatic graphics
// switching
if (disconnected[j] && disconnected[j]->ns.unitNumber == unitNumber)
{
disconnected[j] = NULL;
break;
}
}
const CGSize size = CGDisplayScreenSize(displays[i]);
char* name = getDisplayName(displays[i]);
if (!name)
name = _glfw_strdup("Unknown");
monitor = _glfwAllocMonitor(name, size.width, size.height);
monitor->ns.displayID = displays[i];
monitor->ns.unitNumber = unitNumber;
free(name);
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
}
for (i = 0; i < disconnectedCount; i++)
{
if (disconnected[i])
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
}
free(disconnected);
free(displays);
}
// Change the current video mode
//
void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired)
{
CFArrayRef modes;
CFIndex count, i;
CVDisplayLinkRef link;
CGDisplayModeRef native = NULL;
GLFWvidmode current;
const GLFWvidmode* best;
best = _glfwChooseVideoMode(monitor, desired);
_glfwPlatformGetVideoMode(monitor, &current);
if (_glfwCompareVideoModes(&current, best) == 0)
return;
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
count = CFArrayGetCount(modes);
for (i = 0; i < count; i++)
{
CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
if (!modeIsGood(dm))
continue;
const GLFWvidmode mode = vidmodeFromCGDisplayMode(dm, link);
if (_glfwCompareVideoModes(best, &mode) == 0)
{
native = dm;
break;
}
}
if (native)
{
if (monitor->ns.previousMode == NULL)
monitor->ns.previousMode = CGDisplayCopyDisplayMode(monitor->ns.displayID);
CGDisplayFadeReservationToken token = beginFadeReservation();
CGDisplaySetDisplayMode(monitor->ns.displayID, native, NULL);
endFadeReservation(token);
}
CFRelease(modes);
CVDisplayLinkRelease(link);
}
// Restore the previously saved (original) video mode
//
void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor)
{
if (monitor->ns.previousMode)
{
CGDisplayFadeReservationToken token = beginFadeReservation();
CGDisplaySetDisplayMode(monitor->ns.displayID,
monitor->ns.previousMode, NULL);
endFadeReservation(token);
CGDisplayModeRelease(monitor->ns.previousMode);
monitor->ns.previousMode = NULL;
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
{
}
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
{
const CGRect bounds = CGDisplayBounds(monitor->ns.displayID);
if (xpos)
*xpos = (int) bounds.origin.x;
if (ypos)
*ypos = (int) bounds.origin.y;
}
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;
}
}
const NSRect points = [monitor->ns.screen frame];
const NSRect pixels = [monitor->ns.screen convertRectToBacking:points];
if (xscale)
*xscale = (float) (pixels.size.width / points.size.width);
if (yscale)
*yscale = (float) (pixels.size.height / points.size.height);
}
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
{
CFArrayRef modes;
CFIndex found, i, j;
GLFWvidmode* result;
CVDisplayLinkRef link;
*count = 0;
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
found = CFArrayGetCount(modes);
result = calloc(found, sizeof(GLFWvidmode));
for (i = 0; i < found; i++)
{
CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
if (!modeIsGood(dm))
continue;
const GLFWvidmode mode = vidmodeFromCGDisplayMode(dm, link);
for (j = 0; j < *count; j++)
{
if (_glfwCompareVideoModes(result + j, &mode) == 0)
break;
}
// Skip duplicate modes
if (i < *count)
continue;
(*count)++;
result[*count - 1] = mode;
}
CFRelease(modes);
CVDisplayLinkRelease(link);
return result;
}
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode)
{
CGDisplayModeRef displayMode;
CVDisplayLinkRef link;
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
displayMode = CGDisplayCopyDisplayMode(monitor->ns.displayID);
*mode = vidmodeFromCGDisplayMode(displayMode, link);
CGDisplayModeRelease(displayMode);
CVDisplayLinkRelease(link);
}
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{
uint32_t i, size = CGDisplayGammaTableCapacity(monitor->ns.displayID);
CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue));
CGGetDisplayTransferByTable(monitor->ns.displayID,
size,
values,
values + size,
values + size * 2,
&size);
_glfwAllocGammaArrays(ramp, size);
for (i = 0; i < size; i++)
{
ramp->red[i] = (unsigned short) (values[i] * 65535);
ramp->green[i] = (unsigned short) (values[i + size] * 65535);
ramp->blue[i] = (unsigned short) (values[i + size * 2] * 65535);
}
free(values);
return GLFW_TRUE;
}
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{
int i;
CGGammaValue* values = calloc(ramp->size * 3, sizeof(CGGammaValue));
for (i = 0; i < ramp->size; i++)
{
values[i] = ramp->red[i] / 65535.f;
values[i + ramp->size] = ramp->green[i] / 65535.f;
values[i + ramp->size * 2] = ramp->blue[i] / 65535.f;
}
CGSetDisplayTransferByTable(monitor->ns.displayID,
ramp->size,
values,
values + ramp->size,
values + ramp->size * 2);
free(values);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW native API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(kCGNullDirectDisplay);
return monitor->ns.displayID;
}

178
glfw/cocoa_platform.h vendored Normal file
View File

@@ -0,0 +1,178 @@
//========================================================================
// GLFW 3.3 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-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 <stdint.h>
#include <dlfcn.h>
#include <Carbon/Carbon.h>
#if defined(__OBJC__)
#import <Cocoa/Cocoa.h>
#else
typedef void* id;
#endif
typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
typedef int (* GLFWcocoatextinputfilterfun)(int,int,int);
typedef int (* GLFWapplicationshouldhandlereopenfun)(int);
typedef int (* GLFWcocoatogglefullscreenfun)(GLFWwindow*);
typedef struct VkMacOSSurfaceCreateInfoMVK
{
VkStructureType sType;
const void* pNext;
VkMacOSSurfaceCreateFlagsMVK flags;
const void* pView;
} VkMacOSSurfaceCreateInfoMVK;
typedef VkResult (APIENTRY *PFN_vkCreateMacOSSurfaceMVK)(VkInstance,const VkMacOSSurfaceCreateInfoMVK*,const VkAllocationCallbacks*,VkSurfaceKHR*);
#include "posix_thread.h"
#include "cocoa_joystick.h"
#include "nsgl_context.h"
#include "egl_context.h"
#include "osmesa_context.h"
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
#define _glfw_dlclose(handle) dlclose(handle)
#define _glfw_dlsym(handle, name) dlsym(handle, name)
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->ns.view)
#define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNS ns
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns
#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerNS ns
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorNS ns
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorNS ns
// HIToolbox.framework pointer typedefs
#define kTISPropertyUnicodeKeyLayoutData _glfw.ns.tis.kPropertyUnicodeKeyLayoutData
typedef TISInputSourceRef (*PFN_TISCopyCurrentKeyboardLayoutInputSource)(void);
#define TISCopyCurrentKeyboardLayoutInputSource _glfw.ns.tis.CopyCurrentKeyboardLayoutInputSource
typedef void* (*PFN_TISGetInputSourceProperty)(TISInputSourceRef,CFStringRef);
#define TISGetInputSourceProperty _glfw.ns.tis.GetInputSourceProperty
typedef UInt8 (*PFN_LMGetKbdType)(void);
#define LMGetKbdType _glfw.ns.tis.GetKbdType
// Cocoa-specific per-window data
//
typedef struct _GLFWwindowNS
{
id object;
id delegate;
id view;
id layer;
GLFWbool maximized;
// Cached window properties to filter out duplicate events
int width, height;
int fbWidth, fbHeight;
float xscale, yscale;
// The total sum of the distances the cursor has been warped
// since the last cursor motion event was processed
// This is kept to counteract Cocoa doing the same internally
double cursorWarpDeltaX, cursorWarpDeltaY;
// The text input filter callback
GLFWcocoatextinputfilterfun textInputFilterCallback;
// The toggle fullscreen intercept callback
GLFWcocoatogglefullscreenfun toggleFullscreenCallback;
// Dead key state
UInt32 deadKeyState;
} _GLFWwindowNS;
// Cocoa-specific global data
//
typedef struct _GLFWlibraryNS
{
CGEventSourceRef eventSource;
id delegate;
id autoreleasePool;
GLFWbool cursorHidden;
TISInputSourceRef inputSource;
IOHIDManagerRef hidManager;
id unicodeData;
id helper;
id keyUpMonitor;
id keyDownMonitor;
char keyName[64];
char text[256];
short int keycodes[256];
short int scancodes[GLFW_KEY_LAST + 1];
char* clipboardString;
CGPoint cascadePoint;
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow;
struct {
CFBundleRef bundle;
PFN_TISCopyCurrentKeyboardLayoutInputSource CopyCurrentKeyboardLayoutInputSource;
PFN_TISGetInputSourceProperty GetInputSourceProperty;
PFN_LMGetKbdType GetKbdType;
CFStringRef kPropertyUnicodeKeyLayoutData;
} tis;
} _GLFWlibraryNS;
// Cocoa-specific per-monitor data
//
typedef struct _GLFWmonitorNS
{
CGDirectDisplayID displayID;
CGDisplayModeRef previousMode;
uint32_t unitNumber;
id screen;
} _GLFWmonitorNS;
// Cocoa-specific per-cursor data
//
typedef struct _GLFWcursorNS
{
id object;
} _GLFWcursorNS;
// Cocoa-specific global timer data
//
typedef struct _GLFWtimerNS
{
uint64_t frequency;
} _GLFWtimerNS;
void _glfwInitTimerNS(void);
void _glfwPollMonitorsNS(void);
void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired);
void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor);

60
glfw/cocoa_time.c vendored Normal file
View File

@@ -0,0 +1,60 @@
//========================================================================
// GLFW 3.3 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-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 <mach/mach_time.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Initialise timer
//
void _glfwInitTimerNS(void)
{
mach_timebase_info_data_t info;
mach_timebase_info(&info);
_glfw.timer.ns.frequency = (info.denom * 1e9) / info.numer;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
uint64_t _glfwPlatformGetTimerValue(void)
{
return mach_absolute_time();
}
uint64_t _glfwPlatformGetTimerFrequency(void)
{
return _glfw.timer.ns.frequency;
}

2197
glfw/cocoa_window.m Normal file

File diff suppressed because it is too large Load Diff

758
glfw/context.c vendored Normal file
View File

@@ -0,0 +1,758 @@
//========================================================================
// GLFW 3.3 - 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>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdio.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Checks whether the desired context attributes are valid
//
// This function checks things like whether the specified client API version
// exists and whether all relevant options have supported and non-conflicting
// values
//
GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
{
if (ctxconfig->share)
{
if (ctxconfig->client == GLFW_NO_API ||
ctxconfig->share->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return GLFW_FALSE;
}
}
if (ctxconfig->source != GLFW_NATIVE_CONTEXT_API &&
ctxconfig->source != GLFW_EGL_CONTEXT_API &&
ctxconfig->source != GLFW_OSMESA_CONTEXT_API)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid context creation API 0x%08X",
ctxconfig->source);
return GLFW_FALSE;
}
if (ctxconfig->client != GLFW_NO_API &&
ctxconfig->client != GLFW_OPENGL_API &&
ctxconfig->client != GLFW_OPENGL_ES_API)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid client API 0x%08X",
ctxconfig->client);
return GLFW_FALSE;
}
if (ctxconfig->client == GLFW_OPENGL_API)
{
if ((ctxconfig->major < 1 || ctxconfig->minor < 0) ||
(ctxconfig->major == 1 && ctxconfig->minor > 5) ||
(ctxconfig->major == 2 && ctxconfig->minor > 1) ||
(ctxconfig->major == 3 && ctxconfig->minor > 3))
{
// OpenGL 1.0 is the smallest valid version
// OpenGL 1.x series ended with version 1.5
// OpenGL 2.x series ended with version 2.1
// OpenGL 3.x series ended with version 3.3
// For now, let everything else through
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid OpenGL version %i.%i",
ctxconfig->major, ctxconfig->minor);
return GLFW_FALSE;
}
if (ctxconfig->profile)
{
if (ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE &&
ctxconfig->profile != GLFW_OPENGL_COMPAT_PROFILE)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid OpenGL profile 0x%08X",
ctxconfig->profile);
return GLFW_FALSE;
}
if (ctxconfig->major <= 2 ||
(ctxconfig->major == 3 && ctxconfig->minor < 2))
{
// Desktop OpenGL context profiles are only defined for version 3.2
// and above
_glfwInputError(GLFW_INVALID_VALUE,
"Context profiles are only defined for OpenGL version 3.2 and above");
return GLFW_FALSE;
}
}
if (ctxconfig->forward && ctxconfig->major <= 2)
{
// 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;
}
}
else if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
if (ctxconfig->major < 1 || ctxconfig->minor < 0 ||
(ctxconfig->major == 1 && ctxconfig->minor > 1) ||
(ctxconfig->major == 2 && ctxconfig->minor > 0))
{
// OpenGL ES 1.0 is the smallest valid version
// OpenGL ES 1.x series ended with version 1.1
// OpenGL ES 2.x series ended with version 2.0
// For now, let everything else through
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid OpenGL ES version %i.%i",
ctxconfig->major, ctxconfig->minor);
return GLFW_FALSE;
}
}
if (ctxconfig->robustness)
{
if (ctxconfig->robustness != GLFW_NO_RESET_NOTIFICATION &&
ctxconfig->robustness != GLFW_LOSE_CONTEXT_ON_RESET)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid context robustness mode 0x%08X",
ctxconfig->robustness);
return GLFW_FALSE;
}
}
if (ctxconfig->release)
{
if (ctxconfig->release != GLFW_RELEASE_BEHAVIOR_NONE &&
ctxconfig->release != GLFW_RELEASE_BEHAVIOR_FLUSH)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid context release behavior 0x%08X",
ctxconfig->release);
return GLFW_FALSE;
}
}
return GLFW_TRUE;
}
// Chooses the framebuffer config that best matches the desired one
//
const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
const _GLFWfbconfig* alternatives,
unsigned int count)
{
unsigned int i;
unsigned int missing, leastMissing = UINT_MAX;
unsigned int colorDiff, leastColorDiff = UINT_MAX;
unsigned int extraDiff, leastExtraDiff = UINT_MAX;
const _GLFWfbconfig* current;
const _GLFWfbconfig* closest = NULL;
for (i = 0; i < count; i++)
{
current = alternatives + i;
if (desired->stereo > 0 && current->stereo == 0)
{
// Stereo is a hard constraint
continue;
}
if (desired->doublebuffer != current->doublebuffer)
{
// Double buffering is a hard constraint
continue;
}
// Count number of missing buffers
{
missing = 0;
if (desired->alphaBits > 0 && current->alphaBits == 0)
missing++;
if (desired->depthBits > 0 && current->depthBits == 0)
missing++;
if (desired->stencilBits > 0 && current->stencilBits == 0)
missing++;
if (desired->auxBuffers > 0 &&
current->auxBuffers < desired->auxBuffers)
{
missing += desired->auxBuffers - current->auxBuffers;
}
if (desired->samples > 0 && current->samples == 0)
{
// Technically, several multisampling buffers could be
// involved, but that's a lower level implementation detail and
// not important to us here, so we count them as one
missing++;
}
if (desired->transparent != current->transparent)
missing++;
}
// These polynomials make many small channel size differences matter
// less than one large channel size difference
// Calculate color channel size difference value
{
colorDiff = 0;
if (desired->redBits != GLFW_DONT_CARE)
{
colorDiff += (desired->redBits - current->redBits) *
(desired->redBits - current->redBits);
}
if (desired->greenBits != GLFW_DONT_CARE)
{
colorDiff += (desired->greenBits - current->greenBits) *
(desired->greenBits - current->greenBits);
}
if (desired->blueBits != GLFW_DONT_CARE)
{
colorDiff += (desired->blueBits - current->blueBits) *
(desired->blueBits - current->blueBits);
}
}
// Calculate non-color channel size difference value
{
extraDiff = 0;
if (desired->alphaBits != GLFW_DONT_CARE)
{
extraDiff += (desired->alphaBits - current->alphaBits) *
(desired->alphaBits - current->alphaBits);
}
if (desired->depthBits != GLFW_DONT_CARE)
{
extraDiff += (desired->depthBits - current->depthBits) *
(desired->depthBits - current->depthBits);
}
if (desired->stencilBits != GLFW_DONT_CARE)
{
extraDiff += (desired->stencilBits - current->stencilBits) *
(desired->stencilBits - current->stencilBits);
}
if (desired->accumRedBits != GLFW_DONT_CARE)
{
extraDiff += (desired->accumRedBits - current->accumRedBits) *
(desired->accumRedBits - current->accumRedBits);
}
if (desired->accumGreenBits != GLFW_DONT_CARE)
{
extraDiff += (desired->accumGreenBits - current->accumGreenBits) *
(desired->accumGreenBits - current->accumGreenBits);
}
if (desired->accumBlueBits != GLFW_DONT_CARE)
{
extraDiff += (desired->accumBlueBits - current->accumBlueBits) *
(desired->accumBlueBits - current->accumBlueBits);
}
if (desired->accumAlphaBits != GLFW_DONT_CARE)
{
extraDiff += (desired->accumAlphaBits - current->accumAlphaBits) *
(desired->accumAlphaBits - current->accumAlphaBits);
}
if (desired->samples != GLFW_DONT_CARE)
{
extraDiff += (desired->samples - current->samples) *
(desired->samples - current->samples);
}
if (desired->sRGB && !current->sRGB)
extraDiff++;
}
// Figure out if the current one is better than the best one found so far
// Least number of missing buffers is the most important heuristic,
// then color buffer size match and lastly size match for other buffers
if (missing < leastMissing)
closest = current;
else if (missing == leastMissing)
{
if ((colorDiff < leastColorDiff) ||
(colorDiff == leastColorDiff && extraDiff < leastExtraDiff))
{
closest = current;
}
}
if (current == closest)
{
leastMissing = missing;
leastColorDiff = colorDiff;
leastExtraDiff = extraDiff;
}
}
return closest;
}
// Retrieves the attributes of the current context
//
GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig)
{
int i;
_GLFWwindow* previous;
const char* version;
const char* prefixes[] =
{
"OpenGL ES-CM ",
"OpenGL ES-CL ",
"OpenGL ES ",
NULL
};
window->context.source = ctxconfig->source;
window->context.client = GLFW_OPENGL_API;
previous = _glfwPlatformGetTls(&_glfw.contextSlot);;
glfwMakeContextCurrent((GLFWwindow*) window);
window->context.GetIntegerv = (PFNGLGETINTEGERVPROC)
window->context.getProcAddress("glGetIntegerv");
window->context.GetString = (PFNGLGETSTRINGPROC)
window->context.getProcAddress("glGetString");
if (!window->context.GetIntegerv || !window->context.GetString)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "Entry point retrieval is broken");
glfwMakeContextCurrent((GLFWwindow*) previous);
return GLFW_FALSE;
}
version = (const char*) window->context.GetString(GL_VERSION);
if (!version)
{
if (ctxconfig->client == GLFW_OPENGL_API)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"OpenGL version string retrieval is broken");
}
else
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"OpenGL ES version string retrieval is broken");
}
glfwMakeContextCurrent((GLFWwindow*) previous);
return GLFW_FALSE;
}
for (i = 0; prefixes[i]; i++)
{
const size_t length = strlen(prefixes[i]);
if (strncmp(version, prefixes[i], length) == 0)
{
version += length;
window->context.client = GLFW_OPENGL_ES_API;
break;
}
}
if (!sscanf(version, "%d.%d.%d",
&window->context.major,
&window->context.minor,
&window->context.revision))
{
if (window->context.client == GLFW_OPENGL_API)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"No version found in OpenGL version string");
}
else
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"No version found in OpenGL ES version string");
}
glfwMakeContextCurrent((GLFWwindow*) previous);
return GLFW_FALSE;
}
if (window->context.major < ctxconfig->major ||
(window->context.major == ctxconfig->major &&
window->context.minor < ctxconfig->minor))
{
// The desired OpenGL version is greater than the actual version
// This only happens if the machine lacks {GLX|WGL}_ARB_create_context
// /and/ the user has requested an OpenGL version greater than 1.0
// For API consistency, we emulate the behavior of the
// {GLX|WGL}_ARB_create_context extension and fail here
if (window->context.client == GLFW_OPENGL_API)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"Requested OpenGL version %i.%i, got version %i.%i",
ctxconfig->major, ctxconfig->minor,
window->context.major, window->context.minor);
}
else
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"Requested OpenGL ES version %i.%i, got version %i.%i",
ctxconfig->major, ctxconfig->minor,
window->context.major, window->context.minor);
}
glfwMakeContextCurrent((GLFWwindow*) previous);
return GLFW_FALSE;
}
if (window->context.major >= 3)
{
// OpenGL 3.0+ uses a different function for extension string retrieval
// We cache it here instead of in glfwExtensionSupported mostly to alert
// users as early as possible that their build may be broken
window->context.GetStringi = (PFNGLGETSTRINGIPROC)
window->context.getProcAddress("glGetStringi");
if (!window->context.GetStringi)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Entry point retrieval is broken");
glfwMakeContextCurrent((GLFWwindow*) previous);
return GLFW_FALSE;
}
}
if (window->context.client == GLFW_OPENGL_API)
{
// Read back context flags (OpenGL 3.0 and above)
if (window->context.major >= 3)
{
GLint flags;
window->context.GetIntegerv(GL_CONTEXT_FLAGS, &flags);
if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
window->context.forward = GLFW_TRUE;
if (flags & GL_CONTEXT_FLAG_DEBUG_BIT)
window->context.debug = GLFW_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;
}
if (flags & GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR)
window->context.noerror = GLFW_TRUE;
}
// Read back OpenGL context profile (OpenGL 3.2 and above)
if (window->context.major >= 4 ||
(window->context.major == 3 && window->context.minor >= 2))
{
GLint mask;
window->context.GetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask);
if (mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
window->context.profile = GLFW_OPENGL_COMPAT_PROFILE;
else if (mask & GL_CONTEXT_CORE_PROFILE_BIT)
window->context.profile = GLFW_OPENGL_CORE_PROFILE;
else if (glfwExtensionSupported("GL_ARB_compatibility"))
{
// HACK: This is a workaround for the compatibility profile bit
// not being set in the context flags if an OpenGL 3.2+
// context was created without having requested a specific
// version
window->context.profile = GLFW_OPENGL_COMPAT_PROFILE;
}
}
// Read back robustness strategy
if (glfwExtensionSupported("GL_ARB_robustness"))
{
// NOTE: We avoid using the context flags for detection, as they are
// only present from 3.0 while the extension applies from 1.1
GLint strategy;
window->context.GetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB,
&strategy);
if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB)
window->context.robustness = GLFW_LOSE_CONTEXT_ON_RESET;
else if (strategy == GL_NO_RESET_NOTIFICATION_ARB)
window->context.robustness = GLFW_NO_RESET_NOTIFICATION;
}
}
else
{
// Read back robustness strategy
if (glfwExtensionSupported("GL_EXT_robustness"))
{
// NOTE: The values of these constants match those of the OpenGL ARB
// one, so we can reuse them here
GLint strategy;
window->context.GetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB,
&strategy);
if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB)
window->context.robustness = GLFW_LOSE_CONTEXT_ON_RESET;
else if (strategy == GL_NO_RESET_NOTIFICATION_ARB)
window->context.robustness = GLFW_NO_RESET_NOTIFICATION;
}
}
if (glfwExtensionSupported("GL_KHR_context_flush_control"))
{
GLint behavior;
window->context.GetIntegerv(GL_CONTEXT_RELEASE_BEHAVIOR, &behavior);
if (behavior == GL_NONE)
window->context.release = GLFW_RELEASE_BEHAVIOR_NONE;
else if (behavior == GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH)
window->context.release = GLFW_RELEASE_BEHAVIOR_FLUSH;
}
// Clearing the front buffer to black to avoid garbage pixels left over from
// previous uses of our bit of VRAM
{
PFNGLCLEARPROC glClear = (PFNGLCLEARPROC)
window->context.getProcAddress("glClear");
glClear(GL_COLOR_BUFFER_BIT);
window->context.swapBuffers(window);
}
glfwMakeContextCurrent((GLFWwindow*) previous);
return GLFW_TRUE;
}
// Searches an extension string for the specified extension
//
GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions)
{
const char* start = extensions;
for (;;)
{
const char* where;
const char* terminator;
where = strstr(start, string);
if (!where)
return GLFW_FALSE;
terminator = where + strlen(string);
if (where == start || *(where - 1) == ' ')
{
if (*terminator == ' ' || *terminator == '\0')
break;
}
start = terminator;
}
return GLFW_TRUE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFWwindow* previous = _glfwPlatformGetTls(&_glfw.contextSlot);
_GLFW_REQUIRE_INIT();
if (window && window->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT,
"Cannot make current with a window that has no OpenGL or OpenGL ES context");
return;
}
if (previous)
{
if (!window || window->context.source != previous->context.source)
previous->context.makeCurrent(NULL);
}
if (window)
window->context.makeCurrent(window);
}
GLFWAPI GLFWwindow* glfwGetCurrentContext(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return _glfwPlatformGetTls(&_glfw.contextSlot);
}
GLFWAPI void glfwSwapBuffers(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
if (window->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT,
"Cannot swap buffers of a window that has no OpenGL or OpenGL ES context");
return;
}
window->context.swapBuffers(window);
}
GLFWAPI void glfwSwapInterval(int interval)
{
_GLFWwindow* window;
_GLFW_REQUIRE_INIT();
window = _glfwPlatformGetTls(&_glfw.contextSlot);
if (!window)
{
_glfwInputError(GLFW_NO_CURRENT_CONTEXT,
"Cannot set swap interval without a current OpenGL or OpenGL ES context");
return;
}
window->context.swapInterval(interval);
}
GLFWAPI int glfwExtensionSupported(const char* extension)
{
_GLFWwindow* window;
assert(extension != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_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;
}
if (*extension == '\0')
{
_glfwInputError(GLFW_INVALID_VALUE, "Extension name cannot be an empty string");
return GLFW_FALSE;
}
if (window->context.major >= 3)
{
int i;
GLint count;
// Check if extension is in the modern OpenGL extensions string list
window->context.GetIntegerv(GL_NUM_EXTENSIONS, &count);
for (i = 0; i < count; i++)
{
const char* en = (const char*)
window->context.GetStringi(GL_EXTENSIONS, i);
if (!en)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Extension string retrieval is broken");
return GLFW_FALSE;
}
if (strcmp(en, extension) == 0)
return GLFW_TRUE;
}
}
else
{
// Check if extension is in the old style OpenGL extensions string
const char* extensions = (const char*)
window->context.GetString(GL_EXTENSIONS);
if (!extensions)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Extension string retrieval is broken");
return GLFW_FALSE;
}
if (_glfwStringInExtensionString(extension, extensions))
return GLFW_TRUE;
}
// Check if extension is in the platform-specific string
return window->context.extensionSupported(extension);
}
GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
{
_GLFWwindow* window;
assert(procname != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
window = _glfwPlatformGetTls(&_glfw.contextSlot);
if (!window)
{
_glfwInputError(GLFW_NO_CURRENT_CONTEXT,
"Cannot query entry point without a current OpenGL or OpenGL ES context");
return NULL;
}
return window->context.getProcAddress(procname);
}

295
glfw/dbus_glfw.c vendored Normal file
View File

@@ -0,0 +1,295 @@
//========================================================================
// GLFW 3.3 XKB - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2018 Kovid Goyal <kovid@kovidgoyal.net>
//
// 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 "dbus_glfw.h"
#include <stdlib.h>
#include <string.h>
static inline void
report_error(DBusError *err, const char *fmt, ...) {
static char buf[1024];
va_list args;
va_start(args, fmt);
int n = vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
snprintf(buf + n, sizeof(buf), ". DBUS error: %s", err->message);
_glfwInputError(GLFW_PLATFORM_ERROR, "%s", buf);
dbus_error_free(err);
}
static _GLFWDBUSData *dbus_data = NULL;
GLFWbool
glfw_dbus_init(_GLFWDBUSData *dbus, EventLoopData *eld) {
dbus->eld = eld;
dbus_data = dbus;
return GLFW_TRUE;
}
static void
on_dbus_watch_ready(int fd, int events, void *data) {
DBusWatch *watch = (DBusWatch*)data;
unsigned int flags = 0;
if (events & POLLERR) flags |= DBUS_WATCH_ERROR;
if (events & POLLHUP) flags |= DBUS_WATCH_HANGUP;
if (events & POLLIN) flags |= DBUS_WATCH_READABLE;
if (events & POLLOUT) flags |= DBUS_WATCH_WRITABLE;
dbus_watch_handle(watch, flags);
}
static inline int
events_for_watch(DBusWatch *watch) {
int events = 0;
unsigned int flags = dbus_watch_get_flags(watch);
if (flags & DBUS_WATCH_READABLE) events |= POLLIN;
if (flags & DBUS_WATCH_WRITABLE) events |= POLLOUT;
return events;
}
static dbus_bool_t
add_dbus_watch(DBusWatch *watch, void *data) {
id_type watch_id = addWatch(dbus_data->eld, data, dbus_watch_get_unix_fd(watch), events_for_watch(watch), dbus_watch_get_enabled(watch), on_dbus_watch_ready, watch);
if (!watch_id) return FALSE;
id_type *idp = malloc(sizeof(id_type));
if (!idp) return FALSE;
*idp = watch_id;
dbus_watch_set_data(watch, idp, free);
return TRUE;
}
static void
remove_dbus_watch(DBusWatch *watch, void *data) {
id_type *idp = dbus_watch_get_data(watch);
if (idp) removeWatch(dbus_data->eld, *idp);
}
static void
toggle_dbus_watch(DBusWatch *watch, void *data) {
id_type *idp = dbus_watch_get_data(watch);
if (idp) toggleWatch(dbus_data->eld, *idp, dbus_watch_get_enabled(watch));
}
static void
on_dbus_timer_ready(id_type timer_id, void *data) {
if (data) {
DBusTimeout *t = (DBusTimeout*)data;
dbus_timeout_handle(t);
}
}
static dbus_bool_t
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);
if (!timer_id) return FALSE;
id_type *idp = malloc(sizeof(id_type));
if (!idp) {
removeTimer(dbus_data->eld, timer_id);
return FALSE;
}
*idp = timer_id;
dbus_timeout_set_data(timeout, idp, free);
return TRUE;
}
static void
remove_dbus_timeout(DBusTimeout *timeout, void *data) {
id_type *idp = dbus_timeout_get_data(timeout);
if (idp) removeTimer(dbus_data->eld, *idp);
}
static void
toggle_dbus_timeout(DBusTimeout *timeout, void *data) {
id_type *idp = dbus_timeout_get_data(timeout);
if (idp) toggleTimer(dbus_data->eld, *idp, dbus_timeout_get_enabled(timeout));
}
DBusConnection*
glfw_dbus_connect_to(const char *path, const char* err_msg, const char *name, GLFWbool register_on_bus) {
DBusError err;
dbus_error_init(&err);
DBusConnection *ans = dbus_connection_open_private(path, &err);
if (!ans) {
report_error(&err, err_msg);
return NULL;
}
dbus_connection_set_exit_on_disconnect(ans, FALSE);
dbus_error_free(&err);
if (register_on_bus) {
if (!dbus_bus_register(ans, &err)) {
report_error(&err, err_msg);
return NULL;
}
}
if (!dbus_connection_set_watch_functions(ans, 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", path);
dbus_connection_close(ans);
dbus_connection_unref(ans);
return NULL;
}
if (!dbus_connection_set_timeout_functions(ans, 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", path);
dbus_connection_close(ans);
dbus_connection_unref(ans);
return NULL;
}
return ans;
}
void
glfw_dbus_dispatch(DBusConnection *conn) {
while(dbus_connection_dispatch(conn) == DBUS_DISPATCH_DATA_REMAINS);
}
void
glfw_dbus_terminate(_GLFWDBUSData *dbus) {
if (dbus_data) {
dbus_data->eld = NULL;
dbus_data = NULL;
}
}
void
glfw_dbus_close_connection(DBusConnection *conn) {
dbus_connection_close(conn);
dbus_connection_unref(conn);
}
GLFWbool
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;
va_end(ap);
if (!ret) report_error(&err, failmsg);
return ret;
}
typedef struct {
dbus_pending_callback callback;
void *user_data;
} MethodResponse;
static const char*
format_message_error(DBusError *err) {
static char buf[1024];
snprintf(buf, sizeof(buf), "[%s] %s", err->name ? err->name : "", err->message);
return buf;
}
static void
method_reply_received(DBusPendingCall *pending, void *user_data) {
MethodResponse *res = (MethodResponse*)user_data;
DBusMessage *msg = dbus_pending_call_steal_reply(pending);
if (msg) {
DBusError err;
dbus_error_init(&err);
if (dbus_set_error_from_message(&err, msg)) res->callback(NULL, format_message_error(&err), res->user_data);
else res->callback(msg, NULL, res->user_data);
dbus_message_unref(msg);
}
}
static GLFWbool
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;
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;
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);
}
}
} else {
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to call DBUS method: %s on node: %s and interface: %s could not add arguments", method, node, interface);
}
dbus_message_unref(msg);
return retval;
}
GLFWbool
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;
va_list ap;
va_start(ap, user_data);
retval = call_method(conn, node, path, interface, method, timeout, callback, user_data, ap);
va_end(ap);
return retval;
}
GLFWbool
glfw_dbus_call_method_no_reply(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...) {
GLFWbool retval;
va_list ap;
va_start(ap, method);
retval = call_method(conn, node, path, interface, method, DBUS_TIMEOUT_USE_DEFAULT, NULL, NULL, ap);
va_end(ap);
return retval;
}
int
glfw_dbus_match_signal(DBusMessage *msg, const char *interface, ...) {
va_list ap;
va_start(ap, interface);
int ans = -1, num = -1;
while(1) {
num++;
const char *name = va_arg(ap, const char*);
if (!name) break;
if (dbus_message_is_signal(msg, interface, name)) { ans = num; break; }
}
va_end(ap);
return ans;
}

50
glfw/dbus_glfw.h vendored Normal file
View File

@@ -0,0 +1,50 @@
//========================================================================
// GLFW 3.3 XKB - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2018 Kovid Goyal <kovid@kovidgoyal.net>
//
// 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.
//
//========================================================================
#pragma once
#include <dbus/dbus.h>
#include "backend_utils.h"
typedef void(*dbus_pending_callback)(DBusMessage *msg, const char* err, void* data);
typedef struct {
EventLoopData* eld;
} _GLFWDBUSData;
GLFWbool 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);
void glfw_dbus_close_connection(DBusConnection *conn);
GLFWbool
glfw_dbus_call_method_no_reply(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...);
GLFWbool
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, ...);
int glfw_dbus_match_signal(DBusMessage *msg, const char *interface, ...);

786
glfw/egl_context.c vendored Normal file
View File

@@ -0,0 +1,786 @@
//========================================================================
// GLFW 3.3 EGL - 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 <string.h>
#include <stdlib.h>
#include <assert.h>
// Return a description of the specified EGL error
//
static const char* getEGLErrorString(EGLint error)
{
switch (error)
{
case EGL_SUCCESS:
return "Success";
case EGL_NOT_INITIALIZED:
return "EGL is not or could not be initialized";
case EGL_BAD_ACCESS:
return "EGL cannot access a requested resource";
case EGL_BAD_ALLOC:
return "EGL failed to allocate resources for the requested operation";
case EGL_BAD_ATTRIBUTE:
return "An unrecognized attribute or attribute value was passed in the attribute list";
case EGL_BAD_CONTEXT:
return "An EGLContext argument does not name a valid EGL rendering context";
case EGL_BAD_CONFIG:
return "An EGLConfig argument does not name a valid EGL frame buffer configuration";
case EGL_BAD_CURRENT_SURFACE:
return "The current surface of the calling thread is a window, pixel buffer or pixmap that is no longer valid";
case EGL_BAD_DISPLAY:
return "An EGLDisplay argument does not name a valid EGL display connection";
case EGL_BAD_SURFACE:
return "An EGLSurface argument does not name a valid surface configured for GL rendering";
case EGL_BAD_MATCH:
return "Arguments are inconsistent";
case EGL_BAD_PARAMETER:
return "One or more argument values are invalid";
case EGL_BAD_NATIVE_PIXMAP:
return "A NativePixmapType argument does not refer to a valid native pixmap";
case EGL_BAD_NATIVE_WINDOW:
return "A NativeWindowType argument does not refer to a valid native window";
case EGL_CONTEXT_LOST:
return "The application must destroy all contexts and reinitialise";
default:
return "ERROR: UNKNOWN EGL ERROR";
}
}
// Returns the specified attribute of the specified EGLConfig
//
static int getEGLConfigAttrib(EGLConfig config, int attrib)
{
int value;
eglGetConfigAttrib(_glfw.egl.display, config, attrib, &value);
return value;
}
// Return the EGLConfig most closely matching the specified hints
//
static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* desired,
EGLConfig* result)
{
EGLConfig* nativeConfigs;
_GLFWfbconfig* usableConfigs;
const _GLFWfbconfig* closest;
int i, nativeCount, usableCount;
eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount);
if (!nativeCount)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: No EGLConfigs returned");
return GLFW_FALSE;
}
nativeConfigs = calloc(nativeCount, sizeof(EGLConfig));
eglGetConfigs(_glfw.egl.display, nativeConfigs, nativeCount, &nativeCount);
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
usableCount = 0;
for (i = 0; i < nativeCount; i++)
{
const EGLConfig n = nativeConfigs[i];
_GLFWfbconfig* u = usableConfigs + usableCount;
// Only consider RGB(A) EGLConfigs
if (getEGLConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) != EGL_RGB_BUFFER)
continue;
// Only consider window EGLConfigs
if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT))
continue;
#if defined(_GLFW_X11)
XVisualInfo vi = {0};
// Only consider EGLConfigs with associated Visuals
vi.visualid = getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID);
if (!vi.visualid)
continue;
if (desired->transparent)
{
int count;
XVisualInfo* vis = XGetVisualInfo(_glfw.x11.display,
VisualIDMask, &vi,
&count);
if (vis)
{
u->transparent = _glfwIsVisualTransparentX11(vis[0].visual);
XFree(vis);
}
}
#endif // _GLFW_X11
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
if (ctxconfig->major == 1)
{
if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES_BIT))
continue;
}
else
{
if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT))
continue;
}
}
else if (ctxconfig->client == GLFW_OPENGL_API)
{
if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_BIT))
continue;
}
u->redBits = getEGLConfigAttrib(n, EGL_RED_SIZE);
u->greenBits = getEGLConfigAttrib(n, EGL_GREEN_SIZE);
u->blueBits = getEGLConfigAttrib(n, EGL_BLUE_SIZE);
u->alphaBits = getEGLConfigAttrib(n, EGL_ALPHA_SIZE);
u->depthBits = getEGLConfigAttrib(n, EGL_DEPTH_SIZE);
u->stencilBits = getEGLConfigAttrib(n, EGL_STENCIL_SIZE);
u->samples = getEGLConfigAttrib(n, EGL_SAMPLES);
u->doublebuffer = GLFW_TRUE;
u->handle = (uintptr_t) n;
usableCount++;
}
closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);
if (closest)
*result = (EGLConfig) closest->handle;
free(nativeConfigs);
free(usableConfigs);
return closest != NULL;
}
static void makeContextCurrentEGL(_GLFWwindow* window)
{
if (window)
{
if (!eglMakeCurrent(_glfw.egl.display,
window->context.egl.surface,
window->context.egl.surface,
window->context.egl.handle))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGL: Failed to make context current: %s",
getEGLErrorString(eglGetError()));
return;
}
}
else
{
if (!eglMakeCurrent(_glfw.egl.display,
EGL_NO_SURFACE,
EGL_NO_SURFACE,
EGL_NO_CONTEXT))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGL: Failed to clear current context: %s",
getEGLErrorString(eglGetError()));
return;
}
}
_glfwPlatformSetTls(&_glfw.contextSlot, window);
}
static void swapBuffersEGL(_GLFWwindow* window)
{
if (window != _glfwPlatformGetTls(&_glfw.contextSlot))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGL: The context must be current on the calling thread when swapping buffers");
return;
}
eglSwapBuffers(_glfw.egl.display, window->context.egl.surface);
}
static void swapIntervalEGL(int interval)
{
eglSwapInterval(_glfw.egl.display, interval);
}
static int extensionSupportedEGL(const char* extension)
{
const char* extensions = eglQueryString(_glfw.egl.display, EGL_EXTENSIONS);
if (extensions)
{
if (_glfwStringInExtensionString(extension, extensions))
return GLFW_TRUE;
}
return GLFW_FALSE;
}
static GLFWglproc getProcAddressEGL(const char* procname)
{
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
if (window->context.egl.client)
{
GLFWglproc proc = (GLFWglproc) _glfw_dlsym(window->context.egl.client,
procname);
if (proc)
return proc;
}
return eglGetProcAddress(procname);
}
static void destroyContextEGL(_GLFWwindow* window)
{
#if defined(_GLFW_X11)
// NOTE: Do not unload libGL.so.1 while the X11 display is still open,
// as it will make XCloseDisplay segfault
if (window->context.client != GLFW_OPENGL_API)
#endif // _GLFW_X11
{
if (window->context.egl.client)
{
_glfw_dlclose(window->context.egl.client);
window->context.egl.client = NULL;
}
}
if (window->context.egl.surface)
{
eglDestroySurface(_glfw.egl.display, window->context.egl.surface);
window->context.egl.surface = EGL_NO_SURFACE;
}
if (window->context.egl.handle)
{
eglDestroyContext(_glfw.egl.display, window->context.egl.handle);
window->context.egl.handle = EGL_NO_CONTEXT;
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Initialize EGL
//
GLFWbool _glfwInitEGL(void)
{
int i;
const char* sonames[] =
{
#if defined(_GLFW_EGL_LIBRARY)
_GLFW_EGL_LIBRARY,
#elif defined(_GLFW_WIN32)
"libEGL.dll",
"EGL.dll",
#elif defined(_GLFW_COCOA)
"libEGL.dylib",
#elif defined(__CYGWIN__)
"libEGL-1.so",
#else
"libEGL.so.1",
#endif
NULL
};
if (_glfw.egl.handle)
return GLFW_TRUE;
for (i = 0; sonames[i]; i++)
{
_glfw.egl.handle = _glfw_dlopen(sonames[i]);
if (_glfw.egl.handle)
break;
}
if (!_glfw.egl.handle)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: Library not found");
return GLFW_FALSE;
}
_glfw.egl.prefix = (strncmp(sonames[i], "lib", 3) == 0);
_glfw.egl.GetConfigAttrib = (PFN_eglGetConfigAttrib)
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigAttrib");
_glfw.egl.GetConfigs = (PFN_eglGetConfigs)
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigs");
_glfw.egl.GetDisplay = (PFN_eglGetDisplay)
_glfw_dlsym(_glfw.egl.handle, "eglGetDisplay");
_glfw.egl.GetError = (PFN_eglGetError)
_glfw_dlsym(_glfw.egl.handle, "eglGetError");
_glfw.egl.Initialize = (PFN_eglInitialize)
_glfw_dlsym(_glfw.egl.handle, "eglInitialize");
_glfw.egl.Terminate = (PFN_eglTerminate)
_glfw_dlsym(_glfw.egl.handle, "eglTerminate");
_glfw.egl.BindAPI = (PFN_eglBindAPI)
_glfw_dlsym(_glfw.egl.handle, "eglBindAPI");
_glfw.egl.CreateContext = (PFN_eglCreateContext)
_glfw_dlsym(_glfw.egl.handle, "eglCreateContext");
_glfw.egl.DestroySurface = (PFN_eglDestroySurface)
_glfw_dlsym(_glfw.egl.handle, "eglDestroySurface");
_glfw.egl.DestroyContext = (PFN_eglDestroyContext)
_glfw_dlsym(_glfw.egl.handle, "eglDestroyContext");
_glfw.egl.CreateWindowSurface = (PFN_eglCreateWindowSurface)
_glfw_dlsym(_glfw.egl.handle, "eglCreateWindowSurface");
_glfw.egl.MakeCurrent = (PFN_eglMakeCurrent)
_glfw_dlsym(_glfw.egl.handle, "eglMakeCurrent");
_glfw.egl.SwapBuffers = (PFN_eglSwapBuffers)
_glfw_dlsym(_glfw.egl.handle, "eglSwapBuffers");
_glfw.egl.SwapInterval = (PFN_eglSwapInterval)
_glfw_dlsym(_glfw.egl.handle, "eglSwapInterval");
_glfw.egl.QueryString = (PFN_eglQueryString)
_glfw_dlsym(_glfw.egl.handle, "eglQueryString");
_glfw.egl.GetProcAddress = (PFN_eglGetProcAddress)
_glfw_dlsym(_glfw.egl.handle, "eglGetProcAddress");
if (!_glfw.egl.GetConfigAttrib ||
!_glfw.egl.GetConfigs ||
!_glfw.egl.GetDisplay ||
!_glfw.egl.GetError ||
!_glfw.egl.Initialize ||
!_glfw.egl.Terminate ||
!_glfw.egl.BindAPI ||
!_glfw.egl.CreateContext ||
!_glfw.egl.DestroySurface ||
!_glfw.egl.DestroyContext ||
!_glfw.egl.CreateWindowSurface ||
!_glfw.egl.MakeCurrent ||
!_glfw.egl.SwapBuffers ||
!_glfw.egl.SwapInterval ||
!_glfw.egl.QueryString ||
!_glfw.egl.GetProcAddress)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGL: Failed to load required entry points");
_glfwTerminateEGL();
return GLFW_FALSE;
}
_glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY);
if (_glfw.egl.display == EGL_NO_DISPLAY)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to get EGL display: %s",
getEGLErrorString(eglGetError()));
_glfwTerminateEGL();
return GLFW_FALSE;
}
if (!eglInitialize(_glfw.egl.display, &_glfw.egl.major, &_glfw.egl.minor))
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to initialize EGL: %s",
getEGLErrorString(eglGetError()));
_glfwTerminateEGL();
return GLFW_FALSE;
}
_glfw.egl.KHR_create_context =
extensionSupportedEGL("EGL_KHR_create_context");
_glfw.egl.KHR_create_context_no_error =
extensionSupportedEGL("EGL_KHR_create_context_no_error");
_glfw.egl.KHR_gl_colorspace =
extensionSupportedEGL("EGL_KHR_gl_colorspace");
_glfw.egl.KHR_get_all_proc_addresses =
extensionSupportedEGL("EGL_KHR_get_all_proc_addresses");
_glfw.egl.KHR_context_flush_control =
extensionSupportedEGL("EGL_KHR_context_flush_control");
return GLFW_TRUE;
}
// Terminate EGL
//
void _glfwTerminateEGL(void)
{
if (_glfw.egl.display)
{
eglTerminate(_glfw.egl.display);
_glfw.egl.display = EGL_NO_DISPLAY;
}
if (_glfw.egl.handle)
{
_glfw_dlclose(_glfw.egl.handle);
_glfw.egl.handle = NULL;
}
}
#define setAttrib(a, v) \
{ \
assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \
attribs[index++] = v; \
}
// Create the OpenGL or OpenGL ES context
//
GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
EGLint attribs[40];
EGLConfig config;
EGLContext share = NULL;
int index = 0;
if (!_glfw.egl.display)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: API not available");
return GLFW_FALSE;
}
if (ctxconfig->share)
share = ctxconfig->share->context.egl.handle;
if (!chooseEGLConfig(ctxconfig, fbconfig, &config))
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"EGL: Failed to find a suitable EGLConfig");
return GLFW_FALSE;
}
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
if (!eglBindAPI(EGL_OPENGL_ES_API))
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to bind OpenGL ES: %s",
getEGLErrorString(eglGetError()));
return GLFW_FALSE;
}
}
else
{
if (!eglBindAPI(EGL_OPENGL_API))
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to bind OpenGL: %s",
getEGLErrorString(eglGetError()));
return GLFW_FALSE;
}
}
if (_glfw.egl.KHR_create_context)
{
int mask = 0, flags = 0;
if (ctxconfig->client == GLFW_OPENGL_API)
{
if (ctxconfig->forward)
flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
mask |= EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
mask |= EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR;
}
if (ctxconfig->debug)
flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
if (ctxconfig->robustness)
{
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
{
setAttrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
EGL_NO_RESET_NOTIFICATION_KHR);
}
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
{
setAttrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
EGL_LOSE_CONTEXT_ON_RESET_KHR);
}
flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
}
if (ctxconfig->noerror)
{
if (_glfw.egl.KHR_create_context_no_error)
setAttrib(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE);
}
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
{
setAttrib(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major);
setAttrib(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor);
}
if (mask)
setAttrib(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask);
if (flags)
setAttrib(EGL_CONTEXT_FLAGS_KHR, flags);
}
else
{
if (ctxconfig->client == GLFW_OPENGL_ES_API)
setAttrib(EGL_CONTEXT_CLIENT_VERSION, ctxconfig->major);
}
if (_glfw.egl.KHR_context_flush_control)
{
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
{
setAttrib(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR);
}
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
{
setAttrib(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR);
}
}
setAttrib(EGL_NONE, EGL_NONE);
window->context.egl.handle = eglCreateContext(_glfw.egl.display,
config, share, attribs);
if (window->context.egl.handle == EGL_NO_CONTEXT)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"EGL: Failed to create context: %s",
getEGLErrorString(eglGetError()));
return GLFW_FALSE;
}
// Set up attributes for surface creation
{
int index = 0;
if (fbconfig->sRGB)
{
if (_glfw.egl.KHR_gl_colorspace)
setAttrib(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR);
}
setAttrib(EGL_NONE, EGL_NONE);
}
window->context.egl.surface =
eglCreateWindowSurface(_glfw.egl.display,
config,
_GLFW_EGL_NATIVE_WINDOW,
attribs);
if (window->context.egl.surface == EGL_NO_SURFACE)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGL: Failed to create window surface: %s",
getEGLErrorString(eglGetError()));
return GLFW_FALSE;
}
window->context.egl.config = config;
// Load the appropriate client library
if (!_glfw.egl.KHR_get_all_proc_addresses)
{
int i;
const char** sonames;
const char* es1sonames[] =
{
#if defined(_GLFW_GLESV1_LIBRARY)
_GLFW_GLESV1_LIBRARY,
#elif defined(_GLFW_WIN32)
"GLESv1_CM.dll",
"libGLES_CM.dll",
#elif defined(_GLFW_COCOA)
"libGLESv1_CM.dylib",
#else
"libGLESv1_CM.so.1",
"libGLES_CM.so.1",
#endif
NULL
};
const char* es2sonames[] =
{
#if defined(_GLFW_GLESV2_LIBRARY)
_GLFW_GLESV2_LIBRARY,
#elif defined(_GLFW_WIN32)
"GLESv2.dll",
"libGLESv2.dll",
#elif defined(_GLFW_COCOA)
"libGLESv2.dylib",
#elif defined(__CYGWIN__)
"libGLESv2-2.so",
#else
"libGLESv2.so.2",
#endif
NULL
};
const char* glsonames[] =
{
#if defined(_GLFW_OPENGL_LIBRARY)
_GLFW_OPENGL_LIBRARY,
#elif defined(_GLFW_WIN32)
#elif defined(_GLFW_COCOA)
#else
"libGL.so.1",
#endif
NULL
};
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
if (ctxconfig->major == 1)
sonames = es1sonames;
else
sonames = es2sonames;
}
else
sonames = glsonames;
for (i = 0; sonames[i]; i++)
{
// HACK: Match presence of lib prefix to increase chance of finding
// a matching pair in the jungle that is Win32 EGL/GLES
if (_glfw.egl.prefix != (strncmp(sonames[i], "lib", 3) == 0))
continue;
window->context.egl.client = _glfw_dlopen(sonames[i]);
if (window->context.egl.client)
break;
}
if (!window->context.egl.client)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to load client library");
return GLFW_FALSE;
}
}
window->context.makeCurrent = makeContextCurrentEGL;
window->context.swapBuffers = swapBuffersEGL;
window->context.swapInterval = swapIntervalEGL;
window->context.extensionSupported = extensionSupportedEGL;
window->context.getProcAddress = getProcAddressEGL;
window->context.destroy = destroyContextEGL;
return GLFW_TRUE;
}
#undef setAttrib
// Returns the Visual and depth of the chosen EGLConfig
//
#if defined(_GLFW_X11)
GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth)
{
XVisualInfo* result;
XVisualInfo desired;
EGLConfig native;
EGLint visualID = 0, count = 0;
const long vimask = VisualScreenMask | VisualIDMask;
if (!chooseEGLConfig(ctxconfig, fbconfig, &native))
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"EGL: Failed to find a suitable EGLConfig");
return GLFW_FALSE;
}
eglGetConfigAttrib(_glfw.egl.display, native,
EGL_NATIVE_VISUAL_ID, &visualID);
desired.screen = _glfw.x11.screen;
desired.visualid = visualID;
result = XGetVisualInfo(_glfw.x11.display, vimask, &desired, &count);
if (!result)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGL: Failed to retrieve Visual for EGLConfig");
return GLFW_FALSE;
}
*visual = result->visual;
*depth = result->depth;
XFree(result);
return GLFW_TRUE;
}
#endif // _GLFW_X11
//////////////////////////////////////////////////////////////////////////
////// GLFW native API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI EGLDisplay glfwGetEGLDisplay(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_DISPLAY);
return _glfw.egl.display;
}
GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_CONTEXT);
if (window->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return EGL_NO_CONTEXT;
}
return window->context.egl.handle;
}
GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_SURFACE);
if (window->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return EGL_NO_SURFACE;
}
return window->context.egl.surface;
}

214
glfw/egl_context.h vendored Normal file
View File

@@ -0,0 +1,214 @@
//========================================================================
// GLFW 3.3 EGL - 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.
//
//========================================================================
#if defined(_GLFW_USE_EGLPLATFORM_H)
#include <EGL/eglplatform.h>
#elif defined(_GLFW_WIN32)
#define EGLAPIENTRY __stdcall
typedef HDC EGLNativeDisplayType;
typedef HWND EGLNativeWindowType;
#elif defined(_GLFW_COCOA)
#define EGLAPIENTRY
typedef void* EGLNativeDisplayType;
typedef id EGLNativeWindowType;
#elif defined(_GLFW_X11)
#define EGLAPIENTRY
typedef Display* EGLNativeDisplayType;
typedef Window EGLNativeWindowType;
#elif defined(_GLFW_WAYLAND)
#define EGLAPIENTRY
typedef struct wl_display* EGLNativeDisplayType;
typedef struct wl_egl_window* EGLNativeWindowType;
#else
#error "No supported EGL platform selected"
#endif
#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_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_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_OPENGL_ES_BIT 0x0001
#define EGL_OPENGL_ES2_BIT 0x0004
#define EGL_OPENGL_BIT 0x0008
#define EGL_ALPHA_SIZE 0x3021
#define EGL_BLUE_SIZE 0x3022
#define EGL_GREEN_SIZE 0x3023
#define EGL_RED_SIZE 0x3024
#define EGL_DEPTH_SIZE 0x3025
#define EGL_STENCIL_SIZE 0x3026
#define EGL_SAMPLES 0x3031
#define EGL_OPENGL_ES_API 0x30a0
#define EGL_OPENGL_API 0x30a2
#define EGL_NONE 0x3038
#define EGL_EXTENSIONS 0x3055
#define EGL_CONTEXT_CLIENT_VERSION 0x3098
#define EGL_NATIVE_VISUAL_ID 0x302e
#define EGL_NO_SURFACE ((EGLSurface) 0)
#define EGL_NO_DISPLAY ((EGLDisplay) 0)
#define EGL_NO_CONTEXT ((EGLContext) 0)
#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType) 0)
#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001
#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31bd
#define EGL_NO_RESET_NOTIFICATION_KHR 0x31be
#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31bf
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004
#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098
#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30fb
#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30fd
#define EGL_CONTEXT_FLAGS_KHR 0x30fc
#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31b3
#define EGL_GL_COLORSPACE_KHR 0x309d
#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089
#define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097
#define EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR 0
#define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098
typedef int EGLint;
typedef unsigned int EGLBoolean;
typedef unsigned int EGLenum;
typedef void* EGLConfig;
typedef void* EGLContext;
typedef void* EGLDisplay;
typedef void* EGLSurface;
// EGL function pointer typedefs
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigAttrib)(EGLDisplay,EGLConfig,EGLint,EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigs)(EGLDisplay,EGLConfig*,EGLint,EGLint*);
typedef EGLDisplay (EGLAPIENTRY * PFN_eglGetDisplay)(EGLNativeDisplayType);
typedef EGLint (EGLAPIENTRY * PFN_eglGetError)(void);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglInitialize)(EGLDisplay,EGLint*,EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglTerminate)(EGLDisplay);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglBindAPI)(EGLenum);
typedef EGLContext (EGLAPIENTRY * PFN_eglCreateContext)(EGLDisplay,EGLConfig,EGLContext,const EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglDestroySurface)(EGLDisplay,EGLSurface);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglDestroyContext)(EGLDisplay,EGLContext);
typedef EGLSurface (EGLAPIENTRY * PFN_eglCreateWindowSurface)(EGLDisplay,EGLConfig,EGLNativeWindowType,const EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglMakeCurrent)(EGLDisplay,EGLSurface,EGLSurface,EGLContext);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapBuffers)(EGLDisplay,EGLSurface);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapInterval)(EGLDisplay,EGLint);
typedef const char* (EGLAPIENTRY * PFN_eglQueryString)(EGLDisplay,EGLint);
typedef GLFWglproc (EGLAPIENTRY * PFN_eglGetProcAddress)(const char*);
#define eglGetConfigAttrib _glfw.egl.GetConfigAttrib
#define eglGetConfigs _glfw.egl.GetConfigs
#define eglGetDisplay _glfw.egl.GetDisplay
#define eglGetError _glfw.egl.GetError
#define eglInitialize _glfw.egl.Initialize
#define eglTerminate _glfw.egl.Terminate
#define eglBindAPI _glfw.egl.BindAPI
#define eglCreateContext _glfw.egl.CreateContext
#define eglDestroySurface _glfw.egl.DestroySurface
#define eglDestroyContext _glfw.egl.DestroyContext
#define eglCreateWindowSurface _glfw.egl.CreateWindowSurface
#define eglMakeCurrent _glfw.egl.MakeCurrent
#define eglSwapBuffers _glfw.egl.SwapBuffers
#define eglSwapInterval _glfw.egl.SwapInterval
#define eglQueryString _glfw.egl.QueryString
#define eglGetProcAddress _glfw.egl.GetProcAddress
#define _GLFW_EGL_CONTEXT_STATE _GLFWcontextEGL egl
#define _GLFW_EGL_LIBRARY_CONTEXT_STATE _GLFWlibraryEGL egl
// EGL-specific per-context data
//
typedef struct _GLFWcontextEGL
{
EGLConfig config;
EGLContext handle;
EGLSurface surface;
void* client;
} _GLFWcontextEGL;
// EGL-specific global data
//
typedef struct _GLFWlibraryEGL
{
EGLDisplay display;
EGLint major, minor;
GLFWbool 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;
void* handle;
PFN_eglGetConfigAttrib GetConfigAttrib;
PFN_eglGetConfigs GetConfigs;
PFN_eglGetDisplay GetDisplay;
PFN_eglGetError GetError;
PFN_eglInitialize Initialize;
PFN_eglTerminate Terminate;
PFN_eglBindAPI BindAPI;
PFN_eglCreateContext CreateContext;
PFN_eglDestroySurface DestroySurface;
PFN_eglDestroyContext DestroyContext;
PFN_eglCreateWindowSurface CreateWindowSurface;
PFN_eglMakeCurrent MakeCurrent;
PFN_eglSwapBuffers SwapBuffers;
PFN_eglSwapInterval SwapInterval;
PFN_eglQueryString QueryString;
PFN_eglGetProcAddress GetProcAddress;
} _GLFWlibraryEGL;
GLFWbool _glfwInitEGL(void);
void _glfwTerminateEGL(void);
GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
#if defined(_GLFW_X11)
GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth);
#endif /*_GLFW_X11*/

277
glfw/glfw.py Executable file
View File

@@ -0,0 +1,277 @@
#!/usr/bin/env python
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
import json
import os
import re
import sys
_plat = sys.platform.lower()
is_macos = 'darwin' in _plat
is_freebsd = 'freebsd' in _plat
is_netbsd = 'netbsd' in _plat
is_dragonflybsd = 'dragonfly' in _plat
is_bsd = is_freebsd or is_netbsd or is_dragonflybsd
base = os.path.dirname(os.path.abspath(__file__))
def wayland_protocol_file_name(base, ext='c'):
base = os.path.basename(base).rpartition('.')[0]
return 'wayland-{}-client-protocol.{}'.format(base, ext)
def init_env(env, pkg_config, at_least_version, test_compile, module='x11'):
ans = env.copy()
ans.cflags = [
x for x in ans.cflags
if x not in '-Wpedantic -Wextra -pedantic-errors'.split()
]
if not is_macos:
ans.cflags.append('-pthread')
ans.ldpaths.append('-pthread')
ans.cflags.append('-fpic')
ans.cppflags.append('-D_GLFW_' + module.upper())
ans.cppflags.append('-D_GLFW_BUILD_DLL')
if is_macos:
ans.cppflags.append('-DGL_SILENCE_DEPRECATION')
ans.ldpaths.extend(
"-framework Cocoa -framework IOKit -framework CoreFoundation -framework CoreVideo".
split()
)
else:
ans.ldpaths.extend('-lrt -lm -ldl'.split())
sinfo = json.load(open(os.path.join(base, 'source-info.json')))
module_sources = list(sinfo[module]['sources'])
if module in ('x11', 'wayland'):
remove = 'linux_joystick.c' if is_bsd else 'null_joystick.c'
module_sources.remove(remove)
ans.sources = sinfo['common']['sources'] + module_sources
ans.all_headers = [x for x in os.listdir(base) if x.endswith('.h')]
if module in ('x11', 'wayland'):
at_least_version('xkbcommon', 0, 5)
if module == 'x11':
for dep in 'x11 xrandr xinerama xcursor xkbcommon xkbcommon-x11 x11-xcb dbus-1'.split():
ans.cflags.extend(pkg_config(dep, '--cflags-only-I'))
ans.ldpaths.extend(pkg_config(dep, '--libs'))
elif module == 'cocoa':
for f in 'Cocoa IOKit CoreFoundation CoreVideo'.split():
ans.ldpaths.extend(('-framework', f))
elif module == 'wayland':
at_least_version('wayland-protocols', *sinfo['wayland_protocols'])
ans.wayland_packagedir = os.path.abspath(pkg_config('wayland-protocols', '--variable=pkgdatadir')[0])
ans.wayland_scanner = os.path.abspath(pkg_config('wayland-scanner', '--variable=wayland_scanner')[0])
scanner_version = tuple(map(int, pkg_config('wayland-scanner', '--modversion')[0].strip().split('.')))
ans.wayland_scanner_code = 'private-code' if scanner_version >= (1, 14, 91) else 'code'
ans.wayland_protocols = tuple(sinfo[module]['protocols'])
for p in ans.wayland_protocols:
ans.sources.append(wayland_protocol_file_name(p))
ans.all_headers.append(wayland_protocol_file_name(p, 'h'))
for dep in 'wayland-egl wayland-client wayland-cursor xkbcommon dbus-1'.split():
ans.cflags.extend(pkg_config(dep, '--cflags-only-I'))
ans.ldpaths.extend(pkg_config(dep, '--libs'))
has_memfd_create = test_compile(env.cc, '-Werror', src='''#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
int main(void) {
return syscall(__NR_memfd_create, "test", 0);
}''')
if has_memfd_create:
ans.cppflags.append('-DHAS_MEMFD_CREATE')
return ans
def build_wayland_protocols(env, run_tool, emphasis, newer, dest_dir):
for protocol in env.wayland_protocols:
src = os.path.join(env.wayland_packagedir, protocol)
if not os.path.exists(src):
raise SystemExit('The wayland-protocols package on your system is missing the {} protocol definition file'.format(protocol))
for ext in 'hc':
dest = wayland_protocol_file_name(src, ext)
dest = os.path.join(dest_dir, dest)
if newer(dest, src):
q = 'client-header' if ext == 'h' else env.wayland_scanner_code
run_tool([env.wayland_scanner, q, src, dest],
desc='Generating {} ...'.format(emphasis(os.path.basename(dest))))
def collect_source_information():
raw = open('src/CMakeLists.txt').read()
mraw = open('CMakeLists.txt').read()
def extract_sources(group, start_pos=0):
for which in 'HEADERS SOURCES'.split():
yield which.lower(), list(filter(
lambda x: x[0] not in '"$',
re.search(
r'{0}_{1}\s+([^)]+?)[)]'.format(group, which),
raw[start_pos:]
).group(1).strip().split()
))
wayland_protocols = re.search(r'WaylandProtocols\s+(\S+)\s+', mraw).group(1)
wayland_protocols = list(map(int, wayland_protocols.split('.')))
ans = {
'common': dict(extract_sources('common')),
'wayland_protocols': wayland_protocols,
}
for group in 'cocoa win32 x11 wayland osmesa'.split():
m = re.search('_GLFW_' + group.upper(), raw)
ans[group] = dict(extract_sources('glfw', m.start()))
if group in ('x11', 'wayland'):
for joystick in ('linux', 'null'):
ans[group]['headers'].append('{}_joystick.h'.format(joystick))
ans[group]['sources'].append('{}_joystick.c'.format(joystick))
if group == 'wayland':
ans[group]['protocols'] = p = []
for m in re.finditer(r'WAYLAND_PROTOCOLS_PKGDATADIR\}/(.+?)"?$', raw, flags=re.M):
p.append(m.group(1))
return ans
class Arg:
def __init__(self, decl):
self.type, self.name = decl.rsplit(' ', 1)
self.type = self.type.strip()
self.name = self.name.strip()
while self.name.startswith('*'):
self.name = self.name[1:]
self.type = self.type + '*'
def __repr__(self):
return 'Arg({}, {})'.format(self.type, self.name)
class Function:
def __init__(self, declaration, check_fail=True):
self.check_fail = check_fail
m = re.match(
r'(.+?)\s+(glfw[A-Z][a-zA-Z0-9]+)[(](.+)[)]$', declaration
)
if m is None:
raise SystemExit('Failed to parse ' + repr(declaration))
self.restype = m.group(1).strip()
self.name = m.group(2)
args = m.group(3).strip().split(',')
args = [x.strip() for x in args]
self.args = []
for a in args:
if a == 'void':
continue
self.args.append(Arg(a))
def declaration(self):
return 'typedef {restype} (*{name}_func)({args});\n{name}_func {name}_impl;\n#define {name} {name}_impl'.format(
restype=self.restype,
name=self.name,
args=', '.join(a.type for a in self.args)
)
def load(self):
ans = '*(void **) (&{name}_impl) = dlsym(handle, "{name}");'.format(
name=self.name
)
if self.check_fail:
ans += '\n if ({name}_impl == NULL) fail("Failed to load glfw function {name} with error: %s", dlerror());'.format(
name=self.name
)
return ans
def generate_wrappers(glfw_header):
src = open(glfw_header).read()
functions = []
first = None
for m in re.finditer(r'^GLFWAPI\s+(.+[)]);\s*$', src, flags=re.MULTILINE):
if first is None:
first = m.start()
decl = m.group(1)
if 'VkInstance' in decl:
continue
functions.append(Function(decl))
for line in '''\
void* glfwGetCocoaWindow(GLFWwindow* window)
void* glfwGetNSGLContext(GLFWwindow *window)
uint32_t glfwGetCocoaMonitor(GLFWmonitor* monitor)
GLFWcocoatextinputfilterfun glfwSetCocoaTextInputFilter(GLFWwindow* window, GLFWcocoatextinputfilterfun callback)
GLFWcocoatogglefullscreenfun glfwSetCocoaToggleFullscreenIntercept(GLFWwindow *window, GLFWcocoatogglefullscreenfun callback)
GLFWapplicationshouldhandlereopenfun glfwSetApplicationShouldHandleReopen(GLFWapplicationshouldhandlereopenfun callback)
void glfwGetCocoaKeyEquivalent(int glfw_key, int glfw_mods, void* cocoa_key, void* cocoa_mods)
void* glfwGetX11Display(void)
int32_t glfwGetX11Window(GLFWwindow* window)
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)
'''.splitlines():
if line:
functions.append(Function(line.strip(), check_fail=False))
declarations = [f.declaration() for f in functions]
p = src.find(' * GLFW API tokens')
p = src.find('*/', p)
preamble = src[p + 2:first]
header = '''\
#pragma once
#include <stddef.h>
#include <stdint.h>
{}
typedef int (* GLFWcocoatextinputfilterfun)(int,int,unsigned int);
typedef int (* GLFWapplicationshouldhandlereopenfun)(int);
typedef int (* GLFWcocoatogglefullscreenfun)(GLFWwindow*);
typedef void (*GLFWwaylandframecallbackfunc)(unsigned long long id);
{}
const char* load_glfw(const char* path);
'''.format(preamble, '\n\n'.join(declarations))
with open('../kitty/glfw-wrapper.h', 'w') as f:
f.write(header)
code = '''
#include "data-types.h"
#include "glfw-wrapper.h"
#include <dlfcn.h>
static void* handle = NULL;
#define fail(msg, ...) { snprintf(buf, sizeof(buf), msg, __VA_ARGS__); return buf; }
const char*
load_glfw(const char* path) {
static char buf[2048];
handle = dlopen(path, RTLD_LAZY);
if (handle == NULL) fail("Failed to dlopen %s with error: %s", path, dlerror());
dlerror();
LOAD
return NULL;
}
void
unload_glfw() {
if (handle) { dlclose(handle); handle = NULL; }
}
'''.replace('LOAD', '\n\n '.join(f.load() for f in functions))
with open('../kitty/glfw-wrapper.c', 'w') as f:
f.write(code)
def main():
os.chdir(os.path.dirname(os.path.abspath(__file__)))
generate_wrappers('glfw3.h')
if __name__ == '__main__':
main()

5487
glfw/glfw3.h vendored Normal file

File diff suppressed because it is too large Load Diff

698
glfw/glx_context.c vendored Normal file
View File

@@ -0,0 +1,698 @@
//========================================================================
// GLFW 3.3 GLX - 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 <string.h>
#include <stdlib.h>
#include <assert.h>
#ifndef GLXBadProfileARB
#define GLXBadProfileARB 13
#endif
// Returns the specified attribute of the specified GLXFBConfig
//
static int getGLXFBConfigAttrib(GLXFBConfig fbconfig, int attrib)
{
int value;
glXGetFBConfigAttrib(_glfw.x11.display, fbconfig, attrib, &value);
return value;
}
// Return the GLXFBConfig most closely matching the specified hints
//
static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
GLXFBConfig* result)
{
GLXFBConfig* nativeConfigs;
_GLFWfbconfig* usableConfigs;
const _GLFWfbconfig* closest;
int i, nativeCount, usableCount;
const char* vendor;
GLFWbool trustWindowBit = GLFW_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;
nativeConfigs =
glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, &nativeCount);
if (!nativeConfigs || !nativeCount)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned");
return GLFW_FALSE;
}
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
usableCount = 0;
for (i = 0; i < nativeCount; i++)
{
const GLXFBConfig n = nativeConfigs[i];
_GLFWfbconfig* u = usableConfigs + usableCount;
// Only consider RGBA GLXFBConfigs
if (!(getGLXFBConfigAttrib(n, GLX_RENDER_TYPE) & GLX_RGBA_BIT))
continue;
// Only consider window GLXFBConfigs
if (!(getGLXFBConfigAttrib(n, GLX_DRAWABLE_TYPE) & GLX_WINDOW_BIT))
{
if (trustWindowBit)
continue;
}
if (desired->transparent)
{
XVisualInfo* vi = glXGetVisualFromFBConfig(_glfw.x11.display, n);
if (vi)
{
u->transparent = _glfwIsVisualTransparentX11(vi->visual);
XFree(vi);
}
}
u->redBits = getGLXFBConfigAttrib(n, GLX_RED_SIZE);
u->greenBits = getGLXFBConfigAttrib(n, GLX_GREEN_SIZE);
u->blueBits = getGLXFBConfigAttrib(n, GLX_BLUE_SIZE);
u->alphaBits = getGLXFBConfigAttrib(n, GLX_ALPHA_SIZE);
u->depthBits = getGLXFBConfigAttrib(n, GLX_DEPTH_SIZE);
u->stencilBits = getGLXFBConfigAttrib(n, GLX_STENCIL_SIZE);
u->accumRedBits = getGLXFBConfigAttrib(n, GLX_ACCUM_RED_SIZE);
u->accumGreenBits = getGLXFBConfigAttrib(n, GLX_ACCUM_GREEN_SIZE);
u->accumBlueBits = getGLXFBConfigAttrib(n, GLX_ACCUM_BLUE_SIZE);
u->accumAlphaBits = getGLXFBConfigAttrib(n, GLX_ACCUM_ALPHA_SIZE);
u->auxBuffers = getGLXFBConfigAttrib(n, GLX_AUX_BUFFERS);
if (getGLXFBConfigAttrib(n, GLX_STEREO))
u->stereo = GLFW_TRUE;
if (getGLXFBConfigAttrib(n, GLX_DOUBLEBUFFER))
u->doublebuffer = GLFW_TRUE;
if (_glfw.glx.ARB_multisample)
u->samples = getGLXFBConfigAttrib(n, GLX_SAMPLES);
if (_glfw.glx.ARB_framebuffer_sRGB || _glfw.glx.EXT_framebuffer_sRGB)
u->sRGB = getGLXFBConfigAttrib(n, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB);
u->handle = (uintptr_t) n;
usableCount++;
}
closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);
if (closest)
*result = (GLXFBConfig) closest->handle;
XFree(nativeConfigs);
free(usableConfigs);
return closest != NULL;
}
// Create the OpenGL context using legacy API
//
static GLXContext createLegacyContextGLX(_GLFWwindow* window,
GLXFBConfig fbconfig,
GLXContext share)
{
return glXCreateNewContext(_glfw.x11.display,
fbconfig,
GLX_RGBA_TYPE,
share,
True);
}
static void makeContextCurrentGLX(_GLFWwindow* window)
{
if (window)
{
if (!glXMakeCurrent(_glfw.x11.display,
window->context.glx.window,
window->context.glx.handle))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"GLX: Failed to make context current");
return;
}
}
else
{
if (!glXMakeCurrent(_glfw.x11.display, None, NULL))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"GLX: Failed to clear current context");
return;
}
}
_glfwPlatformSetTls(&_glfw.contextSlot, window);
}
static void swapBuffersGLX(_GLFWwindow* window)
{
glXSwapBuffers(_glfw.x11.display, window->context.glx.window);
}
static void swapIntervalGLX(int interval)
{
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
if (_glfw.glx.EXT_swap_control)
{
_glfw.glx.SwapIntervalEXT(_glfw.x11.display,
window->context.glx.window,
interval);
}
else if (_glfw.glx.MESA_swap_control)
_glfw.glx.SwapIntervalMESA(interval);
else if (_glfw.glx.SGI_swap_control)
{
if (interval > 0)
_glfw.glx.SwapIntervalSGI(interval);
}
}
static int extensionSupportedGLX(const char* extension)
{
const char* extensions =
glXQueryExtensionsString(_glfw.x11.display, _glfw.x11.screen);
if (extensions)
{
if (_glfwStringInExtensionString(extension, extensions))
return GLFW_TRUE;
}
return GLFW_FALSE;
}
static GLFWglproc getProcAddressGLX(const char* procname)
{
if (_glfw.glx.GetProcAddress)
return _glfw.glx.GetProcAddress((const GLubyte*) procname);
else if (_glfw.glx.GetProcAddressARB)
return _glfw.glx.GetProcAddressARB((const GLubyte*) procname);
else
return _glfw_dlsym(_glfw.glx.handle, procname);
}
// Destroy the OpenGL context
//
static void destroyContextGLX(_GLFWwindow* window)
{
if (window->context.glx.window)
{
glXDestroyWindow(_glfw.x11.display, window->context.glx.window);
window->context.glx.window = None;
}
if (window->context.glx.handle)
{
glXDestroyContext(_glfw.x11.display, window->context.glx.handle);
window->context.glx.handle = NULL;
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Initialize GLX
//
GLFWbool _glfwInitGLX(void)
{
int i;
const char* sonames[] =
{
#if defined(_GLFW_GLX_LIBRARY)
_GLFW_GLX_LIBRARY,
#elif defined(__CYGWIN__)
"libGL-1.so",
#else
"libGL.so.1",
"libGL.so",
#endif
NULL
};
if (_glfw.glx.handle)
return GLFW_TRUE;
for (i = 0; sonames[i]; i++)
{
_glfw.glx.handle = _glfw_dlopen(sonames[i]);
if (_glfw.glx.handle)
break;
}
if (!_glfw.glx.handle)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: Failed to load GLX");
return GLFW_FALSE;
}
_glfw.glx.GetFBConfigs =
_glfw_dlsym(_glfw.glx.handle, "glXGetFBConfigs");
_glfw.glx.GetFBConfigAttrib =
_glfw_dlsym(_glfw.glx.handle, "glXGetFBConfigAttrib");
_glfw.glx.GetClientString =
_glfw_dlsym(_glfw.glx.handle, "glXGetClientString");
_glfw.glx.QueryExtension =
_glfw_dlsym(_glfw.glx.handle, "glXQueryExtension");
_glfw.glx.QueryVersion =
_glfw_dlsym(_glfw.glx.handle, "glXQueryVersion");
_glfw.glx.DestroyContext =
_glfw_dlsym(_glfw.glx.handle, "glXDestroyContext");
_glfw.glx.MakeCurrent =
_glfw_dlsym(_glfw.glx.handle, "glXMakeCurrent");
_glfw.glx.SwapBuffers =
_glfw_dlsym(_glfw.glx.handle, "glXSwapBuffers");
_glfw.glx.QueryExtensionsString =
_glfw_dlsym(_glfw.glx.handle, "glXQueryExtensionsString");
_glfw.glx.CreateNewContext =
_glfw_dlsym(_glfw.glx.handle, "glXCreateNewContext");
_glfw.glx.CreateWindow =
_glfw_dlsym(_glfw.glx.handle, "glXCreateWindow");
_glfw.glx.DestroyWindow =
_glfw_dlsym(_glfw.glx.handle, "glXDestroyWindow");
_glfw.glx.GetProcAddress =
_glfw_dlsym(_glfw.glx.handle, "glXGetProcAddress");
_glfw.glx.GetProcAddressARB =
_glfw_dlsym(_glfw.glx.handle, "glXGetProcAddressARB");
_glfw.glx.GetVisualFromFBConfig =
_glfw_dlsym(_glfw.glx.handle, "glXGetVisualFromFBConfig");
if (!_glfw.glx.GetFBConfigs ||
!_glfw.glx.GetFBConfigAttrib ||
!_glfw.glx.GetClientString ||
!_glfw.glx.QueryExtension ||
!_glfw.glx.QueryVersion ||
!_glfw.glx.DestroyContext ||
!_glfw.glx.MakeCurrent ||
!_glfw.glx.SwapBuffers ||
!_glfw.glx.QueryExtensionsString ||
!_glfw.glx.CreateNewContext ||
!_glfw.glx.CreateWindow ||
!_glfw.glx.DestroyWindow ||
!_glfw.glx.GetProcAddress ||
!_glfw.glx.GetProcAddressARB ||
!_glfw.glx.GetVisualFromFBConfig)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"GLX: Failed to load required entry points");
return GLFW_FALSE;
}
if (!glXQueryExtension(_glfw.x11.display,
&_glfw.glx.errorBase,
&_glfw.glx.eventBase))
{
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: GLX extension not found");
return GLFW_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;
}
if (_glfw.glx.major == 1 && _glfw.glx.minor < 3)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"GLX: GLX version 1.3 is required");
return GLFW_FALSE;
}
if (extensionSupportedGLX("GLX_EXT_swap_control"))
{
_glfw.glx.SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)
getProcAddressGLX("glXSwapIntervalEXT");
if (_glfw.glx.SwapIntervalEXT)
_glfw.glx.EXT_swap_control = GLFW_TRUE;
}
if (extensionSupportedGLX("GLX_SGI_swap_control"))
{
_glfw.glx.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)
getProcAddressGLX("glXSwapIntervalSGI");
if (_glfw.glx.SwapIntervalSGI)
_glfw.glx.SGI_swap_control = GLFW_TRUE;
}
if (extensionSupportedGLX("GLX_MESA_swap_control"))
{
_glfw.glx.SwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)
getProcAddressGLX("glXSwapIntervalMESA");
if (_glfw.glx.SwapIntervalMESA)
_glfw.glx.MESA_swap_control = GLFW_TRUE;
}
if (extensionSupportedGLX("GLX_ARB_multisample"))
_glfw.glx.ARB_multisample = GLFW_TRUE;
if (extensionSupportedGLX("GLX_ARB_framebuffer_sRGB"))
_glfw.glx.ARB_framebuffer_sRGB = GLFW_TRUE;
if (extensionSupportedGLX("GLX_EXT_framebuffer_sRGB"))
_glfw.glx.EXT_framebuffer_sRGB = GLFW_TRUE;
if (extensionSupportedGLX("GLX_ARB_create_context"))
{
_glfw.glx.CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)
getProcAddressGLX("glXCreateContextAttribsARB");
if (_glfw.glx.CreateContextAttribsARB)
_glfw.glx.ARB_create_context = GLFW_TRUE;
}
if (extensionSupportedGLX("GLX_ARB_create_context_robustness"))
_glfw.glx.ARB_create_context_robustness = GLFW_TRUE;
if (extensionSupportedGLX("GLX_ARB_create_context_profile"))
_glfw.glx.ARB_create_context_profile = GLFW_TRUE;
if (extensionSupportedGLX("GLX_EXT_create_context_es2_profile"))
_glfw.glx.EXT_create_context_es2_profile = GLFW_TRUE;
if (extensionSupportedGLX("GLX_ARB_create_context_no_error"))
_glfw.glx.ARB_create_context_no_error = GLFW_TRUE;
if (extensionSupportedGLX("GLX_ARB_context_flush_control"))
_glfw.glx.ARB_context_flush_control = GLFW_TRUE;
return GLFW_TRUE;
}
// Terminate GLX
//
void _glfwTerminateGLX(void)
{
// NOTE: This function must not call any X11 functions, as it is called
// after XCloseDisplay (see _glfwPlatformTerminate for details)
if (_glfw.glx.handle)
{
_glfw_dlclose(_glfw.glx.handle);
_glfw.glx.handle = NULL;
}
}
#define setAttrib(a, v) \
{ \
assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \
attribs[index++] = v; \
}
// Create the OpenGL or OpenGL ES context
//
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
int attribs[40];
GLXFBConfig native = NULL;
GLXContext share = NULL;
if (ctxconfig->share)
share = ctxconfig->share->context.glx.handle;
if (!chooseGLXFBConfig(fbconfig, &native))
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"GLX: Failed to find a suitable GLXFBConfig");
return GLFW_FALSE;
}
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
if (!_glfw.glx.ARB_create_context ||
!_glfw.glx.ARB_create_context_profile ||
!_glfw.glx.EXT_create_context_es2_profile)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"GLX: OpenGL ES requested but GLX_EXT_create_context_es2_profile is unavailable");
return GLFW_FALSE;
}
}
if (ctxconfig->forward)
{
if (!_glfw.glx.ARB_create_context)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"GLX: Forward compatibility requested but GLX_ARB_create_context_profile is unavailable");
return GLFW_FALSE;
}
}
if (ctxconfig->profile)
{
if (!_glfw.glx.ARB_create_context ||
!_glfw.glx.ARB_create_context_profile)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"GLX: An OpenGL profile requested but GLX_ARB_create_context_profile is unavailable");
return GLFW_FALSE;
}
}
_glfwGrabErrorHandlerX11();
if (_glfw.glx.ARB_create_context)
{
int index = 0, mask = 0, flags = 0;
if (ctxconfig->client == GLFW_OPENGL_API)
{
if (ctxconfig->forward)
flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
mask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
mask |= GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
}
else
mask |= GLX_CONTEXT_ES2_PROFILE_BIT_EXT;
if (ctxconfig->debug)
flags |= GLX_CONTEXT_DEBUG_BIT_ARB;
if (ctxconfig->robustness)
{
if (_glfw.glx.ARB_create_context_robustness)
{
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
{
setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
GLX_NO_RESET_NOTIFICATION_ARB);
}
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
{
setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
GLX_LOSE_CONTEXT_ON_RESET_ARB);
}
flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB;
}
}
if (ctxconfig->release)
{
if (_glfw.glx.ARB_context_flush_control)
{
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
{
setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
}
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
{
setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
}
}
}
if (ctxconfig->noerror)
{
if (_glfw.glx.ARB_create_context_no_error)
setAttrib(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
}
// NOTE: Only request an explicitly versioned context when necessary, as
// explicitly requesting version 1.0 does not always return the
// highest version supported by the driver
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
{
setAttrib(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
setAttrib(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
}
if (mask)
setAttrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask);
if (flags)
setAttrib(GLX_CONTEXT_FLAGS_ARB, flags);
setAttrib(None, None);
window->context.glx.handle =
_glfw.glx.CreateContextAttribsARB(_glfw.x11.display,
native,
share,
True,
attribs);
// HACK: This is a fallback for broken versions of the Mesa
// implementation of GLX_ARB_create_context_profile that fail
// default 1.0 context creation with a GLXBadProfileARB error in
// violation of the extension spec
if (!window->context.glx.handle)
{
if (_glfw.x11.errorCode == _glfw.glx.errorBase + GLXBadProfileARB &&
ctxconfig->client == GLFW_OPENGL_API &&
ctxconfig->profile == GLFW_OPENGL_ANY_PROFILE &&
ctxconfig->forward == GLFW_FALSE)
{
window->context.glx.handle =
createLegacyContextGLX(window, native, share);
}
}
}
else
{
window->context.glx.handle =
createLegacyContextGLX(window, native, share);
}
_glfwReleaseErrorHandlerX11();
if (!window->context.glx.handle)
{
_glfwInputErrorX11(GLFW_VERSION_UNAVAILABLE, "GLX: Failed to create context");
return GLFW_FALSE;
}
window->context.glx.window =
glXCreateWindow(_glfw.x11.display, native, window->x11.handle, NULL);
if (!window->context.glx.window)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to create window");
return GLFW_FALSE;
}
window->context.makeCurrent = makeContextCurrentGLX;
window->context.swapBuffers = swapBuffersGLX;
window->context.swapInterval = swapIntervalGLX;
window->context.extensionSupported = extensionSupportedGLX;
window->context.getProcAddress = getProcAddressGLX;
window->context.destroy = destroyContextGLX;
return GLFW_TRUE;
}
#undef setAttrib
// Returns the Visual and depth of the chosen GLXFBConfig
//
GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth)
{
GLXFBConfig native;
XVisualInfo* result;
if (!chooseGLXFBConfig(fbconfig, &native))
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"GLX: Failed to find a suitable GLXFBConfig");
return GLFW_FALSE;
}
result = glXGetVisualFromFBConfig(_glfw.x11.display, native);
if (!result)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"GLX: Failed to retrieve Visual for GLXFBConfig");
return GLFW_FALSE;
}
*visual = result->visual;
*depth = result->depth;
XFree(result);
return GLFW_TRUE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW native API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (window->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return NULL;
}
return window->context.glx.handle;
}
GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(None);
if (window->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return None;
}
return window->context.glx.window;
}

181
glfw/glx_context.h vendored Normal file
View File

@@ -0,0 +1,181 @@
//========================================================================
// GLFW 3.3 GLX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#define GLX_VENDOR 1
#define GLX_RGBA_BIT 0x00000001
#define GLX_WINDOW_BIT 0x00000001
#define GLX_DRAWABLE_TYPE 0x8010
#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_RED_SIZE 8
#define GLX_GREEN_SIZE 9
#define GLX_BLUE_SIZE 10
#define GLX_ALPHA_SIZE 11
#define GLX_DEPTH_SIZE 12
#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_ALPHA_SIZE 17
#define GLX_SAMPLES 0x186a1
#define GLX_VISUAL_ID 0x800b
#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20b2
#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
#define GLX_CONTEXT_FLAGS_ARB 0x2094
#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252
#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261
#define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
#define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
#define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
#define GLX_CONTEXT_OPENGL_NO_ERROR_ARB 0x31b3
typedef XID GLXWindow;
typedef XID GLXDrawable;
typedef struct __GLXFBConfig* GLXFBConfig;
typedef struct __GLXcontext* GLXContext;
typedef void (*__GLXextproc)(void);
typedef int (*PFNGLXGETFBCONFIGATTRIBPROC)(Display*,GLXFBConfig,int,int*);
typedef const char* (*PFNGLXGETCLIENTSTRINGPROC)(Display*,int);
typedef Bool (*PFNGLXQUERYEXTENSIONPROC)(Display*,int*,int*);
typedef Bool (*PFNGLXQUERYVERSIONPROC)(Display*,int*,int*);
typedef void (*PFNGLXDESTROYCONTEXTPROC)(Display*,GLXContext);
typedef Bool (*PFNGLXMAKECURRENTPROC)(Display*,GLXDrawable,GLXContext);
typedef void (*PFNGLXSWAPBUFFERSPROC)(Display*,GLXDrawable);
typedef const char* (*PFNGLXQUERYEXTENSIONSSTRINGPROC)(Display*,int);
typedef GLXFBConfig* (*PFNGLXGETFBCONFIGSPROC)(Display*,int,int*);
typedef GLXContext (*PFNGLXCREATENEWCONTEXTPROC)(Display*,GLXFBConfig,int,GLXContext,Bool);
typedef __GLXextproc (* PFNGLXGETPROCADDRESSPROC)(const GLubyte *procName);
typedef void (*PFNGLXSWAPINTERVALEXTPROC)(Display*,GLXDrawable,int);
typedef XVisualInfo* (*PFNGLXGETVISUALFROMFBCONFIGPROC)(Display*,GLXFBConfig);
typedef GLXWindow (*PFNGLXCREATEWINDOWPROC)(Display*,GLXFBConfig,Window,const int*);
typedef void (*PFNGLXDESTROYWINDOWPROC)(Display*,GLXWindow);
typedef int (*PFNGLXSWAPINTERVALMESAPROC)(int);
typedef int (*PFNGLXSWAPINTERVALSGIPROC)(int);
typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display*,GLXFBConfig,GLXContext,Bool,const int*);
// libGL.so function pointer typedefs
#define glXGetFBConfigs _glfw.glx.GetFBConfigs
#define glXGetFBConfigAttrib _glfw.glx.GetFBConfigAttrib
#define glXGetClientString _glfw.glx.GetClientString
#define glXQueryExtension _glfw.glx.QueryExtension
#define glXQueryVersion _glfw.glx.QueryVersion
#define glXDestroyContext _glfw.glx.DestroyContext
#define glXMakeCurrent _glfw.glx.MakeCurrent
#define glXSwapBuffers _glfw.glx.SwapBuffers
#define glXQueryExtensionsString _glfw.glx.QueryExtensionsString
#define glXCreateNewContext _glfw.glx.CreateNewContext
#define glXGetVisualFromFBConfig _glfw.glx.GetVisualFromFBConfig
#define glXCreateWindow _glfw.glx.CreateWindow
#define glXDestroyWindow _glfw.glx.DestroyWindow
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX glx
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx
// GLX-specific per-context data
//
typedef struct _GLFWcontextGLX
{
GLXContext handle;
GLXWindow window;
} _GLFWcontextGLX;
// GLX-specific global data
//
typedef struct _GLFWlibraryGLX
{
int major, minor;
int eventBase;
int errorBase;
// dlopen handle for libGL.so.1
void* handle;
// GLX 1.3 functions
PFNGLXGETFBCONFIGSPROC GetFBConfigs;
PFNGLXGETFBCONFIGATTRIBPROC GetFBConfigAttrib;
PFNGLXGETCLIENTSTRINGPROC GetClientString;
PFNGLXQUERYEXTENSIONPROC QueryExtension;
PFNGLXQUERYVERSIONPROC QueryVersion;
PFNGLXDESTROYCONTEXTPROC DestroyContext;
PFNGLXMAKECURRENTPROC MakeCurrent;
PFNGLXSWAPBUFFERSPROC SwapBuffers;
PFNGLXQUERYEXTENSIONSSTRINGPROC QueryExtensionsString;
PFNGLXCREATENEWCONTEXTPROC CreateNewContext;
PFNGLXGETVISUALFROMFBCONFIGPROC GetVisualFromFBConfig;
PFNGLXCREATEWINDOWPROC CreateWindow;
PFNGLXDESTROYWINDOWPROC DestroyWindow;
// GLX 1.4 and extension functions
PFNGLXGETPROCADDRESSPROC GetProcAddress;
PFNGLXGETPROCADDRESSPROC GetProcAddressARB;
PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI;
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;
} _GLFWlibraryGLX;
GLFWbool _glfwInitGLX(void);
void _glfwTerminateGLX(void);
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
void _glfwDestroyContextGLX(_GLFWwindow* window);
GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth);

426
glfw/ibus_glfw.c vendored Normal file
View File

@@ -0,0 +1,426 @@
//========================================================================
// GLFW 3.3 XKB - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2018 Kovid Goyal <kovid@kovidgoyal.net>
//
// 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 _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <limits.h>
#include "internal.h"
#include "ibus_glfw.h"
#define debug(...) if (_glfw.hints.init.debugKeyboard) printf(__VA_ARGS__);
static const char IBUS_SERVICE[] = "org.freedesktop.IBus";
static const char IBUS_PATH[] = "/org/freedesktop/IBus";
static const char IBUS_INTERFACE[] = "org.freedesktop.IBus";
static const char IBUS_INPUT_INTERFACE[] = "org.freedesktop.IBus.InputContext";
enum Capabilities {
IBUS_CAP_PREEDIT_TEXT = 1 << 0,
IBUS_CAP_AUXILIARY_TEXT = 1 << 1,
IBUS_CAP_LOOKUP_TABLE = 1 << 2,
IBUS_CAP_FOCUS = 1 << 3,
IBUS_CAP_PROPERTY = 1 << 4,
IBUS_CAP_SURROUNDING_TEXT = 1 << 5
};
static inline GLFWbool
test_env_var(const char *name, const char *val) {
const char *q = getenv(name);
return (q && strcmp(q, val) == 0) ? GLFW_TRUE : GLFW_FALSE;
}
static inline GLFWbool
MIN(size_t a, size_t b) {
return a < b ? a : b;
}
static const char*
get_ibus_text_from_message(DBusMessage *msg) {
/* The message structure is (from dbus-monitor)
variant struct {
string "IBusText"
array [
]
string "ash "
variant struct {
string "IBusAttrList"
array [
]
array [
]
}
}
*/
const char *text = NULL;
const char *struct_id = NULL;
DBusMessageIter iter, sub1, sub2;
dbus_message_iter_init(msg, &iter);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) return NULL;
dbus_message_iter_recurse(&iter, &sub1);
if (dbus_message_iter_get_arg_type(&sub1) != DBUS_TYPE_STRUCT) return NULL;
dbus_message_iter_recurse(&sub1, &sub2);
if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_STRING) return NULL;
dbus_message_iter_get_basic(&sub2, &struct_id);
if (!struct_id || strncmp(struct_id, "IBusText", sizeof("IBusText")) != 0) return NULL;
dbus_message_iter_next(&sub2);
dbus_message_iter_next(&sub2);
if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_STRING) return NULL;
dbus_message_iter_get_basic(&sub2, &text);
return text;
}
static inline void
send_text(const char *text, int state) {
_GLFWwindow *w = _glfwFocusedWindow();
if (w && w->callbacks.keyboard) {
w->callbacks.keyboard((GLFWwindow*) w, GLFW_KEY_UNKNOWN, 0, GLFW_PRESS, 0, text, state);
}
}
// Connection handling {{{
static DBusHandlerResult
message_handler(DBusConnection *conn, DBusMessage *msg, void *user_data) {
// To monitor signals from IBUS, use
//  dbus-monitor --address `ibus address` "type='signal',interface='org.freedesktop.IBus.InputContext'"
_GLFWIBUSData *ibus = (_GLFWIBUSData*)user_data;
(void)ibus;
const char *text;
switch(glfw_dbus_match_signal(msg, IBUS_INPUT_INTERFACE, "CommitText", "UpdatePreeditText", "HidePreeditText", "ShowPreeditText", NULL)) {
case 0:
text = get_ibus_text_from_message(msg);
debug("IBUS: CommitText: '%s'\n", text ? text : "(nil)");
send_text(text, 2);
break;
case 1:
text = get_ibus_text_from_message(msg);
send_text(text, 1);
debug("IBUS: UpdatePreeditText: '%s'\n", text ? text : "(nil)");
break;
case 2:
debug("IBUS: HidePreeditText\n");
break;
case 3:
debug("IBUS: ShowPreeditText\n");
break;
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
static inline const char*
get_ibus_address_file_name(void) {
const char *addr;
static char ans[PATH_MAX];
addr = getenv("IBUS_ADDRESS");
int offset = 0;
if (addr && addr[0]) {
memcpy(ans, addr, MIN(strlen(addr), sizeof(ans)));
return ans;
}
const char *de = getenv("DISPLAY");
if (!de || !de[0]) de = ":0.0";
char *display = _glfw_strdup(de);
const char *host = display;
char *disp_num = strrchr(display, ':');
char *screen_num = strrchr(display, '.');
if (!disp_num) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Could not get IBUS address file name as DISPLAY env var has no colon");
free(display);
return NULL;
}
*disp_num = 0;
disp_num++;
if (screen_num) *screen_num = 0;
if (!*host) host = "unix";
memset(ans, 0, sizeof(ans));
const char *conf_env = getenv("XDG_CONFIG_HOME");
if (conf_env && conf_env[0]) {
offset = snprintf(ans, sizeof(ans), "%s", conf_env);
} else {
conf_env = getenv("HOME");
if (!conf_env || !conf_env[0]) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Could not get IBUS address file name as no HOME env var is set");
free(display);
return NULL;
}
offset = snprintf(ans, sizeof(ans), "%s/.config", conf_env);
}
char *key = dbus_get_local_machine_id();
snprintf(ans + offset, sizeof(ans) - offset, "/ibus/bus/%s-%s-%s", key, host, disp_num);
dbus_free(key);
free(display);
return ans;
}
static inline GLFWbool
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;
}
int stat_result = fstat(fileno(addr_file), &s);
GLFWbool found = GLFW_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;
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;
}
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;
}
_glfwInputError(GLFW_PLATFORM_ERROR, "Could not find IBUS_ADDRESS in %s", ibus->address_file_name);
return GLFW_FALSE;
}
void
input_context_created(DBusMessage *msg, const char* errmsg, void *data) {
if (errmsg) {
_glfwInputError(GLFW_PLATFORM_ERROR, "IBUS: Failed to create input context with error: %s", errmsg);
return;
}
const char *path = NULL;
if (!glfw_dbus_get_args(msg, "Failed to get IBUS context path from reply", DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) return;
_GLFWIBUSData *ibus = (_GLFWIBUSData*)data;
free((void*)ibus->input_ctx_path);
ibus->input_ctx_path = _glfw_strdup(path);
if (!ibus->input_ctx_path) return;
dbus_bus_add_match(ibus->conn, "type='signal',interface='org.freedesktop.IBus.InputContext'", NULL);
DBusObjectPathVTable ibus_vtable = {.message_function = message_handler};
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);
glfw_ibus_set_cursor_geometry(ibus, 0, 0, 0, 0);
debug("Connected to IBUS daemon for IME input management\n");
}
GLFWbool
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;
free((void*)ibus->address_file_name);
ibus->address_file_name = _glfw_strdup(address_file_name);
if (!read_ibus_address(ibus)) return GLFW_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;
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 GLFW_TRUE;
}
void
glfw_connect_to_ibus(_GLFWIBUSData *ibus) {
if (ibus->inited) return;
if (!test_env_var("GLFW_IM_MODULE", "ibus")) return;
ibus->inited = GLFW_TRUE;
setup_connection(ibus);
}
void
glfw_ibus_terminate(_GLFWIBUSData *ibus) {
if (ibus->conn) {
glfw_dbus_close_connection(ibus->conn);
ibus->conn = NULL;
}
#define F(x) if (ibus->x) { free((void*)ibus->x); ibus->x = NULL; }
F(input_ctx_path);
F(address);
F(address_file_name);
#undef F
ibus->ok = GLFW_FALSE;
}
static GLFWbool
check_connection(_GLFWIBUSData *ibus) {
if (!ibus->inited) return GLFW_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;
setup_connection(ibus);
}
return GLFW_FALSE;
}
void
glfw_ibus_dispatch(_GLFWIBUSData *ibus) {
if (ibus->conn) glfw_dbus_dispatch(ibus->conn);
}
// }}}
static void
simple_message(_GLFWIBUSData *ibus, const char *method) {
if (check_connection(ibus)) {
glfw_dbus_call_method_no_reply(ibus->conn, IBUS_SERVICE, ibus->input_ctx_path, IBUS_INPUT_INTERFACE, method, DBUS_TYPE_INVALID);
}
}
void
glfw_ibus_set_focused(_GLFWIBUSData *ibus, GLFWbool focused) {
simple_message(ibus, focused ? "FocusIn" : "FocusOut");
}
void
glfw_ibus_set_cursor_geometry(_GLFWIBUSData *ibus, int x, int y, int w, int h) {
if (check_connection(ibus)) {
glfw_dbus_call_method_no_reply(ibus->conn, IBUS_SERVICE, ibus->input_ctx_path, IBUS_INPUT_INTERFACE, "SetCursorLocation",
DBUS_TYPE_INT32, &x, DBUS_TYPE_INT32, &y, DBUS_TYPE_INT32, &w, DBUS_TYPE_INT32, &h, DBUS_TYPE_INVALID);
}
}
typedef enum
{
IBUS_SHIFT_MASK = 1 << 0,
IBUS_LOCK_MASK = 1 << 1,
IBUS_CONTROL_MASK = 1 << 2,
IBUS_MOD1_MASK = 1 << 3,
IBUS_MOD2_MASK = 1 << 4,
IBUS_MOD3_MASK = 1 << 5,
IBUS_MOD4_MASK = 1 << 6,
IBUS_MOD5_MASK = 1 << 7,
IBUS_BUTTON1_MASK = 1 << 8,
IBUS_BUTTON2_MASK = 1 << 9,
IBUS_BUTTON3_MASK = 1 << 10,
IBUS_BUTTON4_MASK = 1 << 11,
IBUS_BUTTON5_MASK = 1 << 12,
/* The next few modifiers are used by XKB, so we skip to the end.
* Bits 15 - 23 are currently unused. Bit 29 is used internally.
*/
/* ibus mask */
IBUS_HANDLED_MASK = 1 << 24,
IBUS_FORWARD_MASK = 1 << 25,
IBUS_IGNORED_MASK = IBUS_FORWARD_MASK,
IBUS_SUPER_MASK = 1 << 26,
IBUS_HYPER_MASK = 1 << 27,
IBUS_META_MASK = 1 << 28,
IBUS_RELEASE_MASK = 1 << 30,
IBUS_MODIFIER_MASK = 0x5f001fff
} IBusModifierType;
static inline uint32_t
ibus_key_state(unsigned int glfw_modifiers, int action) {
uint32_t ans = action == GLFW_RELEASE ? IBUS_RELEASE_MASK : 0;
#define M(g, i) if(glfw_modifiers & GLFW_MOD_##g) ans |= i
M(SHIFT, IBUS_SHIFT_MASK);
M(CAPS_LOCK, IBUS_LOCK_MASK);
M(CONTROL, IBUS_CONTROL_MASK);
M(ALT, IBUS_MOD1_MASK);
M(NUM_LOCK, IBUS_MOD2_MASK);
M(SUPER, IBUS_MOD4_MASK);
#undef M
return ans;
}
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;
if (errmsg) {
_glfwInputError(GLFW_PLATFORM_ERROR, "IBUS: Failed to process key with error: %s", errmsg);
failed = GLFW_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);
free(ev);
}
GLFWbool
ibus_process_key(const KeyEvent *ev_, _GLFWIBUSData *ibus) {
if (!check_connection(ibus)) return GLFW_FALSE;
KeyEvent *ev = malloc(sizeof(KeyEvent));
if (!ev) return GLFW_FALSE;
memcpy(ev, ev_, sizeof(KeyEvent));
uint32_t state = ibus_key_state(ev->glfw_modifiers, ev->action);
if (!glfw_dbus_call_method_with_reply(
ibus->conn, IBUS_SERVICE, ibus->input_ctx_path, IBUS_INPUT_INTERFACE, "ProcessKeyEvent",
3000, key_event_processed, ev,
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 GLFW_TRUE;
}

55
glfw/ibus_glfw.h vendored Normal file
View File

@@ -0,0 +1,55 @@
//========================================================================
// GLFW 3.3 XKB - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2018 Kovid Goyal <kovid@kovidgoyal.net>
//
// 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.
//
//========================================================================
#pragma once
#include "dbus_glfw.h"
#include <xkbcommon/xkbcommon.h>
typedef struct {
GLFWbool ok, inited;
time_t address_file_mtime;
DBusConnection *conn;
const char *input_ctx_path, *address_file_name, *address;
} _GLFWIBUSData;
typedef struct {
xkb_keycode_t keycode, ibus_keycode;
xkb_keysym_t keysym, ibus_sym;
unsigned int glfw_modifiers;
int action;
GLFWid window_id;
int glfw_keycode;
char text[64];
} KeyEvent;
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_dispatch(_GLFWIBUSData *ibus);
GLFWbool ibus_process_key(const KeyEvent *ev_, _GLFWIBUSData *ibus);
void glfw_ibus_set_cursor_geometry(_GLFWIBUSData *ibus, int x, int y, int w, int h);

322
glfw/init.c vendored Normal file
View File

@@ -0,0 +1,322 @@
//========================================================================
// GLFW 3.3 - 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 "mappings.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
// The global variables below comprise all mutable global data in GLFW
//
// Any other global variable is a bug
// Global state shared between compilation units of GLFW
//
_GLFWlibrary _glfw = { GLFW_FALSE };
// These are outside of _glfw so they can be used before initialization and
// after termination
//
static _GLFWerror _glfwMainThreadError;
static GLFWerrorfun _glfwErrorCallback;
static _GLFWinitconfig _glfwInitHints =
{
GLFW_TRUE, // hat buttons
GLFW_FALSE, // debug keyboard
GLFW_TRUE, // enable joystick
{
GLFW_TRUE, // macOS menu bar
GLFW_TRUE // macOS bundle chdir
}
};
// Terminate the library
//
static void terminate(void)
{
int i;
memset(&_glfw.callbacks, 0, sizeof(_glfw.callbacks));
while (_glfw.windowListHead)
glfwDestroyWindow((GLFWwindow*) _glfw.windowListHead);
while (_glfw.cursorListHead)
glfwDestroyCursor((GLFWcursor*) _glfw.cursorListHead);
for (i = 0; i < _glfw.monitorCount; i++)
{
_GLFWmonitor* monitor = _glfw.monitors[i];
if (monitor->originalRamp.size)
_glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp);
_glfwFreeMonitor(monitor);
}
free(_glfw.monitors);
_glfw.monitors = NULL;
_glfw.monitorCount = 0;
free(_glfw.mappings);
_glfw.mappings = NULL;
_glfw.mappingCount = 0;
_glfwTerminateVulkan();
_glfwPlatformTerminate();
_glfw.initialized = GLFW_FALSE;
while (_glfw.errorListHead)
{
_GLFWerror* error = _glfw.errorListHead;
_glfw.errorListHead = error->next;
free(error);
}
_glfwPlatformDestroyTls(&_glfw.contextSlot);
_glfwPlatformDestroyTls(&_glfw.errorSlot);
_glfwPlatformDestroyMutex(&_glfw.errorLock);
memset(&_glfw, 0, sizeof(_glfw));
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
char* _glfw_strdup(const char* source)
{
const size_t length = strlen(source);
char* result = malloc(length + 1);
memcpy(result, source, length);
result[length] = 0;
return result;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW event API //////
//////////////////////////////////////////////////////////////////////////
// Notifies shared code of an error
//
void _glfwInputError(int code, const char* format, ...)
{
_GLFWerror* error;
char description[_GLFW_MESSAGE_SIZE];
if (format)
{
va_list vl;
va_start(vl, format);
vsnprintf(description, sizeof(description), format, vl);
va_end(vl);
description[sizeof(description) - 1] = '\0';
}
else
{
if (code == GLFW_NOT_INITIALIZED)
strcpy(description, "The GLFW library is not initialized");
else if (code == GLFW_NO_CURRENT_CONTEXT)
strcpy(description, "There is no current context");
else if (code == GLFW_INVALID_ENUM)
strcpy(description, "Invalid argument for enum parameter");
else if (code == GLFW_INVALID_VALUE)
strcpy(description, "Invalid value for parameter");
else if (code == GLFW_OUT_OF_MEMORY)
strcpy(description, "Out of memory");
else if (code == GLFW_API_UNAVAILABLE)
strcpy(description, "The requested API is unavailable");
else if (code == GLFW_VERSION_UNAVAILABLE)
strcpy(description, "The requested API version is unavailable");
else if (code == GLFW_PLATFORM_ERROR)
strcpy(description, "A platform-specific error occurred");
else if (code == GLFW_FORMAT_UNAVAILABLE)
strcpy(description, "The requested format is unavailable");
else if (code == GLFW_NO_WINDOW_CONTEXT)
strcpy(description, "The specified window has no context");
else
strcpy(description, "ERROR: UNKNOWN GLFW ERROR");
}
if (_glfw.initialized)
{
error = _glfwPlatformGetTls(&_glfw.errorSlot);
if (!error)
{
error = calloc(1, sizeof(_GLFWerror));
_glfwPlatformSetTls(&_glfw.errorSlot, error);
_glfwPlatformLockMutex(&_glfw.errorLock);
error->next = _glfw.errorListHead;
_glfw.errorListHead = error;
_glfwPlatformUnlockMutex(&_glfw.errorLock);
}
}
else
error = &_glfwMainThreadError;
error->code = code;
strcpy(error->description, description);
if (_glfwErrorCallback)
_glfwErrorCallback(code, description);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI int glfwInit(void)
{
if (_glfw.initialized)
return GLFW_TRUE;
memset(&_glfw, 0, sizeof(_glfw));
_glfw.hints.init = _glfwInitHints;
if (!_glfwPlatformInit())
{
terminate();
return GLFW_FALSE;
}
if (!_glfwPlatformCreateMutex(&_glfw.errorLock) ||
!_glfwPlatformCreateTls(&_glfw.errorSlot) ||
!_glfwPlatformCreateTls(&_glfw.contextSlot))
{
terminate();
return GLFW_FALSE;
}
_glfwPlatformSetTls(&_glfw.errorSlot, &_glfwMainThreadError);
_glfw.initialized = GLFW_TRUE;
_glfw.timer.offset = _glfwPlatformGetTimerValue();
glfwDefaultWindowHints();
{
int i;
for (i = 0; _glfwDefaultMappings[i]; i++)
{
if (!glfwUpdateGamepadMappings(_glfwDefaultMappings[i]))
{
terminate();
return GLFW_FALSE;
}
}
}
return GLFW_TRUE;
}
GLFWAPI void glfwTerminate(void)
{
if (!_glfw.initialized)
return;
terminate();
}
GLFWAPI void glfwInitHint(int hint, int value)
{
switch (hint)
{
case GLFW_ENABLE_JOYSTICKS:
_glfwInitHints.enableJoysticks = value;
return;
case GLFW_JOYSTICK_HAT_BUTTONS:
_glfwInitHints.hatButtons = value;
return;
case GLFW_DEBUG_KEYBOARD:
_glfwInitHints.debugKeyboard = value;
return;
case GLFW_COCOA_CHDIR_RESOURCES:
_glfwInitHints.ns.chdir = value;
return;
case GLFW_COCOA_MENUBAR:
_glfwInitHints.ns.menubar = value;
return;
}
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid init hint 0x%08X", hint);
}
GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
{
if (major != NULL)
*major = GLFW_VERSION_MAJOR;
if (minor != NULL)
*minor = GLFW_VERSION_MINOR;
if (rev != NULL)
*rev = GLFW_VERSION_REVISION;
}
GLFWAPI const char* glfwGetVersionString(void)
{
return _glfwPlatformGetVersionString();
}
GLFWAPI int glfwGetError(const char** description)
{
_GLFWerror* error;
int code = GLFW_NO_ERROR;
if (description)
*description = NULL;
if (_glfw.initialized)
error = _glfwPlatformGetTls(&_glfw.errorSlot);
else
error = &_glfwMainThreadError;
if (error)
{
code = error->code;
error->code = GLFW_NO_ERROR;
if (description && code)
*description = error->description;
}
return code;
}
GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun)
{
_GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun);
return cbfun;
}

1426
glfw/input.c vendored Normal file

File diff suppressed because it is too large Load Diff

783
glfw/internal.h vendored Normal file
View File

@@ -0,0 +1,783 @@
//========================================================================
// GLFW 3.3 - 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.
//
//========================================================================
#pragma once
#if defined(_GLFW_USE_CONFIG_H)
#include "glfw_config.h"
#endif
#define arraysz(x) (sizeof(x)/sizeof(x[0]))
#if defined(GLFW_INCLUDE_GLCOREARB) || \
defined(GLFW_INCLUDE_ES1) || \
defined(GLFW_INCLUDE_ES2) || \
defined(GLFW_INCLUDE_ES3) || \
defined(GLFW_INCLUDE_ES31) || \
defined(GLFW_INCLUDE_ES32) || \
defined(GLFW_INCLUDE_NONE) || \
defined(GLFW_INCLUDE_GLEXT) || \
defined(GLFW_INCLUDE_GLU) || \
defined(GLFW_INCLUDE_VULKAN) || \
defined(GLFW_DLL)
#error "You must not define any header option macros when compiling GLFW"
#endif
#define GLFW_INCLUDE_NONE
#include "glfw3.h"
#define _GLFW_INSERT_FIRST 0
#define _GLFW_INSERT_LAST 1
#define _GLFW_POLL_PRESENCE 0
#define _GLFW_POLL_AXES 1
#define _GLFW_POLL_BUTTONS 2
#define _GLFW_POLL_ALL (_GLFW_POLL_AXES | _GLFW_POLL_BUTTONS)
#define _GLFW_MESSAGE_SIZE 1024
typedef int GLFWbool;
typedef unsigned long long GLFWid;
typedef struct _GLFWerror _GLFWerror;
typedef struct _GLFWinitconfig _GLFWinitconfig;
typedef struct _GLFWwndconfig _GLFWwndconfig;
typedef struct _GLFWctxconfig _GLFWctxconfig;
typedef struct _GLFWfbconfig _GLFWfbconfig;
typedef struct _GLFWcontext _GLFWcontext;
typedef struct _GLFWwindow _GLFWwindow;
typedef struct _GLFWlibrary _GLFWlibrary;
typedef struct _GLFWmonitor _GLFWmonitor;
typedef struct _GLFWcursor _GLFWcursor;
typedef struct _GLFWmapelement _GLFWmapelement;
typedef struct _GLFWmapping _GLFWmapping;
typedef struct _GLFWjoystick _GLFWjoystick;
typedef struct _GLFWtls _GLFWtls;
typedef struct _GLFWmutex _GLFWmutex;
typedef void (* _GLFWmakecontextcurrentfun)(_GLFWwindow*);
typedef void (* _GLFWswapbuffersfun)(_GLFWwindow*);
typedef void (* _GLFWswapintervalfun)(int);
typedef int (* _GLFWextensionsupportedfun)(const char*);
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_UNSIGNED_BYTE 0x1401
#define GL_EXTENSIONS 0x1f03
#define GL_NUM_EXTENSIONS 0x821d
#define GL_CONTEXT_FLAGS 0x821e
#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001
#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
#define GL_CONTEXT_PROFILE_MASK 0x9126
#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
#define GL_NO_RESET_NOTIFICATION_ARB 0x8261
#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82fb
#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82fc
#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008
typedef int GLint;
typedef unsigned int GLuint;
typedef unsigned int GLenum;
typedef unsigned int GLbitfield;
typedef unsigned char GLubyte;
typedef void (APIENTRY * PFNGLCLEARPROC)(GLbitfield);
typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGPROC)(GLenum);
typedef void (APIENTRY * PFNGLGETINTEGERVPROC)(GLenum,GLint*);
typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint);
#define VK_NULL_HANDLE 0
typedef void* VkInstance;
typedef void* VkPhysicalDevice;
typedef uint64_t VkSurfaceKHR;
typedef uint32_t VkFlags;
typedef uint32_t VkBool32;
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_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000,
VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
} VkStructureType;
typedef enum VkResult
{
VK_SUCCESS = 0,
VK_NOT_READY = 1,
VK_TIMEOUT = 2,
VK_EVENT_SET = 3,
VK_EVENT_RESET = 4,
VK_INCOMPLETE = 5,
VK_ERROR_OUT_OF_HOST_MEMORY = -1,
VK_ERROR_OUT_OF_DEVICE_MEMORY = -2,
VK_ERROR_INITIALIZATION_FAILED = -3,
VK_ERROR_DEVICE_LOST = -4,
VK_ERROR_MEMORY_MAP_FAILED = -5,
VK_ERROR_LAYER_NOT_PRESENT = -6,
VK_ERROR_EXTENSION_NOT_PRESENT = -7,
VK_ERROR_FEATURE_NOT_PRESENT = -8,
VK_ERROR_INCOMPATIBLE_DRIVER = -9,
VK_ERROR_TOO_MANY_OBJECTS = -10,
VK_ERROR_FORMAT_NOT_SUPPORTED = -11,
VK_ERROR_SURFACE_LOST_KHR = -1000000000,
VK_SUBOPTIMAL_KHR = 1000001003,
VK_ERROR_OUT_OF_DATE_KHR = -1000001004,
VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001,
VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001,
VK_ERROR_VALIDATION_FAILED_EXT = -1000011001,
VK_RESULT_MAX_ENUM = 0x7FFFFFFF
} VkResult;
typedef struct VkAllocationCallbacks VkAllocationCallbacks;
typedef struct VkExtensionProperties
{
char extensionName[256];
uint32_t specVersion;
} VkExtensionProperties;
typedef void (APIENTRY * PFN_vkVoidFunction)(void);
#if defined(_GLFW_VULKAN_STATIC)
PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance,const char*);
VkResult vkEnumerateInstanceExtensionProperties(const char*,uint32_t*,VkExtensionProperties*);
#else
typedef PFN_vkVoidFunction (APIENTRY * PFN_vkGetInstanceProcAddr)(VkInstance,const char*);
typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const char*,uint32_t*,VkExtensionProperties*);
#define vkEnumerateInstanceExtensionProperties _glfw.vk.EnumerateInstanceExtensionProperties
#define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr
#endif
#if defined(_GLFW_COCOA)
#include "cocoa_platform.h"
#elif defined(_GLFW_WIN32)
#include "win32_platform.h"
#elif defined(_GLFW_X11)
#include "x11_platform.h"
#elif defined(_GLFW_WAYLAND)
#include "wl_platform.h"
#elif defined(_GLFW_OSMESA)
#include "null_platform.h"
#else
#error "No supported window creation API selected"
#endif
// 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)
#define _GLFW_VERSION_NUMBER _GLFW_MAKE_VERSION(GLFW_VERSION_MAJOR, \
GLFW_VERSION_MINOR, \
GLFW_VERSION_REVISION)
// Checks for whether the library has been initialized
#define _GLFW_REQUIRE_INIT() \
if (!_glfw.initialized) \
{ \
_glfwInputError(GLFW_NOT_INITIALIZED, NULL); \
return; \
}
#define _GLFW_REQUIRE_INIT_OR_RETURN(x) \
if (!_glfw.initialized) \
{ \
_glfwInputError(GLFW_NOT_INITIALIZED, NULL); \
return x; \
}
// Swaps the provided pointers
#define _GLFW_SWAP_POINTERS(x, y) \
{ \
void* t; \
t = x; \
x = y; \
y = t; \
}
// Per-thread error structure
//
struct _GLFWerror
{
_GLFWerror* next;
int code;
char description[_GLFW_MESSAGE_SIZE];
};
// Initialization configuration
//
// Parameters relating to the initialization of the library
//
struct _GLFWinitconfig
{
GLFWbool hatButtons;
GLFWbool debugKeyboard;
GLFWbool enableJoysticks;
struct {
GLFWbool menubar;
GLFWbool chdir;
} ns;
};
// Window configuration
//
// Parameters relating to the creation of the window but not directly related
// to the framebuffer. This is used to pass window creation parameters from
// shared code to the platform API.
//
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;
struct {
GLFWbool retina;
char frameName[256];
} ns;
struct {
char className[256];
char instanceName[256];
} x11;
struct {
char appId[256];
} wl;
};
// Context configuration
//
// Parameters relating to the creation of the context but not directly related
// to the framebuffer. This is used to pass context creation parameters from
// shared code to the platform API.
//
struct _GLFWctxconfig
{
int client;
int source;
int major;
int minor;
GLFWbool forward;
GLFWbool debug;
GLFWbool noerror;
int profile;
int robustness;
int release;
_GLFWwindow* share;
struct {
GLFWbool offline;
} nsgl;
};
// Framebuffer configuration
//
// This describes buffers and their sizes. It also contains
// a platform-specific ID used to map back to the backend API object.
//
// It is used to pass framebuffer parameters from shared code to the platform
// API and also to enumerate and select available framebuffer configs.
//
struct _GLFWfbconfig
{
int redBits;
int greenBits;
int blueBits;
int alphaBits;
int depthBits;
int stencilBits;
int accumRedBits;
int accumGreenBits;
int accumBlueBits;
int accumAlphaBits;
int auxBuffers;
GLFWbool stereo;
int samples;
GLFWbool sRGB;
GLFWbool doublebuffer;
GLFWbool transparent;
uintptr_t handle;
};
// Context structure
//
struct _GLFWcontext
{
int client;
int source;
int major, minor, revision;
GLFWbool forward, debug, noerror;
int profile;
int robustness;
int release;
PFNGLGETSTRINGIPROC GetStringi;
PFNGLGETINTEGERVPROC GetIntegerv;
PFNGLGETSTRINGPROC GetString;
_GLFWmakecontextcurrentfun makeCurrent;
_GLFWswapbuffersfun swapBuffers;
_GLFWswapintervalfun swapInterval;
_GLFWextensionsupportedfun extensionSupported;
_GLFWgetprocaddressfun getProcAddress;
_GLFWdestroycontextfun destroy;
// This is defined in the context API's context.h
_GLFW_PLATFORM_CONTEXT_STATE;
// This is defined in egl_context.h
_GLFW_EGL_CONTEXT_STATE;
// This is defined in osmesa_context.h
_GLFW_OSMESA_CONTEXT_STATE;
};
// Window and context structure
//
struct _GLFWwindow
{
struct _GLFWwindow* next;
// Window settings and state
GLFWbool resizable;
GLFWbool decorated;
GLFWbool autoIconify;
GLFWbool floating;
GLFWbool focusOnShow;
GLFWbool shouldClose;
void* userPointer;
GLFWid id;
GLFWvidmode videoMode;
_GLFWmonitor* monitor;
_GLFWcursor* cursor;
int minwidth, minheight;
int maxwidth, maxheight;
int numer, denom;
GLFWbool stickyKeys;
GLFWbool stickyMouseButtons;
GLFWbool lockKeyMods;
int cursorMode;
char mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1];
char keys[GLFW_KEY_LAST + 1];
// Virtual cursor position when cursor is disabled
double virtualCursorPosX, virtualCursorPosY;
_GLFWcontext context;
struct {
GLFWwindowposfun pos;
GLFWwindowsizefun size;
GLFWwindowclosefun close;
GLFWwindowrefreshfun refresh;
GLFWwindowfocusfun focus;
GLFWwindowiconifyfun iconify;
GLFWwindowmaximizefun maximize;
GLFWframebuffersizefun fbsize;
GLFWwindowcontentscalefun scale;
GLFWmousebuttonfun mouseButton;
GLFWcursorposfun cursorPos;
GLFWcursorenterfun cursorEnter;
GLFWscrollfun scroll;
GLFWkeyboardfun keyboard;
GLFWdropfun drop;
} callbacks;
// This is defined in the window API's platform.h
_GLFW_PLATFORM_WINDOW_STATE;
};
// Monitor structure
//
struct _GLFWmonitor
{
char* name;
void* userPointer;
// Physical dimensions in millimeters.
int widthMM, heightMM;
// The window whose video mode is current on this monitor
_GLFWwindow* window;
GLFWvidmode* modes;
int modeCount;
GLFWvidmode currentMode;
GLFWgammaramp originalRamp;
GLFWgammaramp currentRamp;
// This is defined in the window API's platform.h
_GLFW_PLATFORM_MONITOR_STATE;
};
// Cursor structure
//
struct _GLFWcursor
{
_GLFWcursor* next;
// This is defined in the window API's platform.h
_GLFW_PLATFORM_CURSOR_STATE;
};
// Gamepad mapping element structure
//
struct _GLFWmapelement
{
uint8_t type;
uint8_t index;
int8_t axisScale;
int8_t axisOffset;
};
// Gamepad mapping structure
//
struct _GLFWmapping
{
char name[128];
char guid[33];
_GLFWmapelement buttons[15];
_GLFWmapelement axes[6];
};
// Joystick structure
//
struct _GLFWjoystick
{
GLFWbool present;
float* axes;
int axisCount;
unsigned char* buttons;
int buttonCount;
unsigned char* hats;
int hatCount;
char* name;
void* userPointer;
char guid[33];
_GLFWmapping* mapping;
// This is defined in the joystick API's joystick.h
_GLFW_PLATFORM_JOYSTICK_STATE;
};
// Thread local storage structure
//
struct _GLFWtls
{
// This is defined in the platform's thread.h
_GLFW_PLATFORM_TLS_STATE;
};
// Mutex structure
//
struct _GLFWmutex
{
// This is defined in the platform's thread.h
_GLFW_PLATFORM_MUTEX_STATE;
};
// Library global data
//
struct _GLFWlibrary
{
GLFWbool initialized;
struct {
_GLFWinitconfig init;
_GLFWfbconfig framebuffer;
_GLFWwndconfig window;
_GLFWctxconfig context;
int refreshRate;
} hints;
_GLFWerror* errorListHead;
_GLFWcursor* cursorListHead;
_GLFWwindow* windowListHead;
GLFWid focusedWindowId;
_GLFWmonitor** monitors;
int monitorCount;
_GLFWjoystick joysticks[GLFW_JOYSTICK_LAST + 1];
_GLFWmapping* mappings;
int mappingCount;
_GLFWtls errorSlot;
_GLFWtls contextSlot;
_GLFWmutex errorLock;
struct {
uint64_t offset;
// This is defined in the platform's time.h
_GLFW_PLATFORM_LIBRARY_TIMER_STATE;
} timer;
struct {
GLFWbool available;
void* handle;
char* extensions[2];
#if !defined(_GLFW_VULKAN_STATIC)
PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
#endif
GLFWbool KHR_surface;
#if defined(_GLFW_WIN32)
GLFWbool KHR_win32_surface;
#elif defined(_GLFW_COCOA)
GLFWbool MVK_macos_surface;
#elif defined(_GLFW_X11)
GLFWbool KHR_xlib_surface;
GLFWbool KHR_xcb_surface;
#elif defined(_GLFW_WAYLAND)
GLFWbool KHR_wayland_surface;
#endif
} vk;
struct {
GLFWmonitorfun monitor;
GLFWjoystickfun joystick;
} callbacks;
// This is defined in the window API's platform.h
_GLFW_PLATFORM_LIBRARY_WINDOW_STATE;
// This is defined in the context API's context.h
_GLFW_PLATFORM_LIBRARY_CONTEXT_STATE;
// This is defined in the platform's joystick.h
_GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE;
// This is defined in egl_context.h
_GLFW_EGL_LIBRARY_CONTEXT_STATE;
// This is defined in osmesa_context.h
_GLFW_OSMESA_LIBRARY_CONTEXT_STATE;
};
// Global state shared between compilation units of GLFW
//
extern _GLFWlibrary _glfw;
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
int _glfwPlatformInit(void);
void _glfwPlatformTerminate(void);
const char* _glfwPlatformGetVersionString(void);
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos);
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);
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor);
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor);
const char* _glfwPlatformGetScancodeName(int scancode);
int _glfwPlatformGetKeyScancode(int key);
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor);
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos);
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
float* xscale, float* yscale);
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count);
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode);
GLFWbool _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);
uint64_t _glfwPlatformGetTimerValue(void);
uint64_t _glfwPlatformGetTimerFrequency(void);
int _glfwPlatformCreateWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
void _glfwPlatformDestroyWindow(_GLFWwindow* window);
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title);
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
int count, const GLFWimage* images);
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos);
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos);
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height);
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height);
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
int minwidth, int minheight,
int maxwidth, int maxheight);
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom);
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height);
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);
void _glfwPlatformShowWindow(_GLFWwindow* window);
void _glfwPlatformHideWindow(_GLFWwindow* window);
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window);
int _glfwPlatformWindowBell(_GLFWwindow* window);
void _glfwPlatformFocusWindow(_GLFWwindow* window);
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor,
int xpos, int ypos, int width, int height,
int refreshRate);
int _glfwPlatformWindowFocused(_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 _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity);
void _glfwPlatformUpdateIMEState(_GLFWwindow *w, int which, int a, int b, int c, int d);
void _glfwPlatformPollEvents(void);
void _glfwPlatformWaitEvents(void);
void _glfwPlatformWaitEventsTimeout(double timeout);
void _glfwPlatformPostEmptyEvent(void);
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions);
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily);
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
_GLFWwindow* window,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface);
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls);
void _glfwPlatformDestroyTls(_GLFWtls* tls);
void* _glfwPlatformGetTls(_GLFWtls* tls);
void _glfwPlatformSetTls(_GLFWtls* tls, void* value);
GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex);
void _glfwPlatformDestroyMutex(_GLFWmutex* mutex);
void _glfwPlatformLockMutex(_GLFWmutex* mutex);
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex);
//////////////////////////////////////////////////////////////////////////
////// GLFW event API //////
//////////////////////////////////////////////////////////////////////////
void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused);
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 _glfwInputWindowDamage(_GLFWwindow* window);
void _glfwInputWindowCloseRequest(_GLFWwindow* window);
void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor);
void _glfwInputKeyboard(_GLFWwindow* window, int key, int scancode, int action, int mods, const char* text, int state);
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 _glfwInputDrop(_GLFWwindow* window, int count, const char** names);
void _glfwInputJoystick(_GLFWjoystick* js, int event);
void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value);
void _glfwInputJoystickButton(_GLFWjoystick* js, int button, char value);
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__)
void _glfwInputError(int code, const char* format, ...)
__attribute__((format(printf, 2, 3)));
#else
void _glfwInputError(int code, const char* format, ...);
#endif
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions);
const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
const _GLFWfbconfig* alternatives,
unsigned int count);
GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig);
GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig);
const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor,
const GLFWvidmode* desired);
int _glfwCompareVideoModes(const GLFWvidmode* first, const GLFWvidmode* second);
_GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM);
void _glfwFreeMonitor(_GLFWmonitor* monitor);
void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size);
void _glfwFreeGammaArrays(GLFWgammaramp* ramp);
void _glfwSplitBPP(int bpp, int* red, int* green, int* blue);
_GLFWjoystick* _glfwAllocJoystick(const char* name,
const char* guid,
int axisCount,
int buttonCount,
int hatCount);
void _glfwFreeJoystick(_GLFWjoystick* js);
const char* _glfwGetKeyName(int key);
GLFWbool _glfwInitVulkan(int mode);
void _glfwTerminateVulkan(void);
const char* _glfwGetVulkanResultString(VkResult result);
_GLFWwindow* _glfwFocusedWindow();
_GLFWwindow* _glfwWindowForId(GLFWid id);
char* _glfw_strdup(const char* source);

433
glfw/linux_joystick.c vendored Normal file
View File

@@ -0,0 +1,433 @@
//========================================================================
// GLFW 3.3 Linux - 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 <sys/types.h>
#include <sys/stat.h>
#include <sys/inotify.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifndef SYN_DROPPED // < v2.6.39 kernel headers
// Workaround for CentOS-6, which is supported till 2020-11-30, but still on v2.6.32
#define SYN_DROPPED 3
#endif
// Apply an EV_KEY event to the specified joystick
//
static void handleKeyEvent(_GLFWjoystick* js, int code, int value)
{
_glfwInputJoystickButton(js,
js->linjs.keyMap[code - BTN_MISC],
value ? GLFW_PRESS : GLFW_RELEASE);
}
// Apply an EV_ABS event to the specified joystick
//
static void handleAbsEvent(_GLFWjoystick* js, int code, int value)
{
const int index = js->linjs.absMap[code];
if (code >= ABS_HAT0X && code <= ABS_HAT3Y)
{
static const char stateMap[3][3] =
{
{ GLFW_HAT_CENTERED, GLFW_HAT_UP, GLFW_HAT_DOWN },
{ GLFW_HAT_LEFT, GLFW_HAT_LEFT_UP, GLFW_HAT_LEFT_DOWN },
{ GLFW_HAT_RIGHT, GLFW_HAT_RIGHT_UP, GLFW_HAT_RIGHT_DOWN },
};
const int hat = (code - ABS_HAT0X) / 2;
const int axis = (code - ABS_HAT0X) % 2;
int* state = js->linjs.hats[hat];
// NOTE: Looking at several input drivers, it seems all hat events use
// -1 for left / up, 0 for centered and 1 for right / down
if (value == 0)
state[axis] = 0;
else if (value < 0)
state[axis] = 1;
else if (value > 0)
state[axis] = 2;
_glfwInputJoystickHat(js, index, stateMap[state[0]][state[1]]);
}
else
{
const struct input_absinfo* info = &js->linjs.absInfo[code];
float normalized = value;
const int range = info->maximum - info->minimum;
if (range)
{
// Normalize to 0.0 -> 1.0
normalized = (normalized - info->minimum) / range;
// Normalize to -1.0 -> 1.0
normalized = normalized * 2.0f - 1.0f;
}
_glfwInputJoystickAxis(js, index, normalized);
}
}
// Poll state of absolute axes
//
static void pollAbsState(_GLFWjoystick* js)
{
int code;
for (code = 0; code < ABS_CNT; code++)
{
if (js->linjs.absMap[code] < 0)
continue;
struct input_absinfo* info = &js->linjs.absInfo[code];
if (ioctl(js->linjs.fd, EVIOCGABS(code), info) < 0)
continue;
handleAbsEvent(js, code, info->value);
}
}
#define isBitSet(bit, arr) (arr[(bit) / 8] & (1 << ((bit) % 8)))
// Attempt to open the specified joystick device
//
static GLFWbool openJoystickDevice(const char* path)
{
int jid, code;
char name[256] = "";
char guid[33] = "";
char evBits[(EV_CNT + 7) / 8] = {0};
char keyBits[(KEY_CNT + 7) / 8] = {0};
char absBits[(ABS_CNT + 7) / 8] = {0};
int axisCount = 0, buttonCount = 0, hatCount = 0;
struct input_id id;
_GLFWjoystickLinux linjs = {0};
_GLFWjoystick* js = NULL;
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
if (!_glfw.joysticks[jid].present)
continue;
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
return GLFW_FALSE;
}
linjs.fd = open(path, O_RDONLY | O_NONBLOCK);
if (linjs.fd == -1)
return GLFW_FALSE;
if (ioctl(linjs.fd, EVIOCGBIT(0, sizeof(evBits)), evBits) < 0 ||
ioctl(linjs.fd, EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits) < 0 ||
ioctl(linjs.fd, EVIOCGBIT(EV_ABS, sizeof(absBits)), absBits) < 0 ||
ioctl(linjs.fd, EVIOCGID, &id) < 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Linux: Failed to query input device: %s",
strerror(errno));
close(linjs.fd);
return GLFW_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;
}
if (ioctl(linjs.fd, EVIOCGNAME(sizeof(name)), name) < 0)
strncpy(name, "Unknown", sizeof(name));
// Generate a joystick GUID that matches the SDL 2.0.5+ one
if (id.vendor && id.product && id.version)
{
sprintf(guid, "%02x%02x0000%02x%02x0000%02x%02x0000%02x%02x0000",
id.bustype & 0xff, id.bustype >> 8,
id.vendor & 0xff, id.vendor >> 8,
id.product & 0xff, id.product >> 8,
id.version & 0xff, id.version >> 8);
}
else
{
sprintf(guid, "%02x%02x0000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
id.bustype & 0xff, id.bustype >> 8,
name[0], name[1], name[2], name[3],
name[4], name[5], name[6], name[7],
name[8], name[9], name[10]);
}
for (code = BTN_MISC; code < KEY_CNT; code++)
{
if (!isBitSet(code, keyBits))
continue;
linjs.keyMap[code - BTN_MISC] = buttonCount;
buttonCount++;
}
for (code = 0; code < ABS_CNT; code++)
{
linjs.absMap[code] = -1;
if (!isBitSet(code, absBits))
continue;
if (code >= ABS_HAT0X && code <= ABS_HAT3Y)
{
linjs.absMap[code] = hatCount;
hatCount++;
// Skip the Y axis
code++;
}
else
{
if (ioctl(linjs.fd, EVIOCGABS(code), &linjs.absInfo[code]) < 0)
continue;
linjs.absMap[code] = axisCount;
axisCount++;
}
}
js = _glfwAllocJoystick(name, guid, axisCount, buttonCount, hatCount);
if (!js)
{
close(linjs.fd);
return GLFW_FALSE;
}
strncpy(linjs.path, path, sizeof(linjs.path) - 1);
memcpy(&js->linjs, &linjs, sizeof(linjs));
pollAbsState(js);
_glfwInputJoystick(js, GLFW_CONNECTED);
return GLFW_TRUE;
}
#undef isBitSet
// Frees all resources associated with the specified joystick
//
static void closeJoystick(_GLFWjoystick* js)
{
close(js->linjs.fd);
_glfwFreeJoystick(js);
_glfwInputJoystick(js, GLFW_DISCONNECTED);
}
// Lexically compare joysticks by name; used by qsort
//
static int compareJoysticks(const void* fp, const void* sp)
{
const _GLFWjoystick* fj = fp;
const _GLFWjoystick* sj = sp;
return strcmp(fj->linjs.path, sj->linjs.path);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Initialize joystick interface
//
GLFWbool _glfwInitJoysticksLinux(void)
{
DIR* dir;
int count = 0;
const char* dirname = "/dev/input";
_glfw.linjs.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
if (_glfw.linjs.inotify > 0)
{
// HACK: Register for IN_ATTRIB to get notified when udev is done
// This works well in practice but the true way is libudev
_glfw.linjs.watch = inotify_add_watch(_glfw.linjs.inotify,
dirname,
IN_CREATE | IN_ATTRIB | IN_DELETE);
}
// Continue without device connection notifications if inotify fails
if (regcomp(&_glfw.linjs.regex, "^event[0-9]\\+$", 0) != 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "Linux: Failed to compile regex");
return GLFW_FALSE;
}
dir = opendir(dirname);
if (dir)
{
struct dirent* entry;
while ((entry = readdir(dir)))
{
regmatch_t match;
if (regexec(&_glfw.linjs.regex, entry->d_name, 1, &match, 0) != 0)
continue;
char path[PATH_MAX];
snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name);
if (openJoystickDevice(path))
count++;
}
closedir(dir);
}
// Continue with no joysticks if enumeration fails
qsort(_glfw.joysticks, count, sizeof(_GLFWjoystick), compareJoysticks);
return GLFW_TRUE;
}
// Close all opened joystick handles
//
void _glfwTerminateJoysticksLinux(void)
{
int jid;
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
_GLFWjoystick* js = _glfw.joysticks + jid;
if (js->present)
closeJoystick(js);
}
regfree(&_glfw.linjs.regex);
if (_glfw.linjs.inotify > 0)
{
if (_glfw.linjs.watch > 0)
inotify_rm_watch(_glfw.linjs.inotify, _glfw.linjs.watch);
close(_glfw.linjs.inotify);
}
}
void _glfwDetectJoystickConnectionLinux(void)
{
ssize_t offset = 0;
char buffer[16384];
if (_glfw.linjs.inotify <= 0)
return;
const ssize_t size = read(_glfw.linjs.inotify, buffer, sizeof(buffer));
while (size > offset)
{
regmatch_t match;
const struct inotify_event* e = (struct inotify_event*) (buffer + offset);
offset += sizeof(struct inotify_event) + e->len;
if (regexec(&_glfw.linjs.regex, e->name, 1, &match, 0) != 0)
continue;
char path[PATH_MAX];
snprintf(path, sizeof(path), "/dev/input/%s", e->name);
if (e->mask & (IN_CREATE | IN_ATTRIB))
openJoystickDevice(path);
else if (e->mask & IN_DELETE)
{
int jid;
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
{
closeJoystick(_glfw.joysticks + jid);
break;
}
}
}
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
{
// Read all queued events (non-blocking)
for (;;)
{
struct input_event e;
errno = 0;
if (read(js->linjs.fd, &e, sizeof(e)) < 0)
{
// Reset the joystick slot if the device was disconnected
if (errno == ENODEV)
closeJoystick(js);
break;
}
if (e.type == EV_SYN)
{
if (e.code == SYN_DROPPED)
_glfw.linjs.dropped = GLFW_TRUE;
else if (e.code == SYN_REPORT)
{
_glfw.linjs.dropped = GLFW_FALSE;
pollAbsState(js);
}
}
if (_glfw.linjs.dropped)
continue;
if (e.type == EV_KEY)
handleKeyEvent(js, e.code, e.value);
else if (e.type == EV_ABS)
handleAbsEvent(js, e.code, e.value);
}
return js->present;
}
void _glfwPlatformUpdateGamepadGUID(char* guid)
{
}

62
glfw/linux_joystick.h vendored Normal file
View File

@@ -0,0 +1,62 @@
//========================================================================
// GLFW 3.3 Linux - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
//
// 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 <linux/input.h>
#include <linux/limits.h>
#include <regex.h>
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickLinux linjs
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs
#define _GLFW_PLATFORM_MAPPING_NAME "Linux"
// Linux-specific joystick data
//
typedef struct _GLFWjoystickLinux
{
int fd;
char path[PATH_MAX];
int keyMap[KEY_CNT - BTN_MISC];
int absMap[ABS_CNT];
struct input_absinfo absInfo[ABS_CNT];
int hats[4][2];
} _GLFWjoystickLinux;
// Linux-specific joystick API data
//
typedef struct _GLFWlibraryLinux
{
int inotify;
int watch;
regex_t regex;
GLFWbool dropped;
} _GLFWlibraryLinux;
GLFWbool _glfwInitJoysticksLinux(void);
void _glfwTerminateJoysticksLinux(void);
void _glfwDetectJoystickConnectionLinux(void);

478
glfw/mappings.h vendored Normal file
View File

@@ -0,0 +1,478 @@
//========================================================================
// GLFW 3.3 - 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.
//
//========================================================================
// As mappings.h.in, this file is used by CMake to produce the mappings.h
// header file. If you are adding a GLFW specific gamepad mapping, this is
// where to put it.
//========================================================================
// As mappings.h, this provides all pre-defined gamepad mappings, including
// all available in SDL_GameControllerDB. Do not edit this file. Any gamepad
// mappings not specific to GLFW should be submitted to SDL_GameControllerDB.
// This file can be re-generated from mappings.h.in and the upstream
// gamecontrollerdb.txt with the GenerateMappings.cmake script.
//========================================================================
// All gamepad mappings not labeled GLFW are copied from the
// SDL_GameControllerDB project under the following license:
//
// Simple DirectMedia Layer
// Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.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.
const char* _glfwDefaultMappings[] =
{
"03000000fa2d00000100000000000000,3DRUDDER,leftx:a0,lefty:a1,rightx:a5,righty:a2,platform:Windows,",
"03000000022000000090000000000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",
"03000000203800000900000000000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",
"03000000102800000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,",
"03000000a00500003232000000000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,",
"030000008f0e00001200000000000000,Acme,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows,",
"03000000341a00003608000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000c01100001352000000000000,Battalife Joystick,a:b6,b:b7,back:b2,leftshoulder:b0,leftx:a0,lefty:a1,rightshoulder:b1,start:b3,x:b4,y:b5,platform:Windows,",
"030000006b1400000055000000000000,bigben ps3padstreetnew,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",
"0300000066f700000500000000000000,BrutalLegendTest,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,",
"03000000d81d00000b00000000000000,BUFFALO BSGP1601 Series ,a:b5,b:b3,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b4,y:b2,platform:Windows,",
"03000000e82000006058000000000000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",
"030000005e0400008e02000000000000,Controller (XBOX 360 For Windows),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",
"03000000260900008888000000000000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a4,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Windows,",
"03000000a306000022f6000000000000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",
"03000000791d00000103000000000000,Dual Box WII,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",
"030000004f04000023b3000000000000,Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"03000000341a00000108000000000000,EXEQ RF USB Gamepad 8206,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",
"030000000d0f00008500000000000000,Fighting Commander 2016 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00008400000000000000,Fighting Commander 5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00008800000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,",
"030000000d0f00008700000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00002700000000000000,FIGHTING STICK V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
"78696e70757403000000000000000000,Fightstick TES,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Windows,",
"03000000790000000600000000000000,G-Shark GS-GP702,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,",
"03000000260900002625000000000000,Gamecube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Windows,",
"030000008f0e00000d31000000000000,GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000280400000140000000000000,GamePad Pro USB,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
"03000000ffff00000000000000000000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",
"03000000451300000010000000000000,Generic USB Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",
"03000000341a00000302000000000000,Hama Scorpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00004900000000000000,Hatsune Miku Sho Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000d81400000862000000000000,HitBox Edition Cthulhu+,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00005f00000000000000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00005e00000000000000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00004000000000000000,Hori Fighting Stick Mini 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00006e00000000000000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00006600000000000000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f0000ee00000000000000,HORIPAD mini4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00004d00000000000000,HORIPAD3 A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000250900000017000000000000,HRAP2 on PS/SS/N64 Joypad to USB BOX,a:b2,b:b1,back:b9,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b8,x:b3,y:b0,platform:Windows,",
"030000008f0e00001330000000000000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Windows,",
"03000000d81d00000f00000000000000,iBUFFALO BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",
"03000000d81d00001000000000000000,iBUFFALO BSGP1204P Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",
"03000000830500006020000000000000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Windows,",
"03000000b50700001403000000000000,IMPACT BLACK,a:b2,b:b3,back:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,",
"030000006f0e00002401000000000000,INJUSTICE FightStick for PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
"03000000491900000204000000000000,Ipega PG-9023,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",
"030000006d04000011c2000000000000,Logitech Cordless Wingman,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b5,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b2,righttrigger:b7,rightx:a3,righty:a4,x:b4,platform:Windows,",
"030000006d04000016c2000000000000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000006d04000018c2000000000000,Logitech F510 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000006d04000019c2000000000000,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000380700005032000000000000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000380700005082000000000000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"03000000380700008433000000000000,Mad Catz FightStick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
"03000000380700008483000000000000,Mad Catz FightStick TE S+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b6,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"03000000380700008134000000000000,Mad Catz FightStick TE2+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000380700008184000000000000,Mad Catz FightStick TE2+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"03000000380700008034000000000000,Mad Catz TE2 PS3 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000380700008084000000000000,Mad Catz TE2 PS4 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"03000000380700008532000000000000,Madcatz Arcade Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000380700003888000000000000,Madcatz Arcade Fightstick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000380700001888000000000000,MadCatz SFIV FightStick PS3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",
"03000000380700008081000000000000,MADCATZ SFV Arcade FightStick Alpha PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"030000008305000031b0000000000000,MaxfireBlaze3,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",
"03000000250900000128000000000000,Mayflash Arcade Stick,a:b1,b:b2,back:b8,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b5,y:b6,platform:Windows,",
"03000000790000004418000000000000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,",
"03000000790000004318000000000000,Mayflash GameCube Controller Adapter,a:b1,b:b2,back:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b0,leftshoulder:b4,leftstick:b0,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b0,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,",
"030000008f0e00001030000000000000,Mayflash USB Adapter for original Sega Saturn controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,rightshoulder:b2,righttrigger:b7,start:b9,x:b3,y:b4,platform:Windows,",
"0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,",
"03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000001008000001e5000000000000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,platform:Windows,",
"03000000bd12000015d0000000000000,Nintendo Retrolink USB Super SNES Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,",
"030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",
"030000004b120000014d000000000000,NYKO AIRFLO,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a3,leftstick:a0,lefttrigger:b6,leftx:h0.6,lefty:h0.12,rightshoulder:b5,rightstick:a2,righttrigger:b7,rightx:h0.9,righty:h0.4,start:b9,x:b2,y:b3,platform:Windows,",
"03000000362800000100000000000000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,x:b1,y:b2,platform:Windows,",
"03000000120c0000f60e000000000000,P4 Wired Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,",
"030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",
"03000000d62000006dca000000000000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000008f0e00007530000000000000,PS (R) Gamepad,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b1,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000e30500009605000000000000,PS to USB convert cable,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,",
"03000000100800000100000000000000,PS1 USB,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",
"03000000100800000300000000000000,PS2 USB,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",
"03000000888800000803000000000000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,",
"030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows,",
"03000000250900000500000000000000,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows,",
"03000000100000008200000000000000,PS360+ v1.66,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:h0.4,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
"030000004c050000a00b000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"030000004c050000cc09000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"03000000300f00000011000000000000,QanBa Arcade JoyStick 1008,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b10,x:b0,y:b3,platform:Windows,",
"03000000300f00001611000000000000,QanBa Arcade JoyStick 4018,a:b1,b:b2,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,",
"03000000222c00000020000000000000,QANBA DRONE ARCADE JOYSTICK,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,platform:Windows,",
"03000000300f00001210000000000000,QanBa Joystick Plus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,",
"03000000341a00000104000000000000,QanBa Joystick Q4RAF,a:b5,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b1,y:b2,platform:Windows,",
"03000000222c00000223000000000000,Qanba Obsidian Arcade Joystick PS3 Mode,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"03000000222c00000023000000000000,Qanba Obsidian Arcade Joystick PS4 Mode,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"03000000321500000003000000000000,Razer Hydra,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",
"030000000d0f00001100000000000000,REAL ARCADE PRO.3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00008b00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00008a00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00006b00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00006a00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00007000000000000000,REAL ARCADE PRO.4 VLX,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00002200000000000000,REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00005c00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000000d0f00005b00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"03000000790000001100000000000000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,",
"0300000000f000000300000000000000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,",
"0300000000f00000f100000000000000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,",
"030000006b140000010d000000000000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"030000006f0e00001e01000000000000,Rock Candy Gamepad for PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
"030000004f04000003d0000000000000,run'n'drive,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:a3,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:a4,rightstick:b11,righttrigger:b5,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
"03000000a30600001af5000000000000,Saitek Cyborg,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",
"03000000a306000023f6000000000000,Saitek Cyborg V.1 Game pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",
"03000000300f00001201000000000000,Saitek Dual Analog Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,",
"03000000a30600000cff000000000000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,x:b0,y:b1,platform:Windows,",
"03000000a30600000c04000000000000,Saitek P2900,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,",
"03000000300f00001001000000000000,Saitek P480 Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,",
"03000000a30600000b04000000000000,Saitek P990,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,",
"03000000a30600000b04000000010000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Windows,",
"03000000300f00001101000000000000,saitek rumble pad,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,",
"0300000000050000289b000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,",
"030000009b2800000500000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,",
"03000000341a00000208000000000000,SL-6555-SBK,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a3,righty:a2,start:b7,x:b2,y:b3,platform:Windows,",
"030000008f0e00000800000000000000,SpeedLink Strike FX Wireless,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",
"03000000ff1100003133000000000000,SVEN X-PAD,a:b2,b:b3,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a4,start:b5,x:b0,y:b1,platform:Windows,",
"03000000fa1900000706000000000000,Team 5,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",
"03000000b50700001203000000000000,Techmobility X6-38V,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,",
"030000004f04000015b3000000000000,Thrustmaster Dual Analog 2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,",
"030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Windows,",
"030000004f04000004b3000000000000,Thrustmaster Firestorm Dual Power 3,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,",
"03000000666600000488000000000000,TigerGame PS/PS2 Game Controller Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,",
"03000000d90400000200000000000000,TwinShock PS2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",
"03000000380700006652000000000000,UnKnown,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",
"03000000632500002305000000000000,USB Vibration Joystick (BM),a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",
"03000000790000001b18000000000000,Venom Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
"03000000450c00002043000000000000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",
"03000000172700004431000000000000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a7,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,",
"03000000786901006e70000000000000,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",
"03000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",
"03000000022000000090000001000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",
"03000000102800000900000000000000,8Bitdo SFC30 GamePad Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,",
"03000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,",
"030000008305000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X,",
"03000000a306000022f6000001030000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X,",
"03000000790000000600000000000000,G-Shark GP-702,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Mac OS X,",
"03000000ad1b000001f9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
"0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,",
"030000000d0f00005f00000000010000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000000d0f00005e00000000010000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000000d0f00005f00000000000000,HORI Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000000d0f00005e00000000000000,HORI Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000000d0f00004d00000000000000,HORI Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000000d0f00006e00000000010000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000000d0f00006600000000010000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000000d0f00006600000000000000,HORIPAD FPS PLUS 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000008f0e00001330000011010000,HuiJia SNES Controller,a:b4,b:b2,back:b16,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b12,rightshoulder:b14,start:b18,x:b6,y:b0,platform:Mac OS X,",
"03000000830500006020000000010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,",
"03000000830500006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,",
"030000006d04000016c2000000020000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000006d04000016c2000000030000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000006d04000016c2000014040000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000006d04000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000006d04000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000006d0400001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
"030000006d04000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"03000000380700005032000000010000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
"03000000380700005082000000010000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"03000000790000004418000000010000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Mac OS X,",
"0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Mac OS X,",
"03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,",
"03000000d8140000cecf000000000000,MC Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000001008000001e5000006010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,platform:Mac OS X,",
"030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,",
"030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X,",
"030000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,",
"030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,",
"030000004c050000a00b000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000008916000000fd000000000000,Razer Onza TE,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
"03000000321500000010000000010000,Razer RAIJU,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"0300000032150000030a000000000000,Razer Wildcat,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
"03000000790000001100000000000000,Retrolink Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a3,lefty:a4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,",
"03000000790000001100000006010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,",
"030000006b140000010d000000010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"03000000811700007e05000000000000,Sega Saturn,a:b2,b:b4,dpdown:b16,dpleft:b15,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,leftx:a0,lefty:a2,rightshoulder:b9,righttrigger:a4,start:b13,x:b0,y:b6,platform:Mac OS X,",
"03000000b40400000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Mac OS X,",
"030000003512000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,",
"030000004c050000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000004c050000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"030000005e0400008e02000001000000,Steam Virtual GamePad,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
"03000000110100002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Mac OS X,",
"03000000110100002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,",
"03000000381000002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,",
"03000000110100001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,",
"03000000110100001714000020010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,",
"030000004f04000015b3000000000000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Mac OS X,",
"030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Mac OS X,",
"03000000bd12000015d0000000010000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,",
"03000000bd12000015d0000000000000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,",
"03000000100800000100000000000000,Twin USB Joystick,a:b4,b:b2,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b12,leftstick:b20,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b14,rightstick:b22,righttrigger:b10,rightx:a6,righty:a4,start:b18,x:b6,y:b0,platform:Mac OS X,",
"050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,back:b7,dpdown:b3,dpleft:b0,dpright:b1,dpup:b2,guide:b8,leftshoulder:b11,lefttrigger:b12,leftx:a0,lefty:a1,start:b6,x:b10,y:b9,platform:Mac OS X,",
"050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,back:b7,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b8,leftshoulder:b19,leftstick:b23,lefttrigger:b21,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b24,righttrigger:b22,rightx:a2,righty:a3,start:b6,x:b18,y:b17,platform:Mac OS X,",
"030000005e0400008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
"03000000c6240000045d000000000000,Xbox 360 Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
"030000005e040000e302000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
"030000005e040000d102000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
"030000005e040000dd02000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
"030000005e040000e002000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X,",
"030000005e040000fd02000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",
"030000005e040000ea02000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
"030000005e040000e002000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X,",
"03000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Mac OS X,",
"03000000120c0000100e000000010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",
"05000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",
"03000000022000000090000011010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",
"05000000c82d00002038000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",
"03000000c82d00000190000011010000,8Bitdo NES30 Pro 8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",
"05000000c82d00003028000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,",
"05000000102800000900000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,",
"05000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,",
"05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,",
"030000006f0e00003901000020060000,Afterglow Wired Controller for Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000100000008200000011010000,Akishop Customs PS360+ v1.66,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",
"05000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux,",
"03000000666600006706000000010000,boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux,",
"03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",
"03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Linux,",
"03000000a306000022f6000011010000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,",
"03000000b40400000a01000000010000,CYPRESS USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux,",
"03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux,",
"030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,",
"0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",
"030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000006f0e00001304000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:a0,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:a3,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000006f0e00001f01000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"03000000280400000140000000010000,Gravis GamePad Pro USB ,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",
"030000008f0e00000610000000010000,GreenAsia Electronics 4Axes 12Keys GamePad ,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Linux,",
"030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,",
"030000008f0e00000300000010010000,GreenAsia Inc. USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,",
"0500000047532067616d657061640000,GS gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",
"06000000adde0000efbe000002010000,Hidromancer Game Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,a:b1,b:b2,back:b8,guide:b9,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux,",
"03000000c9110000f055000011010000,HJC Game GAMEPAD,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",
"030000000d0f00000d00000000010000,hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftx:b4,lefty:b5,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux,",
"030000000d0f00001000000011010000,HORI CO. LTD. FIGHTING STICK 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",
"030000000d0f00006a00000011010000,HORI CO. LTD. Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"030000000d0f00006b00000011010000,HORI CO. LTD. Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"030000000d0f00002200000011010000,HORI CO. LTD. REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",
"030000000d0f00005f00000011010000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"030000000d0f00005e00000011010000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000000d0f00006e00000011010000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"030000000d0f00006600000011010000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"030000000d0f00006700000001010000,HORIPAD ONE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000008f0e00001330000010010000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Linux,",
"03000000830500006020000010010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,",
"050000006964726f69643a636f6e0000,idroid:con,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"03000000b50700001503000010010000,impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,",
"03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),a:b3,b:b4,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b7,x:b0,y:b1,platform:Linux,",
"030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux,",
"03000000300f00001001000010010000,Jess Tech Dual Analog Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,",
"03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,",
"030000006f0e00000103000000020000,Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"030000006d04000016c2000011010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"030000006d04000016c2000010010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000006d04000015c2000010010000,Logitech Logitech Extreme 3D,a:b0,b:b4,back:b6,guide:b8,leftshoulder:b9,leftstick:h0.8,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:h0.2,start:b7,x:b2,y:b5,platform:Linux,",
"030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux,",
"05000000380700006652000025010000,Mad Catz C.T.R.L.R ,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"03000000380700005032000011010000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"03000000380700005082000011010000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux,",
"03000000380700008034000011010000,Mad Catz fightstick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"03000000380700008084000011010000,Mad Catz fightstick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"03000000380700008433000011010000,Mad Catz FightStick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"03000000380700008483000011010000,Mad Catz FightStick TE S+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"03000000380700001647000010040000,Mad Catz Wired Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000380700003847000090040000,Mad Catz Wired Xbox 360 Controller (SFIV),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",
"03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000380700001888000010010000,MadCatz PC USB Wired Stick 8818,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"03000000380700003888000010010000,MadCatz PC USB Wired Stick 8838,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:a0,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"03000000790000004418000010010000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,",
"03000000780000000600000010010000,Microntek USB Joystick,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,",
"030000005e0400008e02000004010000,Microsoft X-Box 360 pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000005e0400008e02000062230000,Microsoft X-Box 360 pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000005e040000d102000001010000,Microsoft X-Box One pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000005e040000d102000003020000,Microsoft X-Box One pad v2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000005e0400008502000000010000,Microsoft X-Box pad (Japan),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,",
"030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,",
"05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,",
"030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,platform:Linux,",
"050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",
"050000007e0500003003000001000000,Nintendo Wii Remote Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,",
"05000000010000000100000003000000,Nintendo Wiimote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",
"030000000d0500000308000010010000,Nostromo n45 Dual Analog Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Linux,",
"03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,",
"03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"030000005e0400000202000000010000,Old Xbox pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,",
"05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,",
"05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,",
"03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",
"030000006f0e00006401000001010000,PDP Battlefield One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,",
"030000004c0500006802000010010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,",
"050000004c0500006802000000810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",
"03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"030000004c0500006802000011810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",
"050000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:a12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:a13,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,",
"030000004c0500006802000010810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",
"030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,",
"060000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,",
"05000000504c415953544154494f4e00,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,",
"050000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"030000004c050000a00b000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"050000004c050000cc09000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",
"050000004c050000c405000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",
"030000004c050000c405000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",
"050000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"030000004c050000cc09000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"030000004c050000a00b000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",
"030000004c050000cc09000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",
"030000004c050000c405000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"03000000300f00001211000011010000,QanBa Arcade JoyStick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,platform:Linux,",
"030000009b2800000300000001010000,raphnet.net 4nes4snes v1.5,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux,",
"030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000008916000000fd000024010000,Razer Onza Tournament,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000321500000010000011010000,Razer RAIJU,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"03000000c6240000045d000025010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000321500000009000011010000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,",
"050000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,",
"0300000032150000030a000001010000,Razer Wildcat,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000790000001100000010010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux,",
"0300000000f000000300000000010000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,",
"0300000000f00000f100000000010000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,",
"030000006b140000010d000011010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"030000006f0e00001e01000011010000,Rock Candy Gamepad for PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"030000006f0e00004601000001010000,Rock Candy Wired Controller for Xbox One,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,",
"03000000a30600000cff000010010000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux,",
"03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux,",
"03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux,",
"03000000a30600000b04000000010000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Linux,",
"03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,",
"03000000c01600008704000011010000,Serial/Keyboard/Mouse/Joystick,a:b12,b:b10,back:b4,dpdown:b2,dpleft:b3,dpright:b1,dpup:b0,leftshoulder:b9,leftstick:b14,lefttrigger:b6,leftx:a1,lefty:a0,rightshoulder:b8,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b5,x:b13,y:b11,platform:Linux,",
"03000000f025000021c1000010010000,ShanWan Gioteck PS3 Wired Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",
"03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,",
"030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,",
"05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,",
"03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,",
"05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,",
"03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,",
"03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,",
"030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,",
"030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,",
"030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Linux,",
"030000004f04000008d0000000010000,Thrustmaster Run N Drive Wireless,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"030000004f04000009d0000000010000,Thrustmaster Run N Drive Wireless PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",
"03000000bd12000015d0000010010000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux,",
"03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux,",
"03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,",
"03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,",
"03000000790000001100000000010000,USB Gamepad1,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,platform:Linux,",
"05000000ac0500003232000001000000,VR-BOX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,",
"030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000005e040000a102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"030000005e040000a102000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"0000000058626f782033363020576900,Xbox 360 Wireless Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux,",
"0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,",
"050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",
"050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",
"03000000450c00002043000010010000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",
"05000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux,",
"03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux,",
"03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"64633436313965656664373634323364,Microsoft X-Box 360 pad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,x:b2,y:b3,platform:Android,",
"61363931656135336130663561616264,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,",
"4e564944494120436f72706f72617469,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,",
"37336435666338653565313731303834,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,",
"35643031303033326130316330353564,PS4 Controller,a:b1,b:b17,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:+a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android,",
"05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Android,",
"5477696e20555342204a6f7973746963,Twin USB Joystick,a:b22,b:b21,back:b28,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b26,leftstick:b30,lefttrigger:b24,leftx:a0,lefty:a1,rightshoulder:b27,rightstick:b31,righttrigger:b25,rightx:a3,righty:a2,start:b29,x:b23,y:b20,platform:Android,",
"34356136633366613530316338376136,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,x:b17,y:b2,platform:Android,",
"4d466947616d65706164010000000000,MFi Extended Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:iOS,",
"4d466947616d65706164020000000000,MFi Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:iOS,",
"05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:iOS,",
"78696e70757401000000000000000000,XInput Gamepad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
"78696e70757402000000000000000000,XInput Wheel (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
"78696e70757403000000000000000000,XInput Arcade Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
"78696e70757404000000000000000000,XInput Flight Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
"78696e70757405000000000000000000,XInput Dance Pad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
"78696e70757406000000000000000000,XInput Guitar (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
"78696e70757408000000000000000000,XInput Drum Kit (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
NULL
};

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

517
glfw/monitor.c vendored Normal file
View File

@@ -0,0 +1,517 @@
//========================================================================
// GLFW 3.3 - 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>
#include <math.h>
#include <float.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
// Lexically compare video modes, used by qsort
//
static int compareVideoModes(const void* fp, const void* sp)
{
const GLFWvidmode* fm = fp;
const GLFWvidmode* sm = sp;
const int fbpp = fm->redBits + fm->greenBits + fm->blueBits;
const int sbpp = sm->redBits + sm->greenBits + sm->blueBits;
const int farea = fm->width * fm->height;
const int sarea = sm->width * sm->height;
// First sort on color bits per pixel
if (fbpp != sbpp)
return fbpp - sbpp;
// Then sort on screen area
if (farea != sarea)
return farea - sarea;
// Lastly sort on refresh rate
return fm->refreshRate - sm->refreshRate;
}
// Retrieves the available modes for the specified monitor
//
static GLFWbool refreshVideoModes(_GLFWmonitor* monitor)
{
int modeCount;
GLFWvidmode* modes;
if (monitor->modes)
return GLFW_TRUE;
modes = _glfwPlatformGetVideoModes(monitor, &modeCount);
if (!modes)
return GLFW_FALSE;
qsort(modes, modeCount, sizeof(GLFWvidmode), compareVideoModes);
free(monitor->modes);
monitor->modes = modes;
monitor->modeCount = modeCount;
return GLFW_TRUE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW event API //////
//////////////////////////////////////////////////////////////////////////
// Notifies shared code of a monitor connection or disconnection
//
void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement)
{
if (action == GLFW_CONNECTED)
{
_glfw.monitorCount++;
_glfw.monitors =
realloc(_glfw.monitors, sizeof(_GLFWmonitor*) * _glfw.monitorCount);
if (placement == _GLFW_INSERT_FIRST)
{
memmove(_glfw.monitors + 1,
_glfw.monitors,
(_glfw.monitorCount - 1) * sizeof(_GLFWmonitor*));
_glfw.monitors[0] = monitor;
}
else
_glfw.monitors[_glfw.monitorCount - 1] = monitor;
}
else if (action == GLFW_DISCONNECTED)
{
int i;
_GLFWwindow* window;
for (window = _glfw.windowListHead; window; window = window->next)
{
if (window->monitor == monitor)
{
int width, height, xoff, yoff;
_glfwPlatformGetWindowSize(window, &width, &height);
_glfwPlatformSetWindowMonitor(window, NULL, 0, 0, width, height, 0);
_glfwPlatformGetWindowFrameSize(window, &xoff, &yoff, NULL, NULL);
_glfwPlatformSetWindowPos(window, xoff, yoff);
}
}
for (i = 0; i < _glfw.monitorCount; i++)
{
if (_glfw.monitors[i] == monitor)
{
_glfw.monitorCount--;
memmove(_glfw.monitors + i,
_glfw.monitors + i + 1,
(_glfw.monitorCount - i) * sizeof(_GLFWmonitor*));
break;
}
}
}
if (_glfw.callbacks.monitor)
_glfw.callbacks.monitor((GLFWmonitor*) monitor, action);
if (action == GLFW_DISCONNECTED)
_glfwFreeMonitor(monitor);
}
// Notifies shared code that a full screen window has acquired or released
// a monitor
//
void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window)
{
monitor->window = window;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Allocates and returns a monitor object with the specified name and dimensions
//
_GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM)
{
_GLFWmonitor* monitor = calloc(1, sizeof(_GLFWmonitor));
monitor->widthMM = widthMM;
monitor->heightMM = heightMM;
if (name)
monitor->name = _glfw_strdup(name);
return monitor;
}
// Frees a monitor object and any data associated with it
//
void _glfwFreeMonitor(_GLFWmonitor* monitor)
{
if (monitor == NULL)
return;
_glfwPlatformFreeMonitor(monitor);
_glfwFreeGammaArrays(&monitor->originalRamp);
_glfwFreeGammaArrays(&monitor->currentRamp);
free(monitor->modes);
free(monitor->name);
free(monitor);
}
// Allocates red, green and blue value arrays of the specified size
//
void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size)
{
ramp->red = calloc(size, sizeof(unsigned short));
ramp->green = calloc(size, sizeof(unsigned short));
ramp->blue = calloc(size, sizeof(unsigned short));
ramp->size = size;
}
// Frees the red, green and blue value arrays and clears the struct
//
void _glfwFreeGammaArrays(GLFWgammaramp* ramp)
{
free(ramp->red);
free(ramp->green);
free(ramp->blue);
memset(ramp, 0, sizeof(GLFWgammaramp));
}
// Chooses the video mode most closely matching the desired one
//
const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor,
const GLFWvidmode* desired)
{
int i;
unsigned int sizeDiff, leastSizeDiff = UINT_MAX;
unsigned int rateDiff, leastRateDiff = UINT_MAX;
unsigned int colorDiff, leastColorDiff = UINT_MAX;
const GLFWvidmode* current;
const GLFWvidmode* closest = NULL;
if (!refreshVideoModes(monitor))
return NULL;
for (i = 0; i < monitor->modeCount; i++)
{
current = monitor->modes + i;
colorDiff = 0;
if (desired->redBits != GLFW_DONT_CARE)
colorDiff += abs(current->redBits - desired->redBits);
if (desired->greenBits != GLFW_DONT_CARE)
colorDiff += abs(current->greenBits - desired->greenBits);
if (desired->blueBits != GLFW_DONT_CARE)
colorDiff += abs(current->blueBits - desired->blueBits);
sizeDiff = abs((current->width - desired->width) *
(current->width - desired->width) +
(current->height - desired->height) *
(current->height - desired->height));
if (desired->refreshRate != GLFW_DONT_CARE)
rateDiff = abs(current->refreshRate - desired->refreshRate);
else
rateDiff = UINT_MAX - current->refreshRate;
if ((colorDiff < leastColorDiff) ||
(colorDiff == leastColorDiff && sizeDiff < leastSizeDiff) ||
(colorDiff == leastColorDiff && sizeDiff == leastSizeDiff && rateDiff < leastRateDiff))
{
closest = current;
leastSizeDiff = sizeDiff;
leastRateDiff = rateDiff;
leastColorDiff = colorDiff;
}
}
return closest;
}
// Performs lexical comparison between two @ref GLFWvidmode structures
//
int _glfwCompareVideoModes(const GLFWvidmode* fm, const GLFWvidmode* sm)
{
return compareVideoModes(fm, sm);
}
// Splits a color depth into red, green and blue bit depths
//
void _glfwSplitBPP(int bpp, int* red, int* green, int* blue)
{
int delta;
// We assume that by 32 the user really meant 24
if (bpp == 32)
bpp = 24;
// Convert "bits per pixel" to red, green & blue sizes
*red = *green = *blue = bpp / 3;
delta = bpp - (*red * 3);
if (delta >= 1)
*green = *green + 1;
if (delta == 2)
*red = *red + 1;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI GLFWmonitor** glfwGetMonitors(int* count)
{
assert(count != NULL);
*count = 0;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
*count = _glfw.monitorCount;
return (GLFWmonitor**) _glfw.monitors;
}
GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (!_glfw.monitorCount)
return NULL;
return (GLFWmonitor*) _glfw.monitors[0];
}
GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
if (xpos)
*xpos = 0;
if (ypos)
*ypos = 0;
_GLFW_REQUIRE_INIT();
_glfwPlatformGetMonitorPos(monitor, xpos, ypos);
}
GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
if (widthMM)
*widthMM = 0;
if (heightMM)
*heightMM = 0;
_GLFW_REQUIRE_INIT();
if (widthMM)
*widthMM = monitor->widthMM;
if (heightMM)
*heightMM = monitor->heightMM;
}
GLFWAPI void glfwGetMonitorContentScale(GLFWmonitor* handle,
float* xscale, float* yscale)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
if (xscale)
*xscale = 0.f;
if (yscale)
*yscale = 0.f;
_GLFW_REQUIRE_INIT();
_glfwPlatformGetMonitorContentScale(monitor, xscale, yscale);
}
GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return monitor->name;
}
GLFWAPI void glfwSetMonitorUserPointer(GLFWmonitor* handle, void* pointer)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
_GLFW_REQUIRE_INIT();
monitor->userPointer = pointer;
}
GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return monitor->userPointer;
}
GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(_glfw.callbacks.monitor, cbfun);
return cbfun;
}
GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* handle, int* count)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
assert(count != NULL);
*count = 0;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (!refreshVideoModes(monitor))
return NULL;
*count = monitor->modeCount;
return monitor->modes;
}
GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_glfwPlatformGetVideoMode(monitor, &monitor->currentMode);
return &monitor->currentMode;
}
GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
{
unsigned int i;
unsigned short* values;
GLFWgammaramp ramp;
const GLFWgammaramp* original;
assert(handle != NULL);
assert(gamma >= 0.f);
assert(gamma <= FLT_MAX);
_GLFW_REQUIRE_INIT();
if (gamma != gamma || gamma <= 0.f || gamma > FLT_MAX)
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid gamma value %f", gamma);
return;
}
original = glfwGetGammaRamp(handle);
if (!original)
return;
values = calloc(original->size, sizeof(unsigned short));
for (i = 0; i < original->size; i++)
{
float value;
// Calculate intensity
value = i / (float) (original->size - 1);
// Apply gamma curve
value = powf(value, 1.f / gamma) * 65535.f + 0.5f;
// Clamp to value range
if (value > 65535.f)
value = 65535.f;
values[i] = (unsigned short) value;
}
ramp.red = values;
ramp.green = values;
ramp.blue = values;
ramp.size = original->size;
glfwSetGammaRamp(handle, &ramp);
free(values);
}
GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_glfwFreeGammaArrays(&monitor->currentRamp);
if (!_glfwPlatformGetGammaRamp(monitor, &monitor->currentRamp))
return NULL;
return &monitor->currentRamp;
}
GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
assert(ramp != NULL);
assert(ramp->size > 0);
assert(ramp->red != NULL);
assert(ramp->green != NULL);
assert(ramp->blue != NULL);
if (ramp->size <= 0)
{
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid gamma ramp size %i",
ramp->size);
return;
}
_GLFW_REQUIRE_INIT();
if (!monitor->originalRamp.size)
{
if (!_glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp))
return;
}
_glfwPlatformSetGammaRamp(monitor, ramp);
}

56
glfw/nsgl_context.h vendored Normal file
View File

@@ -0,0 +1,56 @@
//========================================================================
// GLFW 3.3 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-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_CONTEXT_STATE _GLFWcontextNSGL nsgl
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl
// NSGL-specific per-context data
//
typedef struct _GLFWcontextNSGL
{
id pixelFormat;
id object;
} _GLFWcontextNSGL;
// NSGL-specific global data
//
typedef struct _GLFWlibraryNSGL
{
// dlopen handle for OpenGL.framework (for glfwGetProcAddress)
CFBundleRef framework;
} _GLFWlibraryNSGL;
GLFWbool _glfwInitNSGL(void);
void _glfwTerminateNSGL(void);
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
void _glfwDestroyContextNSGL(_GLFWwindow* window);

339
glfw/nsgl_context.m Normal file
View File

@@ -0,0 +1,339 @@
//========================================================================
// GLFW 3.3 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-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"
#if (MAC_OS_X_VERSION_MAX_ALLOWED < 101400)
#define NSOpenGLContextParameterSwapInterval NSOpenGLCPSwapInterval
#define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity
#endif
static void makeContextCurrentNSGL(_GLFWwindow* window)
{
if (window)
[window->context.nsgl.object makeCurrentContext];
else
[NSOpenGLContext clearCurrentContext];
_glfwPlatformSetTls(&_glfw.contextSlot, window);
}
static void swapBuffersNSGL(_GLFWwindow* window)
{
// ARP appears to be unnecessary, but this is future-proof
[window->context.nsgl.object flushBuffer];
}
static void swapIntervalNSGL(int interval)
{
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
GLint sync = interval;
[window->context.nsgl.object setValues:&sync
forParameter:NSOpenGLContextParameterSwapInterval];
}
static int extensionSupportedNSGL(const char* extension)
{
// There are no NSGL extensions
return GLFW_FALSE;
}
static GLFWglproc getProcAddressNSGL(const char* procname)
{
CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault,
procname,
kCFStringEncodingASCII);
GLFWglproc symbol = CFBundleGetFunctionPointerForName(_glfw.nsgl.framework,
symbolName);
CFRelease(symbolName);
return symbol;
}
// Destroy the OpenGL context
//
static void destroyContextNSGL(_GLFWwindow* window)
{
[window->context.nsgl.pixelFormat release];
window->context.nsgl.pixelFormat = nil;
[window->context.nsgl.object release];
window->context.nsgl.object = nil;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Initialize OpenGL support
//
GLFWbool _glfwInitNSGL(void)
{
if (_glfw.nsgl.framework)
return GLFW_TRUE;
_glfw.nsgl.framework =
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
if (_glfw.nsgl.framework == NULL)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"NSGL: Failed to locate OpenGL framework");
return GLFW_FALSE;
}
return GLFW_TRUE;
}
// Terminate OpenGL support
//
void _glfwTerminateNSGL(void)
{
}
// Create the OpenGL context
//
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"NSGL: OpenGL ES is not available on macOS");
return GLFW_FALSE;
}
if (ctxconfig->major > 2)
{
if (ctxconfig->major == 3 && ctxconfig->minor < 2)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"NSGL: The targeted version of macOS does not support OpenGL 3.0 or 3.1 but may support 3.2 and above");
return GLFW_FALSE;
}
if (!ctxconfig->forward || ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"NSGL: The targeted version of macOS only supports forward-compatible core profile contexts for OpenGL 3.2 and above");
return GLFW_FALSE;
}
}
// Context robustness modes (GL_KHR_robustness) are not yet supported by
// macOS but are not a hard constraint, so ignore and continue
// Context release behaviors (GL_KHR_context_flush_control) are not yet
// supported by macOS but are not a hard constraint, so ignore and continue
// Debug contexts (GL_KHR_debug) are not yet supported by macOS but are not
// a hard constraint, so ignore and continue
// No-error contexts (GL_KHR_no_error) are not yet supported by macOS but
// are not a hard constraint, so ignore and continue
#define addAttrib(a) \
{ \
assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \
}
#define setAttrib(a, v) { addAttrib(a); addAttrib(v); }
NSOpenGLPixelFormatAttribute attribs[40];
int index = 0;
addAttrib(NSOpenGLPFAAccelerated);
addAttrib(NSOpenGLPFAClosestPolicy);
if (ctxconfig->nsgl.offline)
{
addAttrib(NSOpenGLPFAAllowOfflineRenderers);
// NOTE: This replaces the NSSupportsAutomaticGraphicsSwitching key in
// 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
if (ctxconfig->major >= 4)
{
setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core);
}
else
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
if (ctxconfig->major >= 3)
{
setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
}
if (ctxconfig->major <= 2)
{
if (fbconfig->auxBuffers != GLFW_DONT_CARE)
setAttrib(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers);
if (fbconfig->accumRedBits != GLFW_DONT_CARE &&
fbconfig->accumGreenBits != GLFW_DONT_CARE &&
fbconfig->accumBlueBits != GLFW_DONT_CARE &&
fbconfig->accumAlphaBits != GLFW_DONT_CARE)
{
const int accumBits = fbconfig->accumRedBits +
fbconfig->accumGreenBits +
fbconfig->accumBlueBits +
fbconfig->accumAlphaBits;
setAttrib(NSOpenGLPFAAccumSize, accumBits);
}
}
if (fbconfig->redBits != GLFW_DONT_CARE &&
fbconfig->greenBits != GLFW_DONT_CARE &&
fbconfig->blueBits != GLFW_DONT_CARE)
{
int colorBits = fbconfig->redBits +
fbconfig->greenBits +
fbconfig->blueBits;
// macOS needs non-zero color size, so set reasonable values
if (colorBits == 0)
colorBits = 24;
else if (colorBits < 15)
colorBits = 15;
setAttrib(NSOpenGLPFAColorSize, colorBits);
}
if (fbconfig->alphaBits != GLFW_DONT_CARE)
setAttrib(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);
if (fbconfig->depthBits != GLFW_DONT_CARE)
setAttrib(NSOpenGLPFADepthSize, fbconfig->depthBits);
if (fbconfig->stencilBits != GLFW_DONT_CARE)
setAttrib(NSOpenGLPFAStencilSize, fbconfig->stencilBits);
if (fbconfig->stereo)
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"NSGL: Stereo rendering is deprecated");
return GLFW_FALSE;
#else
addAttrib(NSOpenGLPFAStereo);
#endif
}
if (fbconfig->doublebuffer)
addAttrib(NSOpenGLPFADoubleBuffer);
if (fbconfig->samples != GLFW_DONT_CARE)
{
if (fbconfig->samples == 0)
{
setAttrib(NSOpenGLPFASampleBuffers, 0);
}
else
{
setAttrib(NSOpenGLPFASampleBuffers, 1);
setAttrib(NSOpenGLPFASamples, fbconfig->samples);
}
}
// NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB
// framebuffer, so there's no need (and no way) to request it
addAttrib(0);
#undef addAttrib
#undef setAttrib
window->context.nsgl.pixelFormat =
[[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
if (window->context.nsgl.pixelFormat == nil)
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"NSGL: Failed to find a suitable pixel format");
return GLFW_FALSE;
}
NSOpenGLContext* share = NULL;
if (ctxconfig->share)
share = ctxconfig->share->context.nsgl.object;
window->context.nsgl.object =
[[NSOpenGLContext alloc] initWithFormat:window->context.nsgl.pixelFormat
shareContext:share];
if (window->context.nsgl.object == nil)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"NSGL: Failed to create OpenGL context");
return GLFW_FALSE;
}
if (fbconfig->transparent)
{
GLint opaque = 0;
[window->context.nsgl.object setValues:&opaque forParameter:NSOpenGLContextParameterSurfaceOpacity];
}
[window->context.nsgl.object setView:window->ns.view];
window->context.makeCurrent = makeContextCurrentNSGL;
window->context.swapBuffers = swapBuffersNSGL;
window->context.swapInterval = swapIntervalNSGL;
window->context.extensionSupported = extensionSupportedNSGL;
window->context.getProcAddress = getProcAddressNSGL;
window->context.destroy = destroyContextNSGL;
return GLFW_TRUE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW native API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(nil);
if (window->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return NULL;
}
return window->context.nsgl.object;
}

50
glfw/null_init.c vendored Normal file
View File

@@ -0,0 +1,50 @@
//========================================================================
// GLFW 3.3 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// 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 platform API //////
//////////////////////////////////////////////////////////////////////////
int _glfwPlatformInit(void)
{
_glfwInitTimerPOSIX();
return GLFW_TRUE;
}
void _glfwPlatformTerminate(void)
{
_glfwTerminateOSMesa();
}
const char* _glfwPlatformGetVersionString(void)
{
return _GLFW_VERSION_NUMBER " null OSMesa";
}

42
glfw/null_joystick.c vendored Normal file
View File

@@ -0,0 +1,42 @@
//========================================================================
// GLFW 3.3 - 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.
//
//========================================================================
#include "internal.h"
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
{
return GLFW_FALSE;
}
void _glfwPlatformUpdateGamepadGUID(char* guid)
{
}

31
glfw/null_joystick.h vendored Normal file
View File

@@ -0,0 +1,31 @@
//========================================================================
// GLFW 3.3 - 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 int nulljs
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE int nulljs
#define _GLFW_PLATFORM_MAPPING_NAME ""

68
glfw/null_monitor.c vendored Normal file
View File

@@ -0,0 +1,68 @@
//========================================================================
// GLFW 3.3 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// 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 platform API //////
//////////////////////////////////////////////////////////////////////////
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
{
}
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
{
}
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
float* xscale, float* yscale)
{
if (xscale)
*xscale = 1.f;
if (yscale)
*yscale = 1.f;
}
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
{
return NULL;
}
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
{
}
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{
return GLFW_FALSE;
}
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{
}

62
glfw/null_platform.h vendored Normal file
View File

@@ -0,0 +1,62 @@
//========================================================================
// GLFW 3.3 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// 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 <dlfcn.h>
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNull null
#define _GLFW_PLATFORM_CONTEXT_STATE
#define _GLFW_PLATFORM_MONITOR_STATE
#define _GLFW_PLATFORM_CURSOR_STATE
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
#define _GLFW_EGL_CONTEXT_STATE
#define _GLFW_EGL_LIBRARY_CONTEXT_STATE
#include "osmesa_context.h"
#include "posix_time.h"
#include "posix_thread.h"
#include "null_joystick.h"
#if defined(_GLFW_WIN32)
#define _glfw_dlopen(name) LoadLibraryA(name)
#define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle)
#define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name)
#else
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
#define _glfw_dlclose(handle) dlclose(handle)
#define _glfw_dlsym(handle, name) dlsym(handle, name)
#endif
// Null-specific per-window data
//
typedef struct _GLFWwindowNull
{
int width;
int height;
} _GLFWwindowNull;

330
glfw/null_window.c vendored Normal file
View File

@@ -0,0 +1,330 @@
//========================================================================
// GLFW 3.3 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// 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"
static int createNativeWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig)
{
window->null.width = wndconfig->width;
window->null.height = wndconfig->height;
return GLFW_TRUE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
int _glfwPlatformCreateWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
if (!createNativeWindow(window, wndconfig))
return GLFW_FALSE;
if (ctxconfig->client != GLFW_NO_API)
{
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API ||
ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
{
if (!_glfwInitOSMesa())
return GLFW_FALSE;
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
return GLFW_FALSE;
}
else
{
_glfwInputError(GLFW_API_UNAVAILABLE, "Null: EGL not available");
return GLFW_FALSE;
}
}
return GLFW_TRUE;
}
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
{
if (window->context.destroy)
window->context.destroy(window);
}
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
{
}
void _glfwPlatformSetWindowIcon(_GLFWwindow* window, int count,
const GLFWimage* images)
{
}
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
_GLFWmonitor* monitor,
int xpos, int ypos,
int width, int height,
int refreshRate)
{
}
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
{
}
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
{
}
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
{
if (width)
*width = window->null.width;
if (height)
*height = window->null.height;
}
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
{
window->null.width = width;
window->null.height = height;
}
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
int minwidth, int minheight,
int maxwidth, int maxheight)
{
}
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int n, int d)
{
}
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
{
if (width)
*width = window->null.width;
if (height)
*height = window->null.height;
}
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
int* left, int* top,
int* right, int* bottom)
{
}
void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
float* xscale, float* yscale)
{
if (xscale)
*xscale = 1.f;
if (yscale)
*yscale = 1.f;
}
double _glfwPlatformGetDoubleClickInterval(_GLFWwindow* window)
{
return 0.5;
}
void _glfwPlatformIconifyWindow(_GLFWwindow* window)
{
}
void _glfwPlatformRestoreWindow(_GLFWwindow* window)
{
}
void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
{
}
int _glfwPlatformWindowMaximized(_GLFWwindow* window)
{
return GLFW_FALSE;
}
int _glfwPlatformWindowHovered(_GLFWwindow* window)
{
return GLFW_FALSE;
}
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
{
return GLFW_FALSE;
}
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
{
}
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
{
}
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
{
}
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
{
return 1.f;
}
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
{
}
void _glfwPlatformShowWindow(_GLFWwindow* window)
{
}
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
{
}
int _glfwPlatformWindowBell(_GLFWwindow* window)
{
return GLFW_FALSE;
}
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
{
}
void _glfwPlatformHideWindow(_GLFWwindow* window)
{
}
void _glfwPlatformFocusWindow(_GLFWwindow* window)
{
}
int _glfwPlatformWindowFocused(_GLFWwindow* window)
{
return GLFW_FALSE;
}
int _glfwPlatformWindowIconified(_GLFWwindow* window)
{
return GLFW_FALSE;
}
int _glfwPlatformWindowVisible(_GLFWwindow* window)
{
return GLFW_FALSE;
}
void _glfwPlatformPollEvents(void)
{
}
void _glfwPlatformWaitEvents(void)
{
}
void _glfwPlatformWaitEventsTimeout(double timeout)
{
}
void _glfwPlatformPostEmptyEvent(void)
{
}
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
{
}
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
{
}
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{
}
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
const GLFWimage* image,
int xhot, int yhot, int count)
{
return GLFW_TRUE;
}
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
{
return GLFW_TRUE;
}
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
{
}
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
{
}
void _glfwPlatformSetClipboardString(const char* string)
{
}
const char* _glfwPlatformGetClipboardString(void)
{
return NULL;
}
const char* _glfwPlatformGetScancodeName(int scancode)
{
return "";
}
int _glfwPlatformGetKeyScancode(int key)
{
return -1;
}
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
{
}
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
return GLFW_FALSE;
}
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
_GLFWwindow* window,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface)
{
// This seems like the most appropriate error to return here
return VK_ERROR_INITIALIZATION_FAILED;
}

369
glfw/osmesa_context.c vendored Normal file
View File

@@ -0,0 +1,369 @@
//========================================================================
// GLFW 3.3 OSMesa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// 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 <stdlib.h>
#include <string.h>
#include <assert.h>
#include "internal.h"
static void makeContextCurrentOSMesa(_GLFWwindow* window)
{
if (window)
{
int width, height;
_glfwPlatformGetFramebufferSize(window, &width, &height);
// Check to see if we need to allocate a new buffer
if ((window->context.osmesa.buffer == NULL) ||
(width != window->context.osmesa.width) ||
(height != window->context.osmesa.height))
{
free(window->context.osmesa.buffer);
// Allocate the new buffer (width * height * 8-bit RGBA)
window->context.osmesa.buffer = calloc(4, width * height);
window->context.osmesa.width = width;
window->context.osmesa.height = height;
}
if (!OSMesaMakeCurrent(window->context.osmesa.handle,
window->context.osmesa.buffer,
GL_UNSIGNED_BYTE,
width, height))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"OSMesa: Failed to make context current");
return;
}
}
_glfwPlatformSetTls(&_glfw.contextSlot, window);
}
static GLFWglproc getProcAddressOSMesa(const char* procname)
{
return (GLFWglproc) OSMesaGetProcAddress(procname);
}
static void destroyContextOSMesa(_GLFWwindow* window)
{
if (window->context.osmesa.handle)
{
OSMesaDestroyContext(window->context.osmesa.handle);
window->context.osmesa.handle = NULL;
}
if (window->context.osmesa.buffer)
{
free(window->context.osmesa.buffer);
window->context.osmesa.width = 0;
window->context.osmesa.height = 0;
}
}
static void swapBuffersOSMesa(_GLFWwindow* window)
{
// No double buffering on OSMesa
}
static void swapIntervalOSMesa(int interval)
{
// No swap interval on OSMesa
}
static int extensionSupportedOSMesa(const char* extension)
{
// OSMesa does not have extensions
return GLFW_FALSE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwInitOSMesa(void)
{
int i;
const char* sonames[] =
{
#if defined(_GLFW_OSMESA_LIBRARY)
_GLFW_OSMESA_LIBRARY,
#elif defined(_WIN32)
"libOSMesa.dll",
"OSMesa.dll",
#elif defined(__APPLE__)
"libOSMesa.8.dylib",
#elif defined(__CYGWIN__)
"libOSMesa-8.so",
#else
"libOSMesa.so.8",
"libOSMesa.so.6",
#endif
NULL
};
if (_glfw.osmesa.handle)
return GLFW_TRUE;
for (i = 0; sonames[i]; i++)
{
_glfw.osmesa.handle = _glfw_dlopen(sonames[i]);
if (_glfw.osmesa.handle)
break;
}
if (!_glfw.osmesa.handle)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "OSMesa: Library not found");
return GLFW_FALSE;
}
_glfw.osmesa.CreateContextExt = (PFN_OSMesaCreateContextExt)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaCreateContextExt");
_glfw.osmesa.CreateContextAttribs = (PFN_OSMesaCreateContextAttribs)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaCreateContextAttribs");
_glfw.osmesa.DestroyContext = (PFN_OSMesaDestroyContext)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaDestroyContext");
_glfw.osmesa.MakeCurrent = (PFN_OSMesaMakeCurrent)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaMakeCurrent");
_glfw.osmesa.GetColorBuffer = (PFN_OSMesaGetColorBuffer)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetColorBuffer");
_glfw.osmesa.GetDepthBuffer = (PFN_OSMesaGetDepthBuffer)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetDepthBuffer");
_glfw.osmesa.GetProcAddress = (PFN_OSMesaGetProcAddress)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetProcAddress");
if (!_glfw.osmesa.CreateContextExt ||
!_glfw.osmesa.DestroyContext ||
!_glfw.osmesa.MakeCurrent ||
!_glfw.osmesa.GetColorBuffer ||
!_glfw.osmesa.GetDepthBuffer ||
!_glfw.osmesa.GetProcAddress)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"OSMesa: Failed to load required entry points");
_glfwTerminateOSMesa();
return GLFW_FALSE;
}
return GLFW_TRUE;
}
void _glfwTerminateOSMesa(void)
{
if (_glfw.osmesa.handle)
{
_glfw_dlclose(_glfw.osmesa.handle);
_glfw.osmesa.handle = NULL;
}
}
#define setAttrib(a, v) \
{ \
assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \
attribs[index++] = v; \
}
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
OSMesaContext share = NULL;
const int accumBits = fbconfig->accumRedBits +
fbconfig->accumGreenBits +
fbconfig->accumBlueBits +
fbconfig->accumAlphaBits;
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"OSMesa: OpenGL ES is not available on OSMesa");
return GLFW_FALSE;
}
if (ctxconfig->share)
share = ctxconfig->share->context.osmesa.handle;
if (OSMesaCreateContextAttribs)
{
int index = 0, attribs[40];
setAttrib(OSMESA_FORMAT, OSMESA_RGBA);
setAttrib(OSMESA_DEPTH_BITS, fbconfig->depthBits);
setAttrib(OSMESA_STENCIL_BITS, fbconfig->stencilBits);
setAttrib(OSMESA_ACCUM_BITS, accumBits);
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
{
setAttrib(OSMESA_PROFILE, OSMESA_CORE_PROFILE);
}
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
{
setAttrib(OSMESA_PROFILE, OSMESA_COMPAT_PROFILE);
}
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
{
setAttrib(OSMESA_CONTEXT_MAJOR_VERSION, ctxconfig->major);
setAttrib(OSMESA_CONTEXT_MINOR_VERSION, ctxconfig->minor);
}
if (ctxconfig->forward)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"OSMesa: Forward-compatible contexts not supported");
return GLFW_FALSE;
}
setAttrib(0, 0);
window->context.osmesa.handle =
OSMesaCreateContextAttribs(attribs, share);
}
else
{
if (ctxconfig->profile)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"OSMesa: OpenGL profiles unavailable");
return GLFW_FALSE;
}
window->context.osmesa.handle =
OSMesaCreateContextExt(OSMESA_RGBA,
fbconfig->depthBits,
fbconfig->stencilBits,
accumBits,
share);
}
if (window->context.osmesa.handle == NULL)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"OSMesa: Failed to create context");
return GLFW_FALSE;
}
window->context.makeCurrent = makeContextCurrentOSMesa;
window->context.swapBuffers = swapBuffersOSMesa;
window->context.swapInterval = swapIntervalOSMesa;
window->context.extensionSupported = extensionSupportedOSMesa;
window->context.getProcAddress = getProcAddressOSMesa;
window->context.destroy = destroyContextOSMesa;
return GLFW_TRUE;
}
#undef setAttrib
//////////////////////////////////////////////////////////////////////////
////// GLFW native API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width,
int* height, int* format, void** buffer)
{
void* mesaBuffer;
GLint mesaWidth, mesaHeight, mesaFormat;
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
if (!OSMesaGetColorBuffer(window->context.osmesa.handle,
&mesaWidth, &mesaHeight,
&mesaFormat, &mesaBuffer))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"OSMesa: Failed to retrieve color buffer");
return GLFW_FALSE;
}
if (width)
*width = mesaWidth;
if (height)
*height = mesaHeight;
if (format)
*format = mesaFormat;
if (buffer)
*buffer = mesaBuffer;
return GLFW_TRUE;
}
GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
int* width, int* height,
int* bytesPerValue,
void** buffer)
{
void* mesaBuffer;
GLint mesaWidth, mesaHeight, mesaBytes;
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
if (!OSMesaGetDepthBuffer(window->context.osmesa.handle,
&mesaWidth, &mesaHeight,
&mesaBytes, &mesaBuffer))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"OSMesa: Failed to retrieve depth buffer");
return GLFW_FALSE;
}
if (width)
*width = mesaWidth;
if (height)
*height = mesaHeight;
if (bytesPerValue)
*bytesPerValue = mesaBytes;
if (buffer)
*buffer = mesaBuffer;
return GLFW_TRUE;
}
GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (window->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return NULL;
}
return window->context.osmesa.handle;
}

94
glfw/osmesa_context.h vendored Normal file
View File

@@ -0,0 +1,94 @@
//========================================================================
// GLFW 3.3 OSMesa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// 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 OSMESA_RGBA 0x1908
#define OSMESA_FORMAT 0x22
#define OSMESA_DEPTH_BITS 0x30
#define OSMESA_STENCIL_BITS 0x31
#define OSMESA_ACCUM_BITS 0x32
#define OSMESA_PROFILE 0x33
#define OSMESA_CORE_PROFILE 0x34
#define OSMESA_COMPAT_PROFILE 0x35
#define OSMESA_CONTEXT_MAJOR_VERSION 0x36
#define OSMESA_CONTEXT_MINOR_VERSION 0x37
typedef void* OSMesaContext;
typedef void (*OSMESAproc)(void);
typedef OSMesaContext (GLAPIENTRY * PFN_OSMesaCreateContextExt)(GLenum,GLint,GLint,GLint,OSMesaContext);
typedef OSMesaContext (GLAPIENTRY * PFN_OSMesaCreateContextAttribs)(const int*,OSMesaContext);
typedef void (GLAPIENTRY * PFN_OSMesaDestroyContext)(OSMesaContext);
typedef int (GLAPIENTRY * PFN_OSMesaMakeCurrent)(OSMesaContext,void*,int,int,int);
typedef int (GLAPIENTRY * PFN_OSMesaGetColorBuffer)(OSMesaContext,int*,int*,int*,void**);
typedef int (GLAPIENTRY * PFN_OSMesaGetDepthBuffer)(OSMesaContext,int*,int*,int*,void**);
typedef GLFWglproc (GLAPIENTRY * PFN_OSMesaGetProcAddress)(const char*);
#define OSMesaCreateContextExt _glfw.osmesa.CreateContextExt
#define OSMesaCreateContextAttribs _glfw.osmesa.CreateContextAttribs
#define OSMesaDestroyContext _glfw.osmesa.DestroyContext
#define OSMesaMakeCurrent _glfw.osmesa.MakeCurrent
#define OSMesaGetColorBuffer _glfw.osmesa.GetColorBuffer
#define OSMesaGetDepthBuffer _glfw.osmesa.GetDepthBuffer
#define OSMesaGetProcAddress _glfw.osmesa.GetProcAddress
#define _GLFW_OSMESA_CONTEXT_STATE _GLFWcontextOSMesa osmesa
#define _GLFW_OSMESA_LIBRARY_CONTEXT_STATE _GLFWlibraryOSMesa osmesa
// OSMesa-specific per-context data
//
typedef struct _GLFWcontextOSMesa
{
OSMesaContext handle;
int width;
int height;
void* buffer;
} _GLFWcontextOSMesa;
// OSMesa-specific global data
//
typedef struct _GLFWlibraryOSMesa
{
void* handle;
PFN_OSMesaCreateContextExt CreateContextExt;
PFN_OSMesaCreateContextAttribs CreateContextAttribs;
PFN_OSMesaDestroyContext DestroyContext;
PFN_OSMesaMakeCurrent MakeCurrent;
PFN_OSMesaGetColorBuffer GetColorBuffer;
PFN_OSMesaGetDepthBuffer GetDepthBuffer;
PFN_OSMesaGetProcAddress GetProcAddress;
} _GLFWlibraryOSMesa;
GLFWbool _glfwInitOSMesa(void);
void _glfwTerminateOSMesa(void);
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);

103
glfw/posix_thread.c vendored Normal file
View File

@@ -0,0 +1,103 @@
//========================================================================
// GLFW 3.3 POSIX - 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>
#include <string.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls)
{
assert(tls->posix.allocated == GLFW_FALSE);
if (pthread_key_create(&tls->posix.key, NULL) != 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"POSIX: Failed to create context TLS");
return GLFW_FALSE;
}
tls->posix.allocated = GLFW_TRUE;
return GLFW_TRUE;
}
void _glfwPlatformDestroyTls(_GLFWtls* tls)
{
if (tls->posix.allocated)
pthread_key_delete(tls->posix.key);
memset(tls, 0, sizeof(_GLFWtls));
}
void* _glfwPlatformGetTls(_GLFWtls* tls)
{
assert(tls->posix.allocated == GLFW_TRUE);
return pthread_getspecific(tls->posix.key);
}
void _glfwPlatformSetTls(_GLFWtls* tls, void* value)
{
assert(tls->posix.allocated == GLFW_TRUE);
pthread_setspecific(tls->posix.key, value);
}
GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex)
{
assert(mutex->posix.allocated == GLFW_FALSE);
if (pthread_mutex_init(&mutex->posix.handle, NULL) != 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "POSIX: Failed to create mutex");
return GLFW_FALSE;
}
return mutex->posix.allocated = GLFW_TRUE;
}
void _glfwPlatformDestroyMutex(_GLFWmutex* mutex)
{
if (mutex->posix.allocated)
pthread_mutex_destroy(&mutex->posix.handle);
memset(mutex, 0, sizeof(_GLFWmutex));
}
void _glfwPlatformLockMutex(_GLFWmutex* mutex)
{
assert(mutex->posix.allocated == GLFW_TRUE);
pthread_mutex_lock(&mutex->posix.handle);
}
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex)
{
assert(mutex->posix.allocated == GLFW_TRUE);
pthread_mutex_unlock(&mutex->posix.handle);
}

51
glfw/posix_thread.h vendored Normal file
View File

@@ -0,0 +1,51 @@
//========================================================================
// GLFW 3.3 POSIX - 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 <pthread.h>
#define _GLFW_PLATFORM_TLS_STATE _GLFWtlsPOSIX posix
#define _GLFW_PLATFORM_MUTEX_STATE _GLFWmutexPOSIX posix
// POSIX-specific thread local storage data
//
typedef struct _GLFWtlsPOSIX
{
GLFWbool allocated;
pthread_key_t key;
} _GLFWtlsPOSIX;
// POSIX-specific mutex data
//
typedef struct _GLFWmutexPOSIX
{
GLFWbool allocated;
pthread_mutex_t handle;
} _GLFWmutexPOSIX;

85
glfw/posix_time.c vendored Normal file
View File

@@ -0,0 +1,85 @@
//========================================================================
// GLFW 3.3 POSIX - 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 <sys/time.h>
#include <time.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Initialise timer
//
void _glfwInitTimerPOSIX(void)
{
#if defined(CLOCK_MONOTONIC)
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
{
_glfw.timer.posix.monotonic = GLFW_TRUE;
_glfw.timer.posix.frequency = 1000000000;
}
else
#endif
{
_glfw.timer.posix.monotonic = GLFW_FALSE;
_glfw.timer.posix.frequency = 1000000;
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
uint64_t _glfwPlatformGetTimerValue(void)
{
#if defined(CLOCK_MONOTONIC)
if (_glfw.timer.posix.monotonic)
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (uint64_t) ts.tv_sec * (uint64_t) 1000000000 + (uint64_t) ts.tv_nsec;
}
else
#endif
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (uint64_t) tv.tv_sec * (uint64_t) 1000000 + (uint64_t) tv.tv_usec;
}
}
uint64_t _glfwPlatformGetTimerFrequency(void)
{
return _glfw.timer.posix.frequency;
}

44
glfw/posix_time.h vendored Normal file
View File

@@ -0,0 +1,44 @@
//========================================================================
// GLFW 3.3 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerPOSIX posix
#include <stdint.h>
// POSIX-specific global timer data
//
typedef struct _GLFWtimerPOSIX
{
GLFWbool monotonic;
uint64_t frequency;
} _GLFWtimerPOSIX;
void _glfwInitTimerPOSIX(void);

150
glfw/source-info.json Normal file
View File

@@ -0,0 +1,150 @@
{
"cocoa": {
"headers": [
"cocoa_platform.h",
"cocoa_joystick.h",
"posix_thread.h",
"nsgl_context.h",
"egl_context.h",
"osmesa_context.h"
],
"sources": [
"cocoa_init.m",
"cocoa_joystick.m",
"cocoa_monitor.m",
"cocoa_window.m",
"cocoa_time.c",
"posix_thread.c",
"nsgl_context.m",
"egl_context.c",
"osmesa_context.c"
]
},
"common": {
"headers": [
"internal.h",
"mappings.h"
],
"sources": [
"context.c",
"init.c",
"input.c",
"monitor.c",
"vulkan.c",
"window.c"
]
},
"osmesa": {
"headers": [
"null_platform.h",
"null_joystick.h",
"posix_time.h",
"posix_thread.h",
"osmesa_context.h"
],
"sources": [
"null_init.c",
"null_monitor.c",
"null_window.c",
"null_joystick.c",
"posix_time.c",
"posix_thread.c",
"osmesa_context.c"
]
},
"wayland": {
"headers": [
"wl_platform.h",
"posix_time.h",
"posix_thread.h",
"xkb_glfw.h",
"dbus_glfw.h",
"ibus_glfw.h",
"backend_utils.h",
"egl_context.h",
"osmesa_context.h",
"linux_joystick.h",
"null_joystick.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/xdg-decoration/xdg-decoration-unstable-v1.xml",
"unstable/primary-selection/primary-selection-unstable-v1.xml"
],
"sources": [
"wl_init.c",
"wl_monitor.c",
"wl_window.c",
"posix_time.c",
"posix_thread.c",
"xkb_glfw.c",
"dbus_glfw.c",
"ibus_glfw.c",
"egl_context.c",
"osmesa_context.c",
"backend_utils.c",
"linux_joystick.c",
"null_joystick.c"
]
},
"wayland_protocols": [
1,
17
],
"win32": {
"headers": [
"win32_platform.h",
"win32_joystick.h",
"wgl_context.h",
"egl_context.h",
"osmesa_context.h"
],
"sources": [
"win32_init.c",
"win32_joystick.c",
"win32_monitor.c",
"win32_time.c",
"win32_thread.c",
"win32_window.c",
"wgl_context.c",
"egl_context.c",
"osmesa_context.c"
]
},
"x11": {
"headers": [
"x11_platform.h",
"xkb_glfw.h",
"dbus_glfw.h",
"ibus_glfw.h",
"backend_utils.h",
"posix_time.h",
"posix_thread.h",
"glx_context.h",
"egl_context.h",
"osmesa_context.h",
"linux_joystick.h",
"null_joystick.h"
],
"sources": [
"x11_init.c",
"x11_monitor.c",
"x11_window.c",
"xkb_glfw.c",
"dbus_glfw.c",
"ibus_glfw.c",
"posix_time.c",
"posix_thread.c",
"glx_context.c",
"egl_context.c",
"osmesa_context.c",
"backend_utils.c",
"linux_joystick.c",
"null_joystick.c"
]
}
}

325
glfw/vulkan.c vendored Normal file
View File

@@ -0,0 +1,325 @@
//========================================================================
// GLFW 3.3 - 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>
#include <string.h>
#include <stdlib.h>
#define _GLFW_FIND_LOADER 1
#define _GLFW_REQUIRE_LOADER 2
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwInitVulkan(int mode)
{
VkResult err;
VkExtensionProperties* ep;
uint32_t i, count;
if (_glfw.vk.available)
return GLFW_TRUE;
#if !defined(_GLFW_VULKAN_STATIC)
#if defined(_GLFW_VULKAN_LIBRARY)
_glfw.vk.handle = _glfw_dlopen(_GLFW_VULKAN_LIBRARY);
#elif defined(_GLFW_WIN32)
_glfw.vk.handle = _glfw_dlopen("vulkan-1.dll");
#elif defined(_GLFW_COCOA)
_glfw.vk.handle = _glfw_dlopen("libvulkan.1.dylib");
#else
_glfw.vk.handle = _glfw_dlopen("libvulkan.so.1");
#endif
if (!_glfw.vk.handle)
{
if (mode == _GLFW_REQUIRE_LOADER)
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found");
return GLFW_FALSE;
}
_glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)
_glfw_dlsym(_glfw.vk.handle, "vkGetInstanceProcAddr");
if (!_glfw.vk.GetInstanceProcAddr)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Vulkan: Loader does not export vkGetInstanceProcAddr");
_glfwTerminateVulkan();
return GLFW_FALSE;
}
_glfw.vk.EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)
vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceExtensionProperties");
if (!_glfw.vk.EnumerateInstanceExtensionProperties)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties");
_glfwTerminateVulkan();
return GLFW_FALSE;
}
#endif // _GLFW_VULKAN_STATIC
err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
if (err)
{
// NOTE: This happens on systems with a loader but without any Vulkan ICD
if (mode == _GLFW_REQUIRE_LOADER)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Vulkan: Failed to query instance extension count: %s",
_glfwGetVulkanResultString(err));
}
_glfwTerminateVulkan();
return GLFW_FALSE;
}
ep = calloc(count, sizeof(VkExtensionProperties));
err = vkEnumerateInstanceExtensionProperties(NULL, &count, ep);
if (err)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Vulkan: Failed to query instance extensions: %s",
_glfwGetVulkanResultString(err));
free(ep);
_glfwTerminateVulkan();
return GLFW_FALSE;
}
for (i = 0; i < count; i++)
{
if (strcmp(ep[i].extensionName, "VK_KHR_surface") == 0)
_glfw.vk.KHR_surface = GLFW_TRUE;
#if defined(_GLFW_WIN32)
else if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0)
_glfw.vk.KHR_win32_surface = GLFW_TRUE;
#elif defined(_GLFW_COCOA)
else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0)
_glfw.vk.MVK_macos_surface = GLFW_TRUE;
#elif defined(_GLFW_X11)
else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0)
_glfw.vk.KHR_xlib_surface = GLFW_TRUE;
else if (strcmp(ep[i].extensionName, "VK_KHR_xcb_surface") == 0)
_glfw.vk.KHR_xcb_surface = GLFW_TRUE;
#elif defined(_GLFW_WAYLAND)
else if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0)
_glfw.vk.KHR_wayland_surface = GLFW_TRUE;
#endif
}
free(ep);
_glfw.vk.available = GLFW_TRUE;
_glfwPlatformGetRequiredInstanceExtensions(_glfw.vk.extensions);
return GLFW_TRUE;
}
void _glfwTerminateVulkan(void)
{
#if !defined(_GLFW_VULKAN_STATIC)
if (_glfw.vk.handle)
_glfw_dlclose(_glfw.vk.handle);
#endif
}
const char* _glfwGetVulkanResultString(VkResult result)
{
switch (result)
{
case VK_SUCCESS:
return "Success";
case VK_NOT_READY:
return "A fence or query has not yet completed";
case VK_TIMEOUT:
return "A wait operation has not completed in the specified time";
case VK_EVENT_SET:
return "An event is signaled";
case VK_EVENT_RESET:
return "An event is unsignaled";
case VK_INCOMPLETE:
return "A return array was too small for the result";
case VK_ERROR_OUT_OF_HOST_MEMORY:
return "A host memory allocation has failed";
case VK_ERROR_OUT_OF_DEVICE_MEMORY:
return "A device memory allocation has failed";
case VK_ERROR_INITIALIZATION_FAILED:
return "Initialization of an object could not be completed for implementation-specific reasons";
case VK_ERROR_DEVICE_LOST:
return "The logical or physical device has been lost";
case VK_ERROR_MEMORY_MAP_FAILED:
return "Mapping of a memory object has failed";
case VK_ERROR_LAYER_NOT_PRESENT:
return "A requested layer is not present or could not be loaded";
case VK_ERROR_EXTENSION_NOT_PRESENT:
return "A requested extension is not supported";
case VK_ERROR_FEATURE_NOT_PRESENT:
return "A requested feature is not supported";
case VK_ERROR_INCOMPATIBLE_DRIVER:
return "The requested version of Vulkan is not supported by the driver or is otherwise incompatible";
case VK_ERROR_TOO_MANY_OBJECTS:
return "Too many objects of the type have already been created";
case VK_ERROR_FORMAT_NOT_SUPPORTED:
return "A requested format is not supported on this device";
case VK_ERROR_SURFACE_LOST_KHR:
return "A surface is no longer available";
case VK_SUBOPTIMAL_KHR:
return "A swapchain no longer matches the surface properties exactly, but can still be used";
case VK_ERROR_OUT_OF_DATE_KHR:
return "A surface has changed in such a way that it is no longer compatible with the swapchain";
case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
return "The display used by a swapchain does not use the same presentable image layout";
case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
return "The requested window is already connected to a VkSurfaceKHR, or to some other non-Vulkan API";
case VK_ERROR_VALIDATION_FAILED_EXT:
return "A validation layer found an error";
default:
return "ERROR: UNKNOWN VULKAN ERROR";
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI int glfwVulkanSupported(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
return _glfwInitVulkan(_GLFW_FIND_LOADER);
}
GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count)
{
assert(count != NULL);
*count = 0;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
return NULL;
if (!_glfw.vk.extensions[0])
return NULL;
*count = 2;
return (const char**) _glfw.vk.extensions;
}
GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance,
const char* procname)
{
GLFWvkproc proc;
assert(procname != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
return NULL;
proc = (GLFWvkproc) vkGetInstanceProcAddr(instance, procname);
#if defined(_GLFW_VULKAN_STATIC)
if (!proc)
{
if (strcmp(procname, "vkGetInstanceProcAddr") == 0)
return (GLFWvkproc) vkGetInstanceProcAddr;
}
#else
if (!proc)
proc = (GLFWvkproc) _glfw_dlsym(_glfw.vk.handle, procname);
#endif
return proc;
}
GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
assert(instance != VK_NULL_HANDLE);
assert(device != VK_NULL_HANDLE);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
return GLFW_FALSE;
if (!_glfw.vk.extensions[0])
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Vulkan: Window surface creation extensions not found");
return GLFW_FALSE;
}
return _glfwPlatformGetPhysicalDevicePresentationSupport(instance,
device,
queuefamily);
}
GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance,
GLFWwindow* handle,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(instance != VK_NULL_HANDLE);
assert(window != NULL);
assert(surface != NULL);
*surface = VK_NULL_HANDLE;
_GLFW_REQUIRE_INIT_OR_RETURN(VK_ERROR_INITIALIZATION_FAILED);
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
return VK_ERROR_INITIALIZATION_FAILED;
if (!_glfw.vk.extensions[0])
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Vulkan: Window surface creation extensions not found");
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
if (window->context.client != GLFW_NO_API)
{
_glfwInputError(GLFW_INVALID_VALUE,
"Vulkan: Window surface creation requires the window to have the client API set to GLFW_NO_API");
return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR;
}
return _glfwPlatformCreateWindowSurface(instance, window, allocator, surface);
}

744
glfw/wgl_context.c vendored Normal file
View File

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

159
glfw/wgl_context.h vendored Normal file
View File

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

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