Compare commits
391 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20f7118432 | ||
|
|
37e6c3f0cb | ||
|
|
0459dda5c2 | ||
|
|
a10c816c05 | ||
|
|
c0c7cfacc2 | ||
|
|
8cdb6647ed | ||
|
|
b68e3c85b9 | ||
|
|
ef25d5bbd5 | ||
|
|
278bf6e897 | ||
|
|
90a985b73a | ||
|
|
b016353809 | ||
|
|
bc222af2e2 | ||
|
|
44599c9460 | ||
|
|
902fc22670 | ||
|
|
d84e22fbf1 | ||
|
|
6cc720a350 | ||
|
|
c905978874 | ||
|
|
bfe595a8e8 | ||
|
|
94d56d1a9e | ||
|
|
bd3f0b5363 | ||
|
|
6fae3545c7 | ||
|
|
297963f6ab | ||
|
|
a0ceba407e | ||
|
|
35fa91fba2 | ||
|
|
a5d6cd169e | ||
|
|
06c2263657 | ||
|
|
472c6f6b8d | ||
|
|
afcaca85da | ||
|
|
2575349ec2 | ||
|
|
77054f688d | ||
|
|
c5cb24378f | ||
|
|
d66123dd14 | ||
|
|
4ef8f11f9e | ||
|
|
599be7ddc9 | ||
|
|
685497fc8c | ||
|
|
57542fc204 | ||
|
|
8d9323aec6 | ||
|
|
4984a25b19 | ||
|
|
3bdcb29e01 | ||
|
|
b9ab8e6348 | ||
|
|
4a851701e9 | ||
|
|
eafd8af937 | ||
|
|
28bb123be8 | ||
|
|
8e1ed2f8c3 | ||
|
|
4a0fcb3cff | ||
|
|
b5c2163238 | ||
|
|
d0ecdfb330 | ||
|
|
bdf7d98a36 | ||
|
|
e4b0980d15 | ||
|
|
d99c57aeae | ||
|
|
5f855ce547 | ||
|
|
68f3b6fbeb | ||
|
|
dc6d14943e | ||
|
|
05f7334db9 | ||
|
|
cd707e9335 | ||
|
|
505ed5e43b | ||
|
|
9dc8bf5f62 | ||
|
|
f8098662b6 | ||
|
|
de7a0e86c4 | ||
|
|
ca55438fda | ||
|
|
a4b60e7eef | ||
|
|
5d22e07738 | ||
|
|
bdade7e151 | ||
|
|
6958ded4c4 | ||
|
|
cc06104be6 | ||
|
|
059c34c345 | ||
|
|
9cbb726566 | ||
|
|
e8b4356a88 | ||
|
|
634138cd3b | ||
|
|
3f6b07de81 | ||
|
|
d218900b57 | ||
|
|
cab949a939 | ||
|
|
e350822f5e | ||
|
|
3d6fe93297 | ||
|
|
3a5baf2722 | ||
|
|
cdb472cb56 | ||
|
|
e634350e77 | ||
|
|
464a6c1441 | ||
|
|
d3750b2244 | ||
|
|
b8d2b76ee4 | ||
|
|
14fb7c3201 | ||
|
|
922bc62e0e | ||
|
|
00cae4ccd1 | ||
|
|
61df266df7 | ||
|
|
17751666f2 | ||
|
|
961b2c9b65 | ||
|
|
eaf6f06047 | ||
|
|
d0ac218c05 | ||
|
|
1a01bc15d8 | ||
|
|
cdbe2f13ca | ||
|
|
4f5264277e | ||
|
|
bed3adcc95 | ||
|
|
0c5d59bcf6 | ||
|
|
ff20acd8b8 | ||
|
|
d1cffcde68 | ||
|
|
546dd9b225 | ||
|
|
2a666620c8 | ||
|
|
db50985040 | ||
|
|
8c6d593c41 | ||
|
|
40086c8d1c | ||
|
|
38f73b9f5e | ||
|
|
49429b5f49 | ||
|
|
d9f90ef077 | ||
|
|
6a126fa18e | ||
|
|
14d703f5cc | ||
|
|
9850025f3a | ||
|
|
8daab0ba41 | ||
|
|
88f25ccc76 | ||
|
|
50e7351c73 | ||
|
|
51453a54e4 | ||
|
|
c02ba03f39 | ||
|
|
78dec3d698 | ||
|
|
1590c59131 | ||
|
|
b26f79998a | ||
|
|
489f3e6c9d | ||
|
|
5fef4726a7 | ||
|
|
51fdb8200a | ||
|
|
fb0d98ead1 | ||
|
|
4096caba64 | ||
|
|
38f77144fa | ||
|
|
b8041ce17f | ||
|
|
00575733c8 | ||
|
|
621c92780c | ||
|
|
37f03af4b7 | ||
|
|
bdc4558a43 | ||
|
|
46d483e8b2 | ||
|
|
5143b62a07 | ||
|
|
87ed774cb4 | ||
|
|
4e427d05b7 | ||
|
|
195d987331 | ||
|
|
9b58317fb1 | ||
|
|
1cb15dedac | ||
|
|
5521d6b623 | ||
|
|
f5cf6c1dcb | ||
|
|
89307727e7 | ||
|
|
c30c21b250 | ||
|
|
b6fb087d7e | ||
|
|
97c2b7c1fe | ||
|
|
81506640c8 | ||
|
|
8244f7cd58 | ||
|
|
63573d6e26 | ||
|
|
9368f7f670 | ||
|
|
b7a11035d5 | ||
|
|
2e1b5e2fa7 | ||
|
|
8e5cbafe63 | ||
|
|
eb006a6688 | ||
|
|
40b9049deb | ||
|
|
64ffca2d0a | ||
|
|
1f4b6d4e9a | ||
|
|
eb30ba7722 | ||
|
|
3e0f4d36bc | ||
|
|
1fb118edee | ||
|
|
ca39634880 | ||
|
|
f8418d68a6 | ||
|
|
c0000fb24e | ||
|
|
c169f7ae83 | ||
|
|
7ab5244bf5 | ||
|
|
7e36489034 | ||
|
|
d259b12ae7 | ||
|
|
8f8138d9bd | ||
|
|
a8668f5fbf | ||
|
|
e00e6bd1c2 | ||
|
|
0fc6c47556 | ||
|
|
d530dccb96 | ||
|
|
37bf0e81d2 | ||
|
|
f872f955b0 | ||
|
|
003cd0a203 | ||
|
|
e7173f8145 | ||
|
|
93af102bec | ||
|
|
67f23664c9 | ||
|
|
39f6071c68 | ||
|
|
edc8878632 | ||
|
|
93b62c4dfd | ||
|
|
c3e210c80f | ||
|
|
9a5cc8f650 | ||
|
|
5e7fbfefe9 | ||
|
|
29ad6fba22 | ||
|
|
c848c3ee0d | ||
|
|
547132131a | ||
|
|
40186fb54b | ||
|
|
5dc4e79c8d | ||
|
|
556992a117 | ||
|
|
a41ef8d513 | ||
|
|
6d96a89328 | ||
|
|
0fb1481038 | ||
|
|
4b77530c65 | ||
|
|
cdb493cf50 | ||
|
|
c9a574a764 | ||
|
|
bdb633a882 | ||
|
|
37aee7133d | ||
|
|
2cfd55f3ce | ||
|
|
2e8188e89d | ||
|
|
1e172caea3 | ||
|
|
6866cd0fb8 | ||
|
|
2719926870 | ||
|
|
406891abcc | ||
|
|
4be6e9009a | ||
|
|
6a31909557 | ||
|
|
f49f0d19f9 | ||
|
|
a2407f94e4 | ||
|
|
62a0be4a11 | ||
|
|
b9029f6c67 | ||
|
|
92496f42c9 | ||
|
|
841c907efc | ||
|
|
9bc288cd8e | ||
|
|
2ef0391b08 | ||
|
|
6db768d1a3 | ||
|
|
9b080950a9 | ||
|
|
3cd1fef4cb | ||
|
|
a491a801bf | ||
|
|
41ebb72276 | ||
|
|
e4c0e9073e | ||
|
|
efad733cc5 | ||
|
|
1fcd6e1811 | ||
|
|
75d697fa97 | ||
|
|
cde69670ba | ||
|
|
0be6c9cb97 | ||
|
|
8c9d2d3ca2 | ||
|
|
c84e73d8e6 | ||
|
|
3fb00f6c70 | ||
|
|
86305fdeb3 | ||
|
|
710e146d22 | ||
|
|
d5abc84bea | ||
|
|
6f8214c15c | ||
|
|
a56475e32f | ||
|
|
9dadd91887 | ||
|
|
df5a73bb35 | ||
|
|
a50bf59a2c | ||
|
|
241354ae52 | ||
|
|
c863116011 | ||
|
|
5cbd591a1e | ||
|
|
6bb78c9499 | ||
|
|
893f406a99 | ||
|
|
f722b898b0 | ||
|
|
18335b3eac | ||
|
|
4708b592e2 | ||
|
|
7598a2965c | ||
|
|
1b59761a19 | ||
|
|
7fd1053e0f | ||
|
|
e178e7f6a5 | ||
|
|
d0bf21ab16 | ||
|
|
c826965833 | ||
|
|
a76db39c19 | ||
|
|
323a538bdd | ||
|
|
2435feca3b | ||
|
|
29d059680c | ||
|
|
aaaf7f9d8b | ||
|
|
bc90ce569a | ||
|
|
27f9f1756b | ||
|
|
9135387cfa | ||
|
|
af3504e05c | ||
|
|
9c9eac9d46 | ||
|
|
f28383206a | ||
|
|
ba1c093d18 | ||
|
|
3ea3a85694 | ||
|
|
0e1a423889 | ||
|
|
3ce68ed53f | ||
|
|
90c10da398 | ||
|
|
630bf28c22 | ||
|
|
ff89c1d8e4 | ||
|
|
96703c23c8 | ||
|
|
2b78f5adad | ||
|
|
ab7df777eb | ||
|
|
adbc694ff8 | ||
|
|
7709cdb12b | ||
|
|
f6051f73f5 | ||
|
|
d5c2a21cdf | ||
|
|
8ffc841a3a | ||
|
|
6c478977bb | ||
|
|
07beb53b37 | ||
|
|
59df1a8647 | ||
|
|
fb98aa650d | ||
|
|
9981b5a9c6 | ||
|
|
603533e632 | ||
|
|
38bc90f724 | ||
|
|
721beb9202 | ||
|
|
2e99259589 | ||
|
|
83e6b75872 | ||
|
|
cf70946f50 | ||
|
|
f1c36aba83 | ||
|
|
2973cf15a4 | ||
|
|
55969bc3c5 | ||
|
|
a8504c971a | ||
|
|
1644de2083 | ||
|
|
dd1fb85f60 | ||
|
|
b945b19865 | ||
|
|
91bf9f2ec8 | ||
|
|
f151f4c165 | ||
|
|
95b9b2d373 | ||
|
|
8be698681c | ||
|
|
da3e1a3730 | ||
|
|
29f637c19a | ||
|
|
3d01565ba7 | ||
|
|
962291cc8e | ||
|
|
a662dace9c | ||
|
|
d34e0b325e | ||
|
|
4c242ec528 | ||
|
|
658be9405f | ||
|
|
15e8f6ad8a | ||
|
|
a5aca35f1c | ||
|
|
ae9df1ffac | ||
|
|
8bf2e098f5 | ||
|
|
7091d554b5 | ||
|
|
bada795320 | ||
|
|
7d385849fb | ||
|
|
78775b7f6b | ||
|
|
8d21a5b6b3 | ||
|
|
9da095ca50 | ||
|
|
0fafc07db0 | ||
|
|
65b95999c1 | ||
|
|
056012871f | ||
|
|
c7b377080c | ||
|
|
47acc9ff2f | ||
|
|
fe62700825 | ||
|
|
6bcab56988 | ||
|
|
fbc4d3e1be | ||
|
|
c89d1643f4 | ||
|
|
e2226a1509 | ||
|
|
656916e0fa | ||
|
|
4a55eb9e7f | ||
|
|
9c8cf04a80 | ||
|
|
e846bc9308 | ||
|
|
3c7a71772c | ||
|
|
857a53e80f | ||
|
|
84fcabe5cf | ||
|
|
9dc410c9fd | ||
|
|
8ebad06e7e | ||
|
|
5db1a07f81 | ||
|
|
48e5c8edb3 | ||
|
|
eefc21920e | ||
|
|
d7dd9c295b | ||
|
|
4faf71bd03 | ||
|
|
2751dbdb94 | ||
|
|
fe329cb4ab | ||
|
|
741e719ff8 | ||
|
|
866bb32046 | ||
|
|
7f01e758b3 | ||
|
|
03003d270e | ||
|
|
3d313016ba | ||
|
|
1292c752a8 | ||
|
|
4783947135 | ||
|
|
c9045788f5 | ||
|
|
4eed8463b3 | ||
|
|
303711ab8d | ||
|
|
98d7fc9f39 | ||
|
|
c0a96f2087 | ||
|
|
c509ecca52 | ||
|
|
e5d8eb7845 | ||
|
|
277f43aed6 | ||
|
|
f1494b64e5 | ||
|
|
6b9c71ec62 | ||
|
|
d12a4b0a1a | ||
|
|
a75d075dd1 | ||
|
|
8f8a37bf94 | ||
|
|
03f692fed8 | ||
|
|
614416d4b0 | ||
|
|
feb851716e | ||
|
|
2b095f720e | ||
|
|
d6e750727f | ||
|
|
961ff8633d | ||
|
|
8406d4a8f1 | ||
|
|
e25b64ae15 | ||
|
|
59205a4caf | ||
|
|
5001797179 | ||
|
|
b24dd69067 | ||
|
|
4f163338dd | ||
|
|
1e8f1f8cc6 | ||
|
|
5c3e2e6877 | ||
|
|
ff52ff7865 | ||
|
|
f6f55aaa9a | ||
|
|
6f1aecab99 | ||
|
|
f33205a490 | ||
|
|
2920638a3d | ||
|
|
1ae32b5742 | ||
|
|
4e9dabfb25 | ||
|
|
ca2c419c9b | ||
|
|
020c1311ca | ||
|
|
8193b2a44b | ||
|
|
324a000777 | ||
|
|
951b1c1e83 | ||
|
|
8e57fd93c6 | ||
|
|
d262f43b5b | ||
|
|
73224e7d95 | ||
|
|
19463c81a3 | ||
|
|
6f2bb31068 | ||
|
|
abf9c4117d | ||
|
|
39f50830d7 | ||
|
|
c2fd7005cb | ||
|
|
52f2ed33f5 | ||
|
|
a51239c6ae | ||
|
|
e6217e1428 |
@@ -10,10 +10,16 @@ jobs:
|
||||
- run: if grep -Inr '\s$' kitty kitty_tests kittens docs *.py *.asciidoc *.rst .gitattributes .gitignore; then echo Trailing whitespace found, aborting.; exit 1; fi
|
||||
- run: python3 -m flake8 --count .
|
||||
- run: python3 setup.py build --debug --verbose
|
||||
- run: python3 test.py
|
||||
- run: ./kitty/launcher/kitty +launch test.py
|
||||
- run: make FAIL_WARN=-W man
|
||||
- run: make FAIL_WARN=-W html
|
||||
- run: python3 setup.py linux-package
|
||||
|
||||
lin-package:
|
||||
docker:
|
||||
- image: kovidgoyal/kitty-test:latest
|
||||
steps:
|
||||
- checkout
|
||||
- run: python3 setup.py linux-package --update-check-interval=0
|
||||
|
||||
lin-35:
|
||||
docker:
|
||||
@@ -26,7 +32,7 @@ jobs:
|
||||
steps:
|
||||
- checkout
|
||||
- run: /opt/py3.5/bin/python3 setup.py build --debug --verbose --sanitize
|
||||
- run: ./asan-launcher test.py
|
||||
- run: ./kitty/launcher/kitty +launch test.py
|
||||
|
||||
lin-37:
|
||||
docker:
|
||||
@@ -38,7 +44,7 @@ jobs:
|
||||
steps:
|
||||
- checkout
|
||||
- run: /opt/py3.7/bin/python3 setup.py build --debug --verbose --sanitize
|
||||
- run: ./asan-launcher test.py
|
||||
- run: ./kitty/launcher/kitty +launch test.py
|
||||
|
||||
lin-bundle:
|
||||
docker:
|
||||
@@ -49,8 +55,9 @@ jobs:
|
||||
- checkout
|
||||
- run: echo "export LD_LIBRARY_PATH=$SW/lib" >> $BASH_ENV
|
||||
- run: echo "export PKG_CONFIG_PATH=$SW/lib/pkgconfig" >> $BASH_ENV
|
||||
- run: echo "export PYTHONHOME=$SW" >> $BASH_ENV
|
||||
- run: $SW/bin/python3 setup.py build --debug --verbose
|
||||
- run: $SW/bin/python3 test.py
|
||||
- run: ./kitty/launcher/kitty +launch test.py
|
||||
|
||||
mac-bundle:
|
||||
macos:
|
||||
@@ -65,21 +72,23 @@ jobs:
|
||||
- run: curl https://download.calibre-ebook.com/travis/kitty/osx.tar.xz | tar xJ -C $SW
|
||||
- run: echo "export PATH=$SW/bin:$PATH" >> $BASH_ENV
|
||||
- run: python3 setup.py build --debug --verbose
|
||||
- run: python3 test.py
|
||||
- run: ./kitty/launcher/kitty +launch test.py
|
||||
|
||||
mac-brew:
|
||||
macos:
|
||||
xcode: "10.1.0"
|
||||
xcode: "10.2.0"
|
||||
environment:
|
||||
LC_ALL: en_US.UTF-8
|
||||
LANG: en_US.UTF-8
|
||||
steps:
|
||||
- checkout
|
||||
- run: brew bundle
|
||||
- run: python3 logo/make.py
|
||||
- run: python3 setup.py build --debug --verbose
|
||||
- run: python3 test.py
|
||||
- run: python3 setup.py macos-bundle
|
||||
- run: ./kitty/launcher/kitty +launch test.py
|
||||
- run: echo "export PATH=/usr/local/opt/sphinx-doc/bin:$PATH" >> $BASH_ENV
|
||||
- run: python3 setup.py linux-package --verbose
|
||||
- run: python3 setup.py kitty.app --verbose
|
||||
- run: kitty.app/Contents/MacOS/kitty +runpy "from kitty.constants import *; print(kitty_exe())"
|
||||
|
||||
|
||||
workflows:
|
||||
@@ -90,5 +99,6 @@ workflows:
|
||||
- lin-sys
|
||||
- lin-35
|
||||
- lin-37
|
||||
- lin-package
|
||||
- lin-bundle
|
||||
- mac-brew
|
||||
|
||||
@@ -31,7 +31,7 @@ ENV LANG=en_US.UTF-8
|
||||
RUN apt-get install -y libreadline-dev zlib1g-dev libssl-dev libbz2-dev libsqlite3-dev libffi-dev
|
||||
|
||||
# kitty deps
|
||||
RUN apt-get install -y libgl1-mesa-dev libxi-dev libxrandr-dev libxinerama-dev libxcursor-dev libxcb-xkb-dev libdbus-1-dev libxkbcommon-dev libharfbuzz-dev libpng-dev libfontconfig-dev libpython3-dev libxkbcommon-x11-dev python3-pygments
|
||||
RUN apt-get install -y libgl1-mesa-dev libxi-dev libxrandr-dev libxinerama-dev libxcursor-dev libxcb-xkb-dev libdbus-1-dev libxkbcommon-dev libharfbuzz-dev libpng-dev libfontconfig-dev libpython3-dev libxkbcommon-x11-dev python3-pygments libcanberra-dev
|
||||
|
||||
# Needed to build kitty docs
|
||||
RUN pip3 install sphinx
|
||||
|
||||
3
.github/FUNDING.yml
vendored
Normal file
3
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
patreon: kovidgoyal
|
||||
liberapay: kovidgoyal
|
||||
custom: https://sw.kovidgoyal.net/kitty/support.html
|
||||
28
.gitignore
vendored
28
.gitignore
vendored
@@ -1,19 +1,17 @@
|
||||
*.so
|
||||
*.pyc
|
||||
*.pyo
|
||||
tags
|
||||
build
|
||||
linux-package
|
||||
kitty.app
|
||||
logo/*.iconset
|
||||
compile_commands.json
|
||||
glad/out
|
||||
asan-launcher
|
||||
asan-launcher.dSYM
|
||||
kitty-profile
|
||||
dev
|
||||
__pycache__
|
||||
glfw/wayland-*-client-protocol.[ch]
|
||||
docs/_build
|
||||
docs/generated
|
||||
/tags
|
||||
/build/
|
||||
/linux-package/
|
||||
/kitty.app/
|
||||
/compile_commands.json
|
||||
/link_commands.json
|
||||
/glad/out/
|
||||
/kitty/launcher/
|
||||
/*.dSYM/
|
||||
__pycache__/
|
||||
/glfw/wayland-*-client-protocol.[ch]
|
||||
/docs/_build/
|
||||
/docs/generated/
|
||||
.DS_Store
|
||||
|
||||
3
Brewfile
3
Brewfile
@@ -1,6 +1,5 @@
|
||||
brew 'pkg-config'
|
||||
brew 'imagemagick'
|
||||
brew 'optipng'
|
||||
brew 'librsvg'
|
||||
brew 'harfbuzz'
|
||||
brew 'python'
|
||||
brew 'sphinx-doc'
|
||||
|
||||
11
Makefile
11
Makefile
@@ -1,8 +1,8 @@
|
||||
ifdef V
|
||||
VVAL=--verbose
|
||||
VVAL=--verbose
|
||||
endif
|
||||
ifdef VERBOSE
|
||||
VVAL=--verbose
|
||||
VVAL=--verbose
|
||||
endif
|
||||
|
||||
all:
|
||||
@@ -28,12 +28,7 @@ asan:
|
||||
profile:
|
||||
python3 setup.py build $(VVAL) --profile
|
||||
|
||||
logo/kitty.iconset/icon_256x256.png: logo/kitty.svg logo/make.py
|
||||
logo/make.py
|
||||
|
||||
rendered_logo: logo/kitty.iconset/icon_256x256.png
|
||||
|
||||
app: rendered_logo
|
||||
app:
|
||||
python3 setup.py kitty.app $(VVAL)
|
||||
|
||||
man:
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* asan-launcher.c
|
||||
* Copyright (C) 2017 Kovid Goyal <kovid at kovidgoyal.net>
|
||||
*
|
||||
* Distributed under terms of the GPL3 license.
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#define MAX_ARGC 1024
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
wchar_t *argvw[MAX_ARGC + 1] = {0};
|
||||
argvw[0] = L"kitty";
|
||||
for (int i = 1; i < argc; i++) argvw[i] = Py_DecodeLocale(argv[i], NULL);
|
||||
int ret = Py_Main(argc, argvw);
|
||||
for (int i = 1; i < argc; i++) PyMem_RawFree(argvw[i]);
|
||||
return ret;
|
||||
}
|
||||
@@ -1,2 +1,2 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
cloc --exclude-list-file <(echo -e 'kitty/wcwidth-std.h\nkitty/glfw.c\nkitty/keys.h\nkitty/charsets.c\nkitty/unicode-data.c\nkitty/key_encoding.py\nkitty/rgb.py\nkitty/gl.h\nkitty/gl-wrapper.h\nkitty/gl-wrapper.c\nkitty/khrplatform.h\nkitty/glfw-wrapper.h\nkitty/glfw-wrapper.c\nkitty/emoji.h\nkittens/unicode_input/names.h') kitty kittens
|
||||
|
||||
@@ -20,6 +20,7 @@ Run-time dependencies:
|
||||
* libpng
|
||||
* freetype (not needed on macOS)
|
||||
* fontconfig (not needed on macOS)
|
||||
* libcanberra (not needed on macOS)
|
||||
* ImageMagick (optional, needed to use the ``kitty icat`` tool to display images in the terminal)
|
||||
* pygments (optional, need for syntax highlighting in ``kitty +kitten diff``)
|
||||
|
||||
@@ -28,7 +29,7 @@ Build-time dependencies:
|
||||
* gcc or clang
|
||||
* pkg-config
|
||||
* For building on Linux in addition to the above dependencies you might also need to install the ``-dev`` packages for:
|
||||
``libdbus-1-dev``, ``libxcursor-dev``, ``libxrandr-dev``, ``libxi-dev``, ``libxinerama-dev``, ``libgl1-mesa-dev``, ``libxkbcommon-x11-dev``, ``libfontconfig-dev`` and ``libpython-dev``.
|
||||
``libdbus-1-dev``, ``libxcursor-dev``, ``libxrandr-dev``, ``libxi-dev``, ``libxinerama-dev``, ``libgl1-mesa-dev``, ``libxkbcommon-x11-dev``, ``libfontconfig-dev``, ``libcanberra-dev`` and ``libpython-dev``.
|
||||
if they are not already installed by your distro.
|
||||
|
||||
Install and run from source
|
||||
@@ -44,25 +45,17 @@ Now build the native code parts of |kitty| with the following command::
|
||||
|
||||
You can run |kitty|, as::
|
||||
|
||||
python3 .
|
||||
./kitty/launcher/kitty
|
||||
|
||||
If that works, you can create a script to launch |kitty|:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
#!/usr/bin/env python3
|
||||
import runpy
|
||||
runpy.run_path('/path/to/kitty/dir', run_name='__main__')
|
||||
|
||||
And place it in :file:`~/bin` or :file:`/usr/bin` so that you can run |kitty| using
|
||||
If that works, you can create a symlink to the launcher in :file:`~/bin` or
|
||||
some other directory on your PATH so that you can run |kitty| using
|
||||
just ``kitty``.
|
||||
|
||||
|
||||
Building kitty.app on macOS from source
|
||||
-------------------------------------------
|
||||
|
||||
Install `imagemagick`, `optipng` and `librsvg` using `brew` or similar (needed
|
||||
for the logo generation step). And run::
|
||||
Run::
|
||||
|
||||
make app
|
||||
|
||||
@@ -111,3 +104,9 @@ without needing to install all of |kitty|.
|
||||
|
||||
This applies to creating packages for |kitty| for macOS package managers such as
|
||||
brew or MacPorts as well.
|
||||
|
||||
|
||||
.. note::
|
||||
|kitty| has its own update check mechanism, if you would like to turn
|
||||
it off for your package, use
|
||||
``python3 setup.py linux-package --update-check-interval=0``
|
||||
|
||||
@@ -4,6 +4,177 @@ Changelog
|
||||
|kitty| is a feature full, cross-platform, *fast*, GPU based terminal emulator.
|
||||
To update |kitty|, :doc:`follow the instructions <binary>`.
|
||||
|
||||
0.14.4 [2019-08-31]
|
||||
---------------------
|
||||
|
||||
- hints kitten: Add a :option:`kitty +kitten hints --alphabet` option to
|
||||
control what alphabets are used for hints (:iss:`1879`)
|
||||
|
||||
- hints kitten: Allow specifying :option:`kitty +kitten hints --program`
|
||||
multiple times to run multiple programs (:iss:`1879`)
|
||||
|
||||
- Add a :opt:`kitten_alias` option that can be used to alias kitten invocation
|
||||
for brevity and to change kitten option defaults globally (:iss:`1879`)
|
||||
|
||||
- macOS: Add an option :opt:`macos_show_window_title_in` to control
|
||||
showing the window title in the menubar/titlebar (:pull:`1837`)
|
||||
|
||||
- macOS: Allow drag and drop of text from other applications into kitty
|
||||
(:pull:`1921`)
|
||||
|
||||
- When running kittens, use the colorscheme of the current window
|
||||
rather than the configured colorscheme (:iss:`1906`)
|
||||
|
||||
- Don't fail to start if running the shell to read the EDITOR env var fails
|
||||
(:iss:`1869`)
|
||||
|
||||
- Disable the ``liga`` and ``dlig`` OpenType features for broken fonts
|
||||
such as Nimbus Mono.
|
||||
|
||||
- Fix a regression that broke setting background_opacity via remote control
|
||||
(:iss:`1895`)
|
||||
|
||||
- Fix piping PNG images into the icat kitten not working (:iss:`1920`)
|
||||
|
||||
- When the OS returns a fallback font that does not actually contain glyphs
|
||||
for the text, do not exhaust the list of fallback fonts (:iss:`1918`)
|
||||
|
||||
- Fix formatting attributes not reset across line boundaries when passing
|
||||
buffer as ANSI (:iss:`1924`)
|
||||
|
||||
|
||||
0.14.3 [2019-07-29]
|
||||
---------------------
|
||||
|
||||
- Remote control: Add a command `kitty @ scroll-window` to scroll windows
|
||||
|
||||
- Allow passing a ``!neighbor`` argument to the new_window mapping to open a
|
||||
new window next to the active window (:iss:`1746`)
|
||||
|
||||
- Document the kitty remote control protocol (:iss:`1646`)
|
||||
|
||||
- Add a new option :opt:`pointer_shape_when_grabbed` that allows you to control
|
||||
the mouse pointer shape when the terminal programs grabs the pointer
|
||||
(:iss:`1808`)
|
||||
|
||||
- Add an option :opt:`terminal_select_modifiers` to control which modifiers
|
||||
are used to override mouse selection even when a terminal application has
|
||||
grabbed the mouse (:iss:`1774`)
|
||||
|
||||
- When piping data to a child in the pipe command do it in a thread so as not
|
||||
to block the UI (:iss:`1708`)
|
||||
|
||||
- unicode_input kitten: Fix a regression that broke using indices to select
|
||||
recently used symbols.
|
||||
|
||||
- Fix a regression that caused closing an overlay window to focus
|
||||
the previously focused window rather than the underlying window (:iss:`1720`)
|
||||
|
||||
- macOS: Reduce energy consumption when idle by shutting down Apple's display
|
||||
link thread after 30 second of inactivity (:iss:`1763`)
|
||||
|
||||
- Linux: Fix incorrect scaling for fallback fonts when the font has an
|
||||
underscore that renders out of bounds (:iss:`1713`)
|
||||
|
||||
- macOS: Fix finding fallback font for private use unicode symbols not working
|
||||
reliably (:iss:`1650`)
|
||||
|
||||
- Fix an out of bounds read causing a crash when selecting text with the mouse
|
||||
in the alternate screen mode (:iss:`1578`)
|
||||
|
||||
- Linux: Use the system "bell" sound for the terminal bell. Adds libcanberra
|
||||
as a new dependency to play the system sound.
|
||||
|
||||
- macOS: Fix a rare deadlock causing kitty to hang (:iss:`1779`)
|
||||
|
||||
- Linux: Fix a regression in 0.14.0 that caused the event loop to tick
|
||||
continuously, wasting CPU even when idle (:iss:`1782`)
|
||||
|
||||
- ssh kitten: Make argument parsing more like ssh (:iss:`1787`)
|
||||
|
||||
- When using :opt:`strip_trailing_spaces` do not remove empty lines
|
||||
(:iss:`1802`)
|
||||
|
||||
- Fix a crash when displaying very large number of images (:iss:`1825`)
|
||||
|
||||
|
||||
0.14.2 [2019-06-09]
|
||||
---------------------
|
||||
|
||||
- Add an option :opt:`placement_strategy` to control how the cell area is
|
||||
aligned inside the window when the window size is not an exact multiple
|
||||
of the cell size (:pull:`1670`)
|
||||
|
||||
- hints kitten: Add a :option:`kitty +kitten hints --multiple-joiner` option to
|
||||
control how multiple selections are serialized when copying to clipboard
|
||||
or inserting into the terminal. You can have them on separate lines,
|
||||
separated by arbitrary characters, or even serialized as JSON (:iss:`1665`)
|
||||
|
||||
- macOS: Fix a regression in the previous release that broke using
|
||||
:kbd:`ctrl+shift+tab` (:iss:`1671`)
|
||||
|
||||
- panel kitten: Fix the contents of the panel kitten not being positioned
|
||||
correctly on the vertical axis
|
||||
|
||||
- icat kitten: Fix a regression that broke passing directories to icat
|
||||
(:iss:`1683`)
|
||||
|
||||
- clipboard kitten: Add a :option:`kitty +kitten clipboard --wait-for-completion`
|
||||
option to have the kitten wait till copying to clipboard is complete
|
||||
(:iss:`1693`)
|
||||
|
||||
- Allow using the :doc:`pipe <pipe>` command to send screen and scrollback
|
||||
contents directly to the clipboard (:iss:`1693`)
|
||||
|
||||
- Linux: Disable the Wayland backend on GNOME by default as GNOME has no
|
||||
support for server side decorations. Can be controlled by
|
||||
:opt:`linux_display_server`.
|
||||
|
||||
- Add an option to control the default :opt:`update_check_interval` when
|
||||
building kitty packages
|
||||
|
||||
- Wayland: Fix resizing the window on a compositor that does not provide
|
||||
server side window decorations, such a GNOME or Weston not working
|
||||
correctly (:iss:`1659`)
|
||||
|
||||
- Wayland: Fix crash when enabling disabling monitors on sway (:iss:`1696`)
|
||||
|
||||
|
||||
0.14.1 [2019-05-29]
|
||||
---------------------
|
||||
|
||||
- Add an option :opt:`command_on_bell` to run an arbitrary command when
|
||||
a bell occurs (:iss:`1660`)
|
||||
|
||||
- Add a shortcut to toggle maximized window state :sc:`toggle_maximized`
|
||||
|
||||
- Add support for the underscore key found in some keyboard layouts
|
||||
(:iss:`1639`)
|
||||
|
||||
- Fix a missing newline when using the pipe command between the
|
||||
scrollback and screen contents (:iss:`1642`)
|
||||
|
||||
- Fix colors not being preserved when using the pipe command with
|
||||
the pager history buffer (:pull:`1657`)
|
||||
|
||||
- macOS: Fix a regression that could cause rendering of a kitty window
|
||||
to occasionally freeze in certain situations, such as moving it between
|
||||
monitors or transitioning from/to fullscreen (:iss:`1641`)
|
||||
|
||||
- macOS: Fix a regression that caused :kbd:`cmd+v` to double up in the dvorak
|
||||
keyboard layout (:iss:`1652`)
|
||||
|
||||
- When resizing and only a single window is present in the current layout,
|
||||
use that window's background color to fill in the blank areas.
|
||||
|
||||
- Linux: Automatically increase cell height if the font being used is broken
|
||||
and draws the underscore outside the bounding box (:iss:`690`)
|
||||
|
||||
- Wayland: Fix maximizing the window on a compositor that does not provide
|
||||
server side window decorations, such a GNOME or Weston not working
|
||||
(:iss:`1662`)
|
||||
|
||||
|
||||
0.14.0 [2019-05-24]
|
||||
---------------------
|
||||
|
||||
@@ -60,7 +231,7 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
|
||||
|
||||
- macOS: Fix :kbd:`cmd+period` key not working (:iss:`1318`)
|
||||
|
||||
- macOS: Add an option :opt:`macos_show_window_title_in_menubar` to not
|
||||
- macOS: Add an option `macos_show_window_title_in_menubar` to not
|
||||
show the current window title in the menu-bar (:iss:`1066`)
|
||||
|
||||
- macOS: Workaround for cocoa bug that could cause the mouse cursor to become
|
||||
|
||||
52
docs/conf.py
52
docs/conf.py
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
@@ -11,6 +12,7 @@ import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
from functools import partial
|
||||
|
||||
from docutils import nodes
|
||||
@@ -32,7 +34,7 @@ str_version = importlib.import_module('kitty.constants').str_version
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = 'kitty'
|
||||
copyright = '2018, Kovid Goyal'
|
||||
copyright = time.strftime('%Y, Kovid Goyal')
|
||||
author = 'Kovid Goyal'
|
||||
building_man_pages = 'man' in sys.argv
|
||||
|
||||
@@ -274,6 +276,48 @@ def write_cli_docs(all_kitten_names):
|
||||
# }}}
|
||||
|
||||
|
||||
def write_remote_control_protocol_docs(): # {{{
|
||||
from kitty.cmds import cmap
|
||||
field_pat = re.compile(r'\s*([a-zA-Z0-9_+]+)\s*:\s*(.+)')
|
||||
|
||||
def format_cmd(p, name, cmd):
|
||||
p(name)
|
||||
p('-' * 80)
|
||||
lines = cmd.__doc__.strip().splitlines()
|
||||
fields = []
|
||||
for line in lines:
|
||||
m = field_pat.match(line)
|
||||
if m is None:
|
||||
p(line)
|
||||
else:
|
||||
fields.append((m.group(1), m.group(2)))
|
||||
if fields:
|
||||
p('\nFields are:\n')
|
||||
for (name, desc) in fields:
|
||||
if '+' in name:
|
||||
title = name.replace('+', ' (required)')
|
||||
else:
|
||||
title = name
|
||||
defval = cmd.get_default(name.replace('-', '_'), cmd)
|
||||
if defval is not cmd:
|
||||
title = f'{title} (default: {defval})'
|
||||
else:
|
||||
title = f'{title} (optional)'
|
||||
p(f':code:`{title}`')
|
||||
p(' ', desc), p()
|
||||
p(), p()
|
||||
|
||||
with open(f'generated/rc.rst', 'w') as f:
|
||||
p = partial(print, file=f)
|
||||
for name in sorted(cmap):
|
||||
cmd = cmap[name]
|
||||
if not cmd.__doc__:
|
||||
continue
|
||||
name = name.replace('_', '-')
|
||||
format_cmd(p, name, cmd)
|
||||
# }}}
|
||||
|
||||
|
||||
# config file docs {{{
|
||||
|
||||
class ConfLexer(RegexLexer):
|
||||
@@ -481,9 +525,12 @@ def process_shortcut_link(env, refnode, has_explicit_title, title, target):
|
||||
conf_name, slug = 'kitty', conf_name
|
||||
full_name = conf_name + '.' + slug
|
||||
try:
|
||||
target, title = shortcut_slugs[full_name]
|
||||
target, stitle = shortcut_slugs[full_name]
|
||||
except KeyError:
|
||||
logger.warning('Unknown shortcut: {}'.format(target), location=refnode)
|
||||
else:
|
||||
if not has_explicit_title:
|
||||
title = stitle
|
||||
return title, target
|
||||
|
||||
|
||||
@@ -535,6 +582,7 @@ def setup(app):
|
||||
from kittens.runner import all_kitten_names
|
||||
all_kitten_names = all_kitten_names()
|
||||
write_cli_docs(all_kitten_names)
|
||||
write_remote_control_protocol_docs()
|
||||
write_conf_docs(app, all_kitten_names)
|
||||
app.add_lexer('session', SessionLexer())
|
||||
app.add_role('link', link_role)
|
||||
|
||||
50
docs/faq.rst
50
docs/faq.rst
@@ -103,6 +103,28 @@ for |kitty| and use :ref:`at_set-colors`.
|
||||
A list of pre-made color themes for kitty is available at:
|
||||
`kitty-themes <https://github.com/dexpota/kitty-themes>`_
|
||||
|
||||
Examples of using OSC escape codes to set colors::
|
||||
|
||||
Change the default foreground color:
|
||||
printf '\x1b]10;#ff0000\x1b\\'
|
||||
Change the default background color:
|
||||
printf '\x1b]11;blue\x1b\\'
|
||||
Change the cursor color:
|
||||
printf '\x1b]12;blue\x1b\\'
|
||||
Change the selection background color:
|
||||
printf '\x1b]17;blue\x1b\\'
|
||||
Change the selection foreground color:
|
||||
printf '\x1b]19;blue\x1b\\'
|
||||
Change the nth color (0 - 255):
|
||||
printf '\x1b]4;n;green\x1b\\'
|
||||
|
||||
You can use various syntaxes/names for color specifications in the above
|
||||
examples. See `XParseColor <https://linux.die.net/man/3/xparsecolor>`_
|
||||
for full details.
|
||||
|
||||
If a ``?`` is given rather than a color specification, kitty will respond
|
||||
with the current value for the specified color.
|
||||
|
||||
|
||||
How do I specify command line options for kitty on macOS?
|
||||
---------------------------------------------------------------
|
||||
@@ -140,3 +162,31 @@ Bringing up applications on a single key press is the job of the window
|
||||
manager/desktop environment. For ways to do it with kitty (or indeed any
|
||||
terminal) in different environments,
|
||||
see `here <https://github.com/kovidgoyal/kitty/issues/45>`_.
|
||||
|
||||
|
||||
How do I map key presses in kitty to different keys in the terminal program?
|
||||
--------------------------------------------------------------------------------------
|
||||
|
||||
This is accomplished by using ``map`` with :sc:`send_text <send_text>` in :file:`kitty.conf`.
|
||||
For example::
|
||||
|
||||
map alt+s send_text all \x13
|
||||
|
||||
This maps :kbd:`alt+s`` to :kbd:`ctrl+s`. To figure out what bytes to use for
|
||||
the :sc:`send_text <send_text>` you can use the ``showkey`` utility. Run::
|
||||
|
||||
showkey -a
|
||||
|
||||
Then press the key you want to emulate. On macOS, this utility is currently not
|
||||
available. The manual way to figure it out is:
|
||||
|
||||
1. Look up your key's decimal value in the table at the bottom of `this
|
||||
page <http://ascii-table.com/ansi-escape-sequences.php>`_ or any
|
||||
ANSI escape sequence table. There are different modifiers for :kbd:`ctrl`,
|
||||
:kbd:`alt`, etc. For e.g., for :kbd:`ctrl+s`, find the ``S`` row and look at
|
||||
the third column value, ``19``.
|
||||
|
||||
2. Convert the decimal value to hex with ``kitty +runpy "print(hex(19))"``.
|
||||
This shows the hex value, ``13`` in this case.
|
||||
|
||||
3. Use ``\x(hexval)`` in your ``send_text`` command in kitty. So in this example, ``\x13``
|
||||
|
||||
@@ -107,7 +107,8 @@ features of the graphics protocol:
|
||||
sys.stdout.flush()
|
||||
cmd.clear()
|
||||
|
||||
write_chunked({'a': 'T', 'f': 100}, open(sys.argv[-1], 'rb').read())
|
||||
with open(sys.argv[-1], 'rb') as f:
|
||||
write_chunked({'a': 'T', 'f': 100}, f.read())
|
||||
|
||||
|
||||
Save this script as :file:`png.py`, then you can use it to display any PNG
|
||||
@@ -255,7 +256,10 @@ sequence of escape codes to the terminal emulator::
|
||||
Note that only the first escape code needs to have the full set of control
|
||||
codes such as width, height, format etc. Subsequent chunks must have
|
||||
only the ``m`` key. The client **must** finish sending all chunks for a single image
|
||||
before sending any other graphics related escape codes.
|
||||
before sending any other graphics related escape codes. Note that the cursor
|
||||
position used to display the image **must** be the position when the final chunk is
|
||||
received. Finally, terminals must not display anything, until the entire sequence is
|
||||
received and validated.
|
||||
|
||||
|
||||
Detecting available transmission mediums
|
||||
|
||||
@@ -60,6 +60,7 @@ You can also use your favorite package manager to install the |kitty| package.
|
||||
|kitty| packages are available for:
|
||||
`macOS with Homebrew (Cask) <https://formulae.brew.sh/cask/kitty>`_,
|
||||
`macOS and Linux with Nix <https://nixos.org/nixos/packages.html#kitty>`_,
|
||||
`Ubuntu <https://launchpad.net/ubuntu/+source/kitty>`_,
|
||||
`Debian <https://packages.debian.org/buster/kitty>`_,
|
||||
`openSUSE <https://build.opensuse.org/package/show/X11:terminals/kitty>`_,
|
||||
`Arch Linux <https://www.archlinux.org/packages/community/x86_64/kitty/>`_,
|
||||
@@ -186,6 +187,7 @@ Increase font size :sc:`increase_font_size` (also :kbd:`⌘++`
|
||||
Decrease font size :sc:`decrease_font_size` (also :kbd:`⌘+-` on macOS)
|
||||
Restore font size :sc:`reset_font_size` (also :kbd:`⌘+0` on macOS)
|
||||
Toggle fullscreen :sc:`toggle_fullscreen` (also :kbd:`^+⌘+f` on macOS)
|
||||
Toggle maximized :sc:`toggle_maximized`
|
||||
Input unicode character :sc:`input_unicode_character`
|
||||
Click URL using the keyboard :sc:`open_url`
|
||||
Reset the terminal :sc:`reset_terminal`
|
||||
@@ -366,6 +368,8 @@ Mouse features
|
||||
columns.
|
||||
* Selecting text automatically copies it to the primary clipboard (on
|
||||
platforms with a primary clipboard).
|
||||
* You can select text with kitty even when a terminal program has grabbed
|
||||
the mouse by holding down the :kbd:`shift` key.
|
||||
|
||||
|
||||
Font control
|
||||
@@ -446,6 +450,14 @@ Add the following to your :file:`~/.bashrc`
|
||||
|
||||
source <(kitty + complete setup bash)
|
||||
|
||||
Older versions of bash (for example, v3.2) do not support
|
||||
process substitution with the source command, in which
|
||||
case you can try an alternative:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
source /dev/stdin <<<"$(kitty + complete setup bash)"
|
||||
|
||||
|
||||
zsh
|
||||
~~~~~~~~~
|
||||
@@ -484,3 +496,4 @@ See :doc:`changelog`.
|
||||
|
||||
*
|
||||
kittens/*
|
||||
generated/rc
|
||||
|
||||
@@ -20,6 +20,10 @@ import tempfile
|
||||
py3 = sys.version_info[0] > 2
|
||||
is64bit = platform.architecture()[0] == '64bit'
|
||||
is_macos = 'darwin' in sys.platform.lower()
|
||||
if is_macos:
|
||||
mac_ver = tuple(map(int, platform.mac_ver()[0].split('.')))
|
||||
if mac_ver[:2] < (10, 12):
|
||||
raise SystemExit('Your version of macOS is too old, at least 10.12 is required')
|
||||
|
||||
try:
|
||||
__file__
|
||||
@@ -225,7 +229,8 @@ def script_launch():
|
||||
|
||||
def update_intaller_wrapper():
|
||||
# To run: python3 -c "import runpy; runpy.run_path('installer.py', run_name='update_wrapper')" installer.sh
|
||||
src = open(__file__, 'rb').read().decode('utf-8')
|
||||
with open(__file__, 'rb') as f:
|
||||
src = f.read().decode('utf-8')
|
||||
wrapper = sys.argv[-1]
|
||||
with open(wrapper, 'r+b') as f:
|
||||
raw = f.read().decode('utf-8')
|
||||
|
||||
@@ -14,12 +14,12 @@ render loop to reduce CPU usage. See :ref:`conf-kitty-performance` for details.
|
||||
See also the :opt:`sync_to_monitor` option to further decrease latency at the cost
|
||||
of some `tearing <https://en.wikipedia.org/wiki/Screen_tearing>`_ while scrolling.
|
||||
|
||||
You can generate detailed per-function performance data using
|
||||
`gperftools <https://github.com/gperftools/gperftools>`_. Build |kitty| with
|
||||
`make profile` which will create an executable called `kitty-profile`. Run
|
||||
that and perform the task you want to analyse, for example, scrolling a large
|
||||
file with `less`. After you quit, function call statistics will be printed to
|
||||
`stdout` and you can use tools like *kcachegrind* for more detailed analysis.
|
||||
You can generate detailed per-function performance data using `gperftools
|
||||
<https://github.com/gperftools/gperftools>`_. Build |kitty| with `make
|
||||
profile`. Run kitty and perform the task you want to analyse, for example,
|
||||
scrolling a large file with `less`. After you quit, function call statistics
|
||||
will be printed to `stdout` and you can use tools like *kcachegrind* for more
|
||||
detailed analysis.
|
||||
|
||||
Here are some CPU usage numbers for the task of scrolling a file continuously
|
||||
in less. The CPU usage is for the terminal process and X together and is
|
||||
|
||||
@@ -43,6 +43,10 @@ You can choose where to run the pipe program:
|
||||
``tab``
|
||||
A new window in a new tab
|
||||
|
||||
``clipboard, primary``
|
||||
Copy the text directly to the clipboard. In this case the specified program
|
||||
is not run, so use some dummy program name for it.
|
||||
|
||||
``none``
|
||||
Run it in the background
|
||||
|
||||
|
||||
29
docs/rc_protocol.rst
Normal file
29
docs/rc_protocol.rst
Normal file
@@ -0,0 +1,29 @@
|
||||
Documentation for the kitty remote control protocol
|
||||
======================================================
|
||||
|
||||
The kitty remote control protocol is a simple protocol that involves sending
|
||||
data to kitty in the form of JSON. Any individual command of kitty has the
|
||||
form::
|
||||
|
||||
<ESC>P@kitty-cmd<JSON object><ESC>\
|
||||
|
||||
Where ``<ESC>`` is the byte ``0x1b``. The JSON object has the form::
|
||||
|
||||
{
|
||||
'cmd': "command name",
|
||||
'version': "kitty version",
|
||||
'no_response': Optional Boolean,
|
||||
'payload': <Optional JSON object>,
|
||||
}
|
||||
|
||||
The ``version`` above is a string of the form :code:`0.14.2`. If you are developing a
|
||||
standalone client, use the kitty version that you are developing against. Using
|
||||
a version greater than the version of the kitty instance you are talking to,
|
||||
will cause a failure.
|
||||
|
||||
Set ``no_response`` to True if you don't want a response from kitty.
|
||||
|
||||
The optional payload is a JSON object that is specific to the actual command being sent.
|
||||
The fields in the object for every command are documented below.
|
||||
|
||||
.. include:: generated/rc.rst
|
||||
@@ -134,5 +134,10 @@ still write to the pipes of any other program on the same computer and
|
||||
therefore can control |kitty|. It can, however, be useful to block programs
|
||||
running on other computers (for example, over ssh) or as other users.
|
||||
|
||||
Documentation for the remote control protocol
|
||||
-----------------------------------------------
|
||||
|
||||
If you wish to develop your own client to talk to |kitty|, you
|
||||
can use the :doc:`rc_protocol`.
|
||||
|
||||
.. include:: generated/cli-kitty-at.rst
|
||||
|
||||
@@ -93,7 +93,7 @@ def generate(function_name, callback_name, report_name, keymap, command_class, i
|
||||
report_cmd = cmd_for_report(report_name, keymap, type_map, payload_allowed)
|
||||
if payload_allowed:
|
||||
payload_after_value = "case ';': state = PAYLOAD; break;"
|
||||
payload = payload = ', PAYLOAD'
|
||||
payload = ', PAYLOAD'
|
||||
parr = 'static uint8_t payload[4096];'
|
||||
payload_case = f'''
|
||||
case PAYLOAD: {{
|
||||
|
||||
@@ -29,10 +29,12 @@ def get_data(fname, folder='UCD'):
|
||||
bn = os.path.basename(url)
|
||||
local = os.path.join('/tmp', bn)
|
||||
if os.path.exists(local):
|
||||
data = open(local, 'rb').read()
|
||||
with open(local, 'rb') as f:
|
||||
data = f.read()
|
||||
else:
|
||||
data = urlopen(url).read()
|
||||
open(local, 'wb').write(data)
|
||||
with open(local, 'wb') as f:
|
||||
f.write(data)
|
||||
for line in data.decode('utf-8').splitlines():
|
||||
line = line.strip()
|
||||
if line and not line.startswith('#'):
|
||||
@@ -166,21 +168,20 @@ def write_case(spec, p):
|
||||
|
||||
@contextmanager
|
||||
def create_header(path, include_data_types=True):
|
||||
f = open(path, 'w')
|
||||
p = partial(print, file=f)
|
||||
p('// unicode data, built from the unicode standard on:', date.today())
|
||||
p('// see gen-wcwidth.py')
|
||||
if path.endswith('.h'):
|
||||
p('#pragma once')
|
||||
if include_data_types:
|
||||
p('#include "data-types.h"\n')
|
||||
p('START_ALLOW_CASE_RANGE')
|
||||
p()
|
||||
yield p
|
||||
p()
|
||||
if include_data_types:
|
||||
p('END_ALLOW_CASE_RANGE')
|
||||
f.close()
|
||||
with open(path, 'w') as f:
|
||||
p = partial(print, file=f)
|
||||
p('// unicode data, built from the unicode standard on:', date.today())
|
||||
p('// see gen-wcwidth.py')
|
||||
if path.endswith('.h'):
|
||||
p('#pragma once')
|
||||
if include_data_types:
|
||||
p('#include "data-types.h"\n')
|
||||
p('START_ALLOW_CASE_RANGE')
|
||||
p()
|
||||
yield p
|
||||
p()
|
||||
if include_data_types:
|
||||
p('END_ALLOW_CASE_RANGE')
|
||||
|
||||
|
||||
def gen_emoji():
|
||||
@@ -282,7 +283,9 @@ def gen_ucd():
|
||||
p('combining_type mark_for_codepoint(char_type c) {')
|
||||
rmap = codepoint_to_mark_map(p, mark_map)
|
||||
p('}\n')
|
||||
expected = int(re.search(r'^#define VS15 (\d+)', open('kitty/unicode-data.h').read(), re.M).group(1))
|
||||
with open('kitty/unicode-data.h') as f:
|
||||
unicode_data = f.read()
|
||||
expected = int(re.search(r'^#define VS15 (\d+)', unicode_data, re.M).group(1))
|
||||
if rmap[0xfe0e] != expected:
|
||||
raise ValueError('The mark for 0xfe0e has changed, you have to update VS15 to {} and VS16 to {} in unicode-data.h'.format(
|
||||
rmap[0xfe0e], rmap[0xfe0f]
|
||||
|
||||
@@ -8,9 +8,11 @@ import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
|
||||
cmdline = (
|
||||
'glad --profile core --out-path {dest} --api gl=3.3 --generator {generator} --spec gl'
|
||||
' --extensions GL_ARB_texture_storage,GL_ARB_copy_image,GL_ARB_multisample,GL_ARB_robustness,GL_KHR_debug'
|
||||
'glad --out-path {dest} --api gl:core=3.3 '
|
||||
' --extensions GL_ARB_texture_storage,GL_ARB_copy_image,GL_ARB_multisample,GL_ARB_robustness,GL_KHR_debug '
|
||||
'c --header-only --debug'
|
||||
)
|
||||
|
||||
|
||||
@@ -23,7 +25,7 @@ def regenerate():
|
||||
clean('out')
|
||||
|
||||
subprocess.check_call(
|
||||
shlex.split(cmdline.format(dest='out', generator='c-debug'))
|
||||
shlex.split(cmdline.format(dest='out'))
|
||||
)
|
||||
|
||||
|
||||
@@ -32,33 +34,12 @@ def strip_trailing_whitespace(c):
|
||||
|
||||
|
||||
def export():
|
||||
c = open('out/src/glad.c', 'rb').read().decode('utf-8')
|
||||
functions = []
|
||||
with open('out/include/glad/gl.h', 'r', encoding='utf-8') as source:
|
||||
data = source.read()
|
||||
data = strip_trailing_whitespace(data)
|
||||
|
||||
def sub(m):
|
||||
functions.append(m.group(2))
|
||||
return m.group()
|
||||
|
||||
c = re.sub(r'^([A-Z0-9]+) glad_debug_([a-zA-Z0-9]+) = glad_debug_impl_\2;$', sub, c, flags=re.M)
|
||||
switch = ['glad_debug_{0} = glad_{0}'.format(f) for f in functions]
|
||||
c = c.replace('<glad/glad.h>', '"gl-wrapper.h"', 1)
|
||||
c = '#pragma GCC diagnostic ignored "-Wpedantic"\n' + c
|
||||
c += '''
|
||||
int
|
||||
init_glad(GLADloadproc load, int debug) {
|
||||
int ret = gladLoadGLLoader(load);
|
||||
if (ret && !debug) {
|
||||
SUB;
|
||||
}
|
||||
return ret;
|
||||
}'''.replace('SUB', ';\n '.join(switch), 1)
|
||||
open('../kitty/gl-wrapper.c', 'w').write(strip_trailing_whitespace(c))
|
||||
raw = open('out/include/glad/glad.h').read()
|
||||
raw = raw.replace('<KHR/khrplatform.h>', '"khrplatform.h"')
|
||||
raw += '\nint init_glad(GLADloadproc, int);\n'
|
||||
open('../kitty/gl-wrapper.h', 'w').write(strip_trailing_whitespace(raw))
|
||||
raw = open('out/include/KHR/khrplatform.h', 'rb').read().decode('utf-8')
|
||||
open('../kitty/khrplatform.h', 'w').write(strip_trailing_whitespace(raw))
|
||||
with open('../kitty/gl-wrapper.h', 'w', encoding='utf-8') as dest:
|
||||
dest.write(data)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
89
glfw/backend_utils.c
vendored
89
glfw/backend_utils.c
vendored
@@ -11,6 +11,8 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <float.h>
|
||||
#include <time.h>
|
||||
@@ -220,24 +222,90 @@ dispatchTimers(EventLoopData *eld) {
|
||||
}
|
||||
|
||||
static void
|
||||
drain_wakeup_fd(int fd, int events, void* data) {
|
||||
drain_wakeup_fd(int fd, EventLoopData* eld) {
|
||||
static char drain_buf[64];
|
||||
while(read(fd, drain_buf, sizeof(drain_buf)) < 0 && errno == EINTR);
|
||||
eld->wakeup_data_read = false;
|
||||
while(true) {
|
||||
ssize_t ret = read(fd, drain_buf, sizeof(drain_buf));
|
||||
if (ret < 0) {
|
||||
if (errno == EINTR) continue;
|
||||
break;
|
||||
}
|
||||
if (ret > 0) { eld->wakeup_data_read = true; continue; }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mark_wakep_fd_ready(int fd UNUSED, int events UNUSED, void *data) {
|
||||
((EventLoopData*)(data))->wakeup_fd_ready = true;
|
||||
}
|
||||
|
||||
bool
|
||||
initPollData(EventLoopData *eld, int display_fd) {
|
||||
if (!addWatch(eld, "display", display_fd, POLLIN, 1, NULL, NULL)) return false;
|
||||
#ifdef HAS_EVENT_FD
|
||||
eld->wakeupFd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
|
||||
if (eld->wakeupFd == -1) return false;
|
||||
const int wakeup_fd = eld->wakeupFd;
|
||||
#else
|
||||
if (pipe2(eld->wakeupFds, O_CLOEXEC | O_NONBLOCK) != 0) return false;
|
||||
const int wakeup_fd = eld->wakeupFds[0];
|
||||
#endif
|
||||
if (!addWatch(eld, "wakeup", wakeup_fd, POLLIN, 1, mark_wakep_fd_ready, eld)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
initPollData(EventLoopData *eld, int wakeup_fd, int display_fd) {
|
||||
addWatch(eld, "display", display_fd, POLLIN, 1, NULL, NULL);
|
||||
addWatch(eld, "wakeup", wakeup_fd, POLLIN, 1, drain_wakeup_fd, NULL);
|
||||
check_for_wakeup_events(EventLoopData *eld) {
|
||||
#ifdef HAS_EVENT_FD
|
||||
int fd = eld->wakeupFd;
|
||||
#else
|
||||
int fd = eld->wakeupFds[0];
|
||||
#endif
|
||||
drain_wakeup_fd(fd, eld);
|
||||
}
|
||||
|
||||
void
|
||||
wakeupEventLoop(EventLoopData *eld) {
|
||||
#ifdef HAS_EVENT_FD
|
||||
static const uint64_t value = 1;
|
||||
while (write(eld->wakeupFd, &value, sizeof value) < 0 && (errno == EINTR || errno == EAGAIN));
|
||||
#else
|
||||
while (write(eld->wakeupFds[1], "w", 1) < 0 && (errno == EINTR || errno == EAGAIN));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef HAS_EVENT_FD
|
||||
static inline void
|
||||
closeFds(int *fds, size_t count) {
|
||||
while(count--) {
|
||||
if (*fds > 0) {
|
||||
close(*fds);
|
||||
*fds = -1;
|
||||
}
|
||||
fds++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
finalizePollData(EventLoopData *eld) {
|
||||
#ifdef HAS_EVENT_FD
|
||||
close(eld->wakeupFd); eld->wakeupFd = -1;
|
||||
#else
|
||||
closeFds(eld->wakeupFds, arraysz(eld->wakeupFds));
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
pollForEvents(EventLoopData *eld, double timeout) {
|
||||
int read_ok = 0;
|
||||
timeout = prepareForPoll(eld, timeout);
|
||||
EVDBG("pollForEvents final timeout: %.3f", timeout);
|
||||
int result;
|
||||
double end_time = monotonic() + timeout;
|
||||
eld->wakeup_fd_ready = false;
|
||||
|
||||
while(1) {
|
||||
if (timeout >= 0) {
|
||||
@@ -270,17 +338,6 @@ pollForEvents(EventLoopData *eld, double timeout) {
|
||||
return read_ok;
|
||||
}
|
||||
|
||||
void
|
||||
closeFds(int *fds, size_t count) {
|
||||
while(count--) {
|
||||
if (*fds > 0) {
|
||||
close(*fds);
|
||||
*fds = -1;
|
||||
}
|
||||
fds++;
|
||||
}
|
||||
}
|
||||
|
||||
// Splits and translates a text/uri-list into separate file paths
|
||||
// NOTE: This function destroys the provided string
|
||||
//
|
||||
|
||||
23
glfw/backend_utils.h
vendored
23
glfw/backend_utils.h
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Wayland - www.glfw.org
|
||||
// GLFW 3.4 Wayland - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
|
||||
//
|
||||
@@ -29,6 +29,16 @@
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __has_include
|
||||
#if __has_include(<sys/eventfd.h>)
|
||||
#define HAS_EVENT_FD
|
||||
#include <sys/eventfd.h>
|
||||
#endif
|
||||
#else
|
||||
#define HAS_EVENT_FD
|
||||
#include <sys/eventfd.h>
|
||||
#endif
|
||||
|
||||
typedef unsigned long long id_type;
|
||||
typedef void(*watch_callback_func)(int, int, void*);
|
||||
typedef void(*timer_callback_func)(id_type, void*);
|
||||
@@ -56,13 +66,19 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
struct pollfd fds[32];
|
||||
#ifdef HAS_EVENT_FD
|
||||
int wakeupFd;
|
||||
#else
|
||||
int wakeupFds[2];
|
||||
#endif
|
||||
bool wakeup_data_read, wakeup_fd_ready;
|
||||
nfds_t watches_count, timers_count;
|
||||
Watch watches[32];
|
||||
Timer timers[128];
|
||||
} EventLoopData;
|
||||
|
||||
|
||||
void check_for_wakeup_events(EventLoopData *eld);
|
||||
id_type addWatch(EventLoopData *eld, const char *name, int fd, int events, int enabled, watch_callback_func cb, void *cb_data);
|
||||
void removeWatch(EventLoopData *eld, id_type watch_id);
|
||||
void toggleWatch(EventLoopData *eld, id_type watch_id, int enabled);
|
||||
@@ -75,6 +91,7 @@ double prepareForPoll(EventLoopData *eld, double timeout);
|
||||
int pollWithTimeout(struct pollfd *fds, nfds_t nfds, double timeout);
|
||||
int pollForEvents(EventLoopData *eld, double timeout);
|
||||
unsigned dispatchTimers(EventLoopData *eld);
|
||||
void closeFds(int *fds, size_t count);
|
||||
void initPollData(EventLoopData *eld, int wakeup_fd, int display_fd);
|
||||
void finalizePollData(EventLoopData *eld);
|
||||
bool initPollData(EventLoopData *eld, int display_fd);
|
||||
char** parseUriList(char* text, int* count);
|
||||
void wakeupEventLoop(EventLoopData *eld);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 macOS - www.glfw.org
|
||||
// GLFW 3.4 macOS - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -23,9 +23,12 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
#include <sys/param.h> // For MAXPATHLEN
|
||||
#include <pthread.h>
|
||||
|
||||
// Change to our application bundle's resources directory, if present
|
||||
//
|
||||
@@ -197,7 +200,7 @@ static void createKeyTables(void)
|
||||
|
||||
// Retrieve Unicode data for the current keyboard layout
|
||||
//
|
||||
static GLFWbool updateUnicodeDataNS(void)
|
||||
static bool updateUnicodeDataNS(void)
|
||||
{
|
||||
if (_glfw.ns.inputSource)
|
||||
{
|
||||
@@ -214,7 +217,7 @@ static GLFWbool updateUnicodeDataNS(void)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Cocoa: Failed to retrieve keyboard layout input source");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfw.ns.unicodeData =
|
||||
@@ -224,15 +227,15 @@ static GLFWbool updateUnicodeDataNS(void)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Cocoa: Failed to retrieve keyboard layout Unicode data");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Load HIToolbox.framework and the TIS symbols we need from it
|
||||
//
|
||||
static GLFWbool initializeTIS(void)
|
||||
static bool initializeTIS(void)
|
||||
{
|
||||
// This works only because Cocoa has already loaded it properly
|
||||
_glfw.ns.tis.bundle =
|
||||
@@ -241,19 +244,19 @@ static GLFWbool initializeTIS(void)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Cocoa: Failed to load HIToolbox.framework");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
CFStringRef* kPropertyUnicodeKeyLayoutData =
|
||||
CFBundleGetDataPointerForName(_glfw.ns.tis.bundle,
|
||||
CFSTR("kTISPropertyUnicodeKeyLayoutData"));
|
||||
_glfw.ns.tis.CopyCurrentKeyboardLayoutInputSource =
|
||||
*(void **)&_glfw.ns.tis.CopyCurrentKeyboardLayoutInputSource =
|
||||
CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
|
||||
CFSTR("TISCopyCurrentKeyboardLayoutInputSource"));
|
||||
_glfw.ns.tis.GetInputSourceProperty =
|
||||
*(void **)&_glfw.ns.tis.GetInputSourceProperty =
|
||||
CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
|
||||
CFSTR("TISGetInputSourceProperty"));
|
||||
_glfw.ns.tis.GetKbdType =
|
||||
*(void **)&_glfw.ns.tis.GetKbdType =
|
||||
CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
|
||||
CFSTR("LMGetKbdType"));
|
||||
|
||||
@@ -264,7 +267,7 @@ static GLFWbool initializeTIS(void)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Cocoa: Failed to load TIS API symbols");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfw.ns.tis.kPropertyUnicodeKeyLayoutData =
|
||||
@@ -280,14 +283,16 @@ static GLFWbool initializeTIS(void)
|
||||
|
||||
- (void)selectedKeyboardInputSourceChanged:(NSObject* )object
|
||||
{
|
||||
(void)object;
|
||||
updateUnicodeDataNS();
|
||||
}
|
||||
|
||||
- (void)doNothing:(id)object
|
||||
{
|
||||
(void)object;
|
||||
}
|
||||
|
||||
@end // GLFWHelper
|
||||
@end // GLFWHelper
|
||||
|
||||
@interface GLFWApplication : NSApplication
|
||||
- (void)tick_callback;
|
||||
@@ -307,24 +312,33 @@ static GLFWbool initializeTIS(void)
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline bool
|
||||
is_ctrl_tab(NSEvent *event, NSEventModifierFlags modifierFlags) {
|
||||
return event.keyCode == kVK_Tab && (modifierFlags == NSEventModifierFlagControl || modifierFlags == (
|
||||
NSEventModifierFlagControl | NSEventModifierFlagShift));
|
||||
if (
|
||||
(modifierFlags == NSEventModifierFlagControl &&
|
||||
[event.charactersIgnoringModifiers isEqualToString:@"\t"]) ||
|
||||
(modifierFlags == (NSEventModifierFlagControl | NSEventModifierFlagShift) &&
|
||||
[event.charactersIgnoringModifiers isEqualToString:@"\x19"])
|
||||
) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_cmd_period(NSEvent *event, NSEventModifierFlags modifierFlags) {
|
||||
return event.keyCode == kVK_ANSI_Period && modifierFlags == NSEventModifierFlagCommand;
|
||||
if (modifierFlags != NSEventModifierFlagCommand) return false;
|
||||
if ([event.charactersIgnoringModifiers isEqualToString:@"."]) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int _glfwPlatformInit(void)
|
||||
{
|
||||
@autoreleasepool {
|
||||
|
||||
_glfw.ns.helper = [[GLFWHelper alloc] init];
|
||||
|
||||
[NSThread detachNewThreadSelector:@selector(doNothing:)
|
||||
@@ -367,6 +381,7 @@ int _glfwPlatformInit(void)
|
||||
_glfw.ns.keyDownMonitor =
|
||||
[NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskKeyDown
|
||||
handler:keydown_block];
|
||||
|
||||
if (_glfw.hints.init.ns.chdir)
|
||||
changeToResourcesDirectory();
|
||||
|
||||
@@ -380,31 +395,27 @@ int _glfwPlatformInit(void)
|
||||
|
||||
_glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
|
||||
if (!_glfw.ns.eventSource)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
CGEventSourceSetLocalEventsSuppressionInterval(_glfw.ns.eventSource, 0.0);
|
||||
|
||||
if (!initializeTIS())
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
_glfw.ns.displayLinks.lock = [NSLock new];
|
||||
_glfwInitTimerNS();
|
||||
_glfwInitJoysticksNS();
|
||||
|
||||
_glfwPollMonitorsNS();
|
||||
}
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
|
||||
} // autoreleasepool
|
||||
}
|
||||
|
||||
void _glfwPlatformTerminate(void)
|
||||
{
|
||||
@autoreleasepool {
|
||||
|
||||
if (_glfw.ns.displayLinks.lock) {
|
||||
_glfwClearDisplayLinks();
|
||||
[_glfw.ns.displayLinks.lock release];
|
||||
_glfw.ns.displayLinks.lock = nil;
|
||||
}
|
||||
_glfwClearDisplayLinks();
|
||||
|
||||
if (_glfw.ns.inputSource)
|
||||
{
|
||||
@@ -437,6 +448,7 @@ void _glfwPlatformTerminate(void)
|
||||
[_glfw.ns.helper release];
|
||||
_glfw.ns.helper = nil;
|
||||
}
|
||||
|
||||
if (_glfw.ns.keyUpMonitor)
|
||||
[NSEvent removeMonitor:_glfw.ns.keyUpMonitor];
|
||||
if (_glfw.ns.keyDownMonitor)
|
||||
@@ -446,7 +458,8 @@ void _glfwPlatformTerminate(void)
|
||||
|
||||
_glfwTerminateNSGL();
|
||||
_glfwTerminateJoysticksNS();
|
||||
}
|
||||
|
||||
} // autoreleasepool
|
||||
}
|
||||
|
||||
const char* _glfwPlatformGetVersionString(void)
|
||||
@@ -461,32 +474,56 @@ const char* _glfwPlatformGetVersionString(void)
|
||||
static GLFWtickcallback tick_callback = NULL;
|
||||
static void* tick_callback_data = NULL;
|
||||
static bool tick_callback_requested = false;
|
||||
static pthread_t main_thread;
|
||||
static NSLock *tick_lock = NULL;
|
||||
|
||||
|
||||
void _glfwDispatchTickCallback() {
|
||||
if (tick_callback) {
|
||||
tick_callback_requested = false;
|
||||
tick_callback(tick_callback_data);
|
||||
if (tick_lock && tick_callback) {
|
||||
[tick_lock lock];
|
||||
while(tick_callback_requested) {
|
||||
tick_callback_requested = false;
|
||||
tick_callback(tick_callback_data);
|
||||
}
|
||||
[tick_lock unlock];
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformRequestTickCallback() {
|
||||
static void
|
||||
request_tick_callback() {
|
||||
if (!tick_callback_requested) {
|
||||
tick_callback_requested = true;
|
||||
[NSApp performSelectorOnMainThread:@selector(tick_callback) withObject:nil waitUntilDone:NO];
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformPostEmptyEvent(void)
|
||||
{
|
||||
if (pthread_equal(pthread_self(), main_thread)) {
|
||||
request_tick_callback();
|
||||
} else if (tick_lock) {
|
||||
[tick_lock lock];
|
||||
request_tick_callback();
|
||||
[tick_lock unlock];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _glfwPlatformStopMainLoop(void) {
|
||||
tick_callback = NULL;
|
||||
[NSApp stop:nil];
|
||||
_glfwPlatformPostEmptyEvent();
|
||||
_glfwCocoaPostEmptyEvent();
|
||||
}
|
||||
|
||||
void _glfwPlatformRunMainLoop(GLFWtickcallback callback, void* data) {
|
||||
main_thread = pthread_self();
|
||||
tick_callback = callback;
|
||||
tick_callback_data = data;
|
||||
tick_lock = [NSLock new];
|
||||
[NSApp run];
|
||||
[tick_lock release];
|
||||
tick_lock = NULL;
|
||||
tick_callback = NULL;
|
||||
tick_callback_data = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -509,10 +546,7 @@ remove_timer_at(size_t idx) {
|
||||
Timer *t = timers + idx;
|
||||
if (t->os_timer) { [t->os_timer invalidate]; t->os_timer = NULL; }
|
||||
if (t->callback_data && t->free_callback_data) { t->free_callback_data(t->id, t->callback_data); t->callback_data = NULL; }
|
||||
num_timers--;
|
||||
if (idx < num_timers) {
|
||||
memmove(timers + idx, timers + idx + 1, sizeof(timers[0]) * (num_timers - idx));
|
||||
}
|
||||
remove_i_from_array(timers, idx, num_timers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -554,7 +588,7 @@ void _glfwPlatformRemoveTimer(unsigned long long timer_id) {
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformUpdateTimer(unsigned long long timer_id, double interval, GLFWbool enabled) {
|
||||
void _glfwPlatformUpdateTimer(unsigned long long timer_id, double interval, bool enabled) {
|
||||
for (size_t i = 0; i < num_timers; i++) {
|
||||
if (timers[i].id == timer_id) {
|
||||
Timer *t = timers + i;
|
||||
|
||||
4
glfw/cocoa_joystick.h
vendored
4
glfw/cocoa_joystick.h
vendored
@@ -1,7 +1,7 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Cocoa - www.glfw.org
|
||||
// GLFW 3.4 Cocoa - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Cocoa - www.glfw.org
|
||||
// GLFW 3.4 Cocoa - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -75,7 +77,7 @@ static long getElementValue(_GLFWjoystick* js, _GLFWjoyelementNS* element)
|
||||
//
|
||||
static CFComparisonResult compareElements(const void* fp,
|
||||
const void* sp,
|
||||
void* user)
|
||||
void* user UNUSED)
|
||||
{
|
||||
const _GLFWjoyelementNS* fe = fp;
|
||||
const _GLFWjoyelementNS* se = sp;
|
||||
@@ -117,9 +119,9 @@ static void closeJoystick(_GLFWjoystick* js)
|
||||
|
||||
// Callback for user-initiated joystick addition
|
||||
//
|
||||
static void matchCallback(void* context,
|
||||
IOReturn result,
|
||||
void* sender,
|
||||
static void matchCallback(void* context UNUSED,
|
||||
IOReturn result UNUSED,
|
||||
void* sender UNUSED,
|
||||
IOHIDDeviceRef device)
|
||||
{
|
||||
int jid;
|
||||
@@ -270,9 +272,9 @@ static void matchCallback(void* context,
|
||||
|
||||
// Callback for user-initiated joystick removal
|
||||
//
|
||||
static void removeCallback(void* context,
|
||||
IOReturn result,
|
||||
void* sender,
|
||||
static void removeCallback(void* context UNUSED,
|
||||
IOReturn result UNUSED,
|
||||
void* sender UNUSED,
|
||||
IOHIDDeviceRef device)
|
||||
{
|
||||
int jid;
|
||||
@@ -316,7 +318,7 @@ void _glfwInitJoysticksNS(void)
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < sizeof(usages) / sizeof(long); i++)
|
||||
for (size_t i = 0; i < sizeof(usages) / sizeof(long); i++)
|
||||
{
|
||||
const long page = kHIDPage_GenericDesktop;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 macOS - www.glfw.org
|
||||
// GLFW 3.4 macOS - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -116,16 +118,16 @@ static char* getDisplayName(CGDirectDisplayID displayID)
|
||||
|
||||
// Check whether the display mode should be included in enumeration
|
||||
//
|
||||
static GLFWbool modeIsGood(CGDisplayModeRef mode)
|
||||
static bool modeIsGood(CGDisplayModeRef mode)
|
||||
{
|
||||
uint32_t flags = CGDisplayModeGetIOFlags(mode);
|
||||
|
||||
if (!(flags & kDisplayModeValidFlag) || !(flags & kDisplayModeSafeFlag))
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
if (flags & kDisplayModeInterlacedFlag)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
if (flags & kDisplayModeStretchedFlag)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
|
||||
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
|
||||
@@ -133,12 +135,12 @@ static GLFWbool modeIsGood(CGDisplayModeRef mode)
|
||||
CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0))
|
||||
{
|
||||
CFRelease(format);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
CFRelease(format);
|
||||
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Convert Core Graphics display mode to GLFW video mode
|
||||
@@ -215,12 +217,12 @@ static void endFadeReservation(CGDisplayFadeReservationToken token)
|
||||
|
||||
// Finds and caches the NSScreen corresponding to the specified monitor
|
||||
//
|
||||
GLFWbool refreshMonitorScreen(_GLFWmonitor* monitor)
|
||||
static bool refreshMonitorScreen(_GLFWmonitor* monitor)
|
||||
{
|
||||
if (monitor->ns.screen)
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
|
||||
for (NSScreen* screen in [NSScreen screens])
|
||||
for (NSScreen* screen in [NSScreen screens])
|
||||
{
|
||||
NSNumber* displayID = [screen deviceDescription][@"NSScreenNumber"];
|
||||
|
||||
@@ -230,12 +232,12 @@ GLFWbool refreshMonitorScreen(_GLFWmonitor* monitor)
|
||||
if (monitor->ns.unitNumber == CGDisplayUnitNumber([displayID unsignedIntValue]))
|
||||
{
|
||||
monitor->ns.screen = screen;
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to find a screen for monitor");
|
||||
return GLFW_FALSE;
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to find a screen for monitor");
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -243,49 +245,30 @@ GLFWbool refreshMonitorScreen(_GLFWmonitor* monitor)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void _glfwClearDisplayLinks() {
|
||||
[_glfw.ns.displayLinks.lock lock];
|
||||
for (size_t i = 0; i < _glfw.ns.displayLinks.count; i++) {
|
||||
if (_glfw.ns.displayLinks.entries[i].displayLinkStarted) {
|
||||
CVDisplayLinkStop(_glfw.ns.displayLinks.entries[i].displayLink);
|
||||
_glfw.ns.displayLinks.entries[i].displayLinkStarted = GLFW_FALSE;
|
||||
}
|
||||
if (_glfw.ns.displayLinks.entries[i].displayLink) {
|
||||
CVDisplayLinkStop(_glfw.ns.displayLinks.entries[i].displayLink);
|
||||
CVDisplayLinkRelease(_glfw.ns.displayLinks.entries[i].displayLink);
|
||||
_glfw.ns.displayLinks.entries[i].displayLink = nil;
|
||||
_glfw.ns.displayLinks.entries[i].lastRenderFrameRequestedAt = 0;
|
||||
}
|
||||
}
|
||||
_glfw.ns.displayLinks.count = 0;
|
||||
[_glfw.ns.displayLinks.lock unlock];
|
||||
}
|
||||
|
||||
static CVReturn displayLinkCallback(
|
||||
CVDisplayLinkRef displayLink,
|
||||
const CVTimeStamp* now, const CVTimeStamp* outputTime,
|
||||
CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* userInfo)
|
||||
CVDisplayLinkRef displayLink UNUSED,
|
||||
const CVTimeStamp* now UNUSED, const CVTimeStamp* outputTime UNUSED,
|
||||
CVOptionFlags flagsIn UNUSED, CVOptionFlags* flagsOut UNUSED, void* userInfo)
|
||||
{
|
||||
CGDirectDisplayID displayID = (CGDirectDisplayID)userInfo;
|
||||
[_glfw.ns.displayLinks.lock lock];
|
||||
GLFWbool notify = GLFW_FALSE;
|
||||
for (size_t i = 0; i < _glfw.ns.displayLinks.count; i++) {
|
||||
if (_glfw.ns.displayLinks.entries[i].displayID == displayID) {
|
||||
if (_glfw.ns.displayLinks.entries[i].renderFrameRequested) {
|
||||
notify = GLFW_TRUE;
|
||||
_glfw.ns.displayLinks.entries[i].renderFrameRequested = GLFW_FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
[_glfw.ns.displayLinks.lock unlock];
|
||||
if (notify) {
|
||||
NSNumber *arg = [NSNumber numberWithUnsignedInt:displayID];
|
||||
[NSApp performSelectorOnMainThread:@selector(render_frame_received:) withObject:arg waitUntilDone:NO];
|
||||
[arg release];
|
||||
}
|
||||
NSNumber *arg = [NSNumber numberWithUnsignedInt:displayID];
|
||||
[NSApp performSelectorOnMainThread:@selector(render_frame_received:) withObject:arg waitUntilDone:NO];
|
||||
[arg release];
|
||||
return kCVReturnSuccess;
|
||||
}
|
||||
|
||||
static inline void createDisplayLink(CGDirectDisplayID displayID) {
|
||||
[_glfw.ns.displayLinks.lock lock];
|
||||
if (_glfw.ns.displayLinks.count >= sizeof(_glfw.ns.displayLinks.entries)/sizeof(_glfw.ns.displayLinks.entries[0]) - 1) return;
|
||||
for (size_t i = 0; i < _glfw.ns.displayLinks.count; i++) {
|
||||
if (_glfw.ns.displayLinks.entries[i].displayID == displayID) return;
|
||||
@@ -295,26 +278,24 @@ static inline void createDisplayLink(CGDirectDisplayID displayID) {
|
||||
entry->displayID = displayID;
|
||||
CVDisplayLinkCreateWithCGDisplay(displayID, &entry->displayLink);
|
||||
CVDisplayLinkSetOutputCallback(entry->displayLink, &displayLinkCallback, (void*)(uintptr_t)displayID);
|
||||
[_glfw.ns.displayLinks.lock unlock];
|
||||
}
|
||||
|
||||
// Poll for changes in the set of connected monitors
|
||||
//
|
||||
void _glfwPollMonitorsNS(void)
|
||||
{
|
||||
uint32_t i, j, displayCount, disconnectedCount;
|
||||
CGDirectDisplayID* displays;
|
||||
_GLFWmonitor** disconnected = NULL;
|
||||
uint32_t displayCount;
|
||||
|
||||
CGGetOnlineDisplayList(0, NULL, &displayCount);
|
||||
displays = calloc(displayCount, sizeof(CGDirectDisplayID));
|
||||
CGDirectDisplayID* displays = calloc(displayCount, sizeof(CGDirectDisplayID));
|
||||
CGGetOnlineDisplayList(displayCount, displays, &displayCount);
|
||||
_glfwClearDisplayLinks();
|
||||
|
||||
for (i = 0; i < _glfw.monitorCount; i++)
|
||||
for (int i = 0; i < _glfw.monitorCount; i++)
|
||||
_glfw.monitors[i]->ns.screen = nil;
|
||||
|
||||
disconnectedCount = _glfw.monitorCount;
|
||||
_GLFWmonitor** disconnected = NULL;
|
||||
uint32_t disconnectedCount = _glfw.monitorCount;
|
||||
if (disconnectedCount)
|
||||
{
|
||||
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
|
||||
@@ -323,19 +304,18 @@ void _glfwPollMonitorsNS(void)
|
||||
_glfw.monitorCount * sizeof(_GLFWmonitor*));
|
||||
}
|
||||
|
||||
for (i = 0; i < displayCount; i++)
|
||||
for (uint32_t i = 0; i < displayCount; i++)
|
||||
{
|
||||
_GLFWmonitor* monitor;
|
||||
const uint32_t unitNumber = CGDisplayUnitNumber(displays[i]);
|
||||
|
||||
if (CGDisplayIsAsleep(displays[i]))
|
||||
continue;
|
||||
|
||||
for (j = 0; j < disconnectedCount; j++)
|
||||
// HACK: Compare unit numbers instead of display IDs to work around
|
||||
// display replacement on machines with automatic graphics
|
||||
// switching
|
||||
const uint32_t unitNumber = CGDisplayUnitNumber(displays[i]);
|
||||
|
||||
for (uint32_t j = 0; j < disconnectedCount; j++)
|
||||
{
|
||||
// HACK: Compare unit numbers instead of display IDs to work around
|
||||
// display replacement on machines with automatic graphics
|
||||
// switching
|
||||
if (disconnected[j] && disconnected[j]->ns.unitNumber == unitNumber)
|
||||
{
|
||||
disconnected[j] = NULL;
|
||||
@@ -348,7 +328,7 @@ void _glfwPollMonitorsNS(void)
|
||||
if (!name)
|
||||
name = _glfw_strdup("Unknown");
|
||||
|
||||
monitor = _glfwAllocMonitor(name, size.width, size.height);
|
||||
_GLFWmonitor* monitor = _glfwAllocMonitor(name, size.width, size.height);
|
||||
monitor->ns.displayID = displays[i];
|
||||
monitor->ns.unitNumber = unitNumber;
|
||||
createDisplayLink(monitor->ns.displayID);
|
||||
@@ -358,7 +338,7 @@ void _glfwPollMonitorsNS(void)
|
||||
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
|
||||
}
|
||||
|
||||
for (i = 0; i < disconnectedCount; i++)
|
||||
for (uint32_t i = 0; i < disconnectedCount; i++)
|
||||
{
|
||||
if (disconnected[i])
|
||||
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
||||
@@ -366,30 +346,27 @@ void _glfwPollMonitorsNS(void)
|
||||
|
||||
free(disconnected);
|
||||
free(displays);
|
||||
_glfwRestartDisplayLinks();
|
||||
}
|
||||
|
||||
// Change the current video mode
|
||||
//
|
||||
void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
||||
{
|
||||
CFArrayRef modes;
|
||||
CFIndex count, i;
|
||||
CVDisplayLinkRef link;
|
||||
CGDisplayModeRef native = NULL;
|
||||
GLFWvidmode current;
|
||||
const GLFWvidmode* best;
|
||||
|
||||
best = _glfwChooseVideoMode(monitor, desired);
|
||||
const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired);
|
||||
_glfwPlatformGetVideoMode(monitor, ¤t);
|
||||
if (_glfwCompareVideoModes(¤t, best) == 0)
|
||||
return;
|
||||
|
||||
CVDisplayLinkRef link;
|
||||
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
|
||||
|
||||
modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
|
||||
count = CFArrayGetCount(modes);
|
||||
CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
|
||||
const CFIndex count = CFArrayGetCount(modes);
|
||||
CGDisplayModeRef native = NULL;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
for (CFIndex i = 0; i < count; i++)
|
||||
{
|
||||
CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
|
||||
if (!modeIsGood(dm))
|
||||
@@ -438,7 +415,7 @@ void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor)
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
|
||||
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -467,7 +444,9 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
||||
*yscale = (float) (pixels.size.height / points.size.height);
|
||||
}
|
||||
|
||||
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height)
|
||||
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
|
||||
int* xpos, int* ypos,
|
||||
int* width, int* height)
|
||||
{
|
||||
if (!refreshMonitorScreen(monitor))
|
||||
return;
|
||||
@@ -487,20 +466,16 @@ void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos
|
||||
|
||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
||||
{
|
||||
CFArrayRef modes;
|
||||
CFIndex found, i, j;
|
||||
GLFWvidmode* result;
|
||||
CVDisplayLinkRef link;
|
||||
|
||||
*count = 0;
|
||||
|
||||
CVDisplayLinkRef link;
|
||||
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
|
||||
|
||||
modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
|
||||
found = CFArrayGetCount(modes);
|
||||
result = calloc(found, sizeof(GLFWvidmode));
|
||||
CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
|
||||
const CFIndex found = CFArrayGetCount(modes);
|
||||
GLFWvidmode* result = calloc(found, sizeof(GLFWvidmode));
|
||||
|
||||
for (i = 0; i < found; i++)
|
||||
for (CFIndex i = 0; i < found; i++)
|
||||
{
|
||||
CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
|
||||
if (!modeIsGood(dm))
|
||||
@@ -508,7 +483,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
||||
|
||||
const GLFWvidmode mode = vidmodeFromCGDisplayMode(dm, link);
|
||||
|
||||
for (j = 0; j < *count; j++)
|
||||
for (CFIndex j = 0; j < *count; j++)
|
||||
{
|
||||
if (_glfwCompareVideoModes(result + j, &mode) == 0)
|
||||
break;
|
||||
@@ -529,21 +504,20 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
||||
|
||||
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode)
|
||||
{
|
||||
CGDisplayModeRef displayMode;
|
||||
CVDisplayLinkRef link;
|
||||
|
||||
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
|
||||
|
||||
displayMode = CGDisplayCopyDisplayMode(monitor->ns.displayID);
|
||||
*mode = vidmodeFromCGDisplayMode(displayMode, link);
|
||||
CGDisplayModeRelease(displayMode);
|
||||
CGDisplayModeRef native = CGDisplayCopyDisplayMode(monitor->ns.displayID);
|
||||
*mode = vidmodeFromCGDisplayMode(native, link);
|
||||
CGDisplayModeRelease(native);
|
||||
|
||||
CVDisplayLinkRelease(link);
|
||||
}
|
||||
|
||||
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
{
|
||||
uint32_t i, size = CGDisplayGammaTableCapacity(monitor->ns.displayID);
|
||||
uint32_t size = CGDisplayGammaTableCapacity(monitor->ns.displayID);
|
||||
CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue));
|
||||
|
||||
CGGetDisplayTransferByTable(monitor->ns.displayID,
|
||||
@@ -555,7 +529,7 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
|
||||
_glfwAllocGammaArrays(ramp, size);
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
ramp->red[i] = (unsigned short) (values[i] * 65535);
|
||||
ramp->green[i] = (unsigned short) (values[i + size] * 65535);
|
||||
@@ -563,15 +537,14 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
}
|
||||
|
||||
free(values);
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||
{
|
||||
int i;
|
||||
CGGammaValue* values = calloc(ramp->size * 3, sizeof(CGGammaValue));
|
||||
|
||||
for (i = 0; i < ramp->size; i++)
|
||||
for (unsigned int i = 0; i < ramp->size; i++)
|
||||
{
|
||||
values[i] = ramp->red[i] / 65535.f;
|
||||
values[i + ramp->size] = ramp->green[i] / 65535.f;
|
||||
|
||||
22
glfw/cocoa_platform.h
vendored
22
glfw/cocoa_platform.h
vendored
@@ -1,7 +1,7 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 macOS - www.glfw.org
|
||||
// GLFW 3.4 macOS - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -116,8 +116,8 @@ typedef struct _GLFWwindowNS
|
||||
id view;
|
||||
id layer;
|
||||
|
||||
GLFWbool maximized;
|
||||
GLFWbool retina;
|
||||
bool maximized;
|
||||
bool retina;
|
||||
|
||||
// Cached window properties to filter out duplicate events
|
||||
int width, height;
|
||||
@@ -136,7 +136,7 @@ typedef struct _GLFWwindowNS
|
||||
// Dead key state
|
||||
UInt32 deadKeyState;
|
||||
// Whether a render frame has been requested for this window
|
||||
GLFWbool renderFrameRequested;
|
||||
bool renderFrameRequested;
|
||||
GLFWcocoarenderframefun renderFrameCallback;
|
||||
} _GLFWwindowNS;
|
||||
|
||||
@@ -144,8 +144,7 @@ typedef struct _GLFWDisplayLinkNS
|
||||
{
|
||||
CVDisplayLinkRef displayLink;
|
||||
CGDirectDisplayID displayID;
|
||||
GLFWbool displayLinkStarted;
|
||||
GLFWbool renderFrameRequested;
|
||||
double lastRenderFrameRequestedAt;
|
||||
} _GLFWDisplayLinkNS;
|
||||
|
||||
// Cocoa-specific global data
|
||||
@@ -154,7 +153,7 @@ typedef struct _GLFWlibraryNS
|
||||
{
|
||||
CGEventSourceRef eventSource;
|
||||
id delegate;
|
||||
GLFWbool cursorHidden;
|
||||
bool cursorHidden;
|
||||
TISInputSourceRef inputSource;
|
||||
IOHIDManagerRef hidManager;
|
||||
id unicodeData;
|
||||
@@ -184,7 +183,6 @@ typedef struct _GLFWlibraryNS
|
||||
struct {
|
||||
_GLFWDisplayLinkNS entries[256];
|
||||
size_t count;
|
||||
id lock;
|
||||
} displayLinks;
|
||||
|
||||
} _GLFWlibraryNS;
|
||||
@@ -222,8 +220,12 @@ void _glfwInitTimerNS(void);
|
||||
void _glfwPollMonitorsNS(void);
|
||||
void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
||||
void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor);
|
||||
|
||||
float _glfwTransformYNS(float y);
|
||||
|
||||
void _glfwClearDisplayLinks(void);
|
||||
void _glfwCocoaPostEmptyEvent(short subtype, long data1, bool at_start);
|
||||
void _glfwRestartDisplayLinks(void);
|
||||
void _glfwDispatchTickCallback(void);
|
||||
void _glfwDispatchRenderFrame(CGDirectDisplayID);
|
||||
void _glfwShutdownCVDisplayLink(unsigned long long, void*);
|
||||
void _glfwCocoaPostEmptyEvent(void);
|
||||
|
||||
4
glfw/cocoa_time.c
vendored
4
glfw/cocoa_time.c
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 macOS - www.glfw.org
|
||||
// GLFW 3.4 macOS - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
@@ -23,6 +23,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
70
glfw/context.c
vendored
70
glfw/context.c
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// Please use C89 style variable declarations in this file because VS 2010
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -44,7 +46,7 @@
|
||||
// exists and whether all relevant options have supported and non-conflicting
|
||||
// values
|
||||
//
|
||||
GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
bool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
{
|
||||
if (ctxconfig->share)
|
||||
{
|
||||
@@ -52,7 +54,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
ctxconfig->share->context.client == GLFW_NO_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +65,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
_glfwInputError(GLFW_INVALID_ENUM,
|
||||
"Invalid context creation API 0x%08X",
|
||||
ctxconfig->source);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctxconfig->client != GLFW_NO_API &&
|
||||
@@ -73,7 +75,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
_glfwInputError(GLFW_INVALID_ENUM,
|
||||
"Invalid client API 0x%08X",
|
||||
ctxconfig->client);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||
@@ -92,7 +94,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
_glfwInputError(GLFW_INVALID_VALUE,
|
||||
"Invalid OpenGL version %i.%i",
|
||||
ctxconfig->major, ctxconfig->minor);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctxconfig->profile)
|
||||
@@ -103,7 +105,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
_glfwInputError(GLFW_INVALID_ENUM,
|
||||
"Invalid OpenGL profile 0x%08X",
|
||||
ctxconfig->profile);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctxconfig->major <= 2 ||
|
||||
@@ -114,7 +116,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
|
||||
_glfwInputError(GLFW_INVALID_VALUE,
|
||||
"Context profiles are only defined for OpenGL version 3.2 and above");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +125,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
// Forward-compatible contexts are only defined for OpenGL version 3.0 and above
|
||||
_glfwInputError(GLFW_INVALID_VALUE,
|
||||
"Forward-compatibility is only defined for OpenGL version 3.0 and above");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||
@@ -140,7 +142,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
_glfwInputError(GLFW_INVALID_VALUE,
|
||||
"Invalid OpenGL ES version %i.%i",
|
||||
ctxconfig->major, ctxconfig->minor);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +154,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
_glfwInputError(GLFW_INVALID_ENUM,
|
||||
"Invalid context robustness mode 0x%08X",
|
||||
ctxconfig->robustness);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,11 +166,11 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
_glfwInputError(GLFW_INVALID_ENUM,
|
||||
"Invalid context release behavior 0x%08X",
|
||||
ctxconfig->release);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Chooses the framebuffer config that best matches the desired one
|
||||
@@ -341,7 +343,7 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
|
||||
|
||||
// Retrieves the attributes of the current context
|
||||
//
|
||||
GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
bool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig)
|
||||
{
|
||||
int i;
|
||||
@@ -369,7 +371,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Entry point retrieval is broken");
|
||||
glfwMakeContextCurrent((GLFWwindow*) previous);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
version = (const char*) window->context.GetString(GL_VERSION);
|
||||
@@ -387,7 +389,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent((GLFWwindow*) previous);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; prefixes[i]; i++)
|
||||
@@ -419,7 +421,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent((GLFWwindow*) previous);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (window->context.major < ctxconfig->major ||
|
||||
@@ -449,7 +451,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent((GLFWwindow*) previous);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (window->context.major >= 3)
|
||||
@@ -465,7 +467,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Entry point retrieval is broken");
|
||||
glfwMakeContextCurrent((GLFWwindow*) previous);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,21 +480,21 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
window->context.GetIntegerv(GL_CONTEXT_FLAGS, &flags);
|
||||
|
||||
if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
|
||||
window->context.forward = GLFW_TRUE;
|
||||
window->context.forward = true;
|
||||
|
||||
if (flags & GL_CONTEXT_FLAG_DEBUG_BIT)
|
||||
window->context.debug = GLFW_TRUE;
|
||||
window->context.debug = true;
|
||||
else if (glfwExtensionSupported("GL_ARB_debug_output") &&
|
||||
ctxconfig->debug)
|
||||
{
|
||||
// HACK: This is a workaround for older drivers (pre KHR_debug)
|
||||
// not setting the debug bit in the context flags for
|
||||
// debug contexts
|
||||
window->context.debug = GLFW_TRUE;
|
||||
window->context.debug = true;
|
||||
}
|
||||
|
||||
if (flags & GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR)
|
||||
window->context.noerror = GLFW_TRUE;
|
||||
window->context.noerror = true;
|
||||
}
|
||||
|
||||
// Read back OpenGL context profile (OpenGL 3.2 and above)
|
||||
@@ -572,12 +574,12 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent((GLFWwindow*) previous);
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Searches an extension string for the specified extension
|
||||
//
|
||||
GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions)
|
||||
bool _glfwStringInExtensionString(const char* string, const char* extensions)
|
||||
{
|
||||
const char* start = extensions;
|
||||
|
||||
@@ -588,7 +590,7 @@ GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions
|
||||
|
||||
where = strstr(start, string);
|
||||
if (!where)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
terminator = where + strlen(string);
|
||||
if (where == start || *(where - 1) == ' ')
|
||||
@@ -600,7 +602,7 @@ GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions
|
||||
start = terminator;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -677,20 +679,20 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
|
||||
_GLFWwindow* window;
|
||||
assert(extension != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(false);
|
||||
|
||||
window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||
if (!window)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_CURRENT_CONTEXT,
|
||||
"Cannot query extension without a current OpenGL or OpenGL ES context");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*extension == '\0')
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE, "Extension name cannot be an empty string");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (window->context.major >= 3)
|
||||
@@ -710,11 +712,11 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Extension string retrieval is broken");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strcmp(en, extension) == 0)
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -727,11 +729,11 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Extension string retrieval is broken");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_glfwStringInExtensionString(extension, extensions))
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if extension is in the platform-specific string
|
||||
|
||||
52
glfw/dbus_glfw.c
vendored
52
glfw/dbus_glfw.c
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 XKB - www.glfw.org
|
||||
// GLFW 3.4 XKB - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2018 Kovid Goyal <kovid@kovidgoyal.net>
|
||||
//
|
||||
@@ -45,15 +45,15 @@ report_error(DBusError *err, const char *fmt, ...) {
|
||||
static _GLFWDBUSData *dbus_data = NULL;
|
||||
static DBusConnection *session_bus = NULL;
|
||||
|
||||
GLFWbool
|
||||
bool
|
||||
glfw_dbus_init(_GLFWDBUSData *dbus, EventLoopData *eld) {
|
||||
dbus->eld = eld;
|
||||
dbus_data = dbus;
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
on_dbus_watch_ready(int fd, int events, void *data) {
|
||||
on_dbus_watch_ready(int fd UNUSED, int events, void *data) {
|
||||
DBusWatch *watch = (DBusWatch*)data;
|
||||
unsigned int flags = 0;
|
||||
if (events & POLLERR) flags |= DBUS_WATCH_ERROR;
|
||||
@@ -84,19 +84,19 @@ add_dbus_watch(DBusWatch *watch, void *data) {
|
||||
}
|
||||
|
||||
static void
|
||||
remove_dbus_watch(DBusWatch *watch, void *data) {
|
||||
remove_dbus_watch(DBusWatch *watch, void *data UNUSED) {
|
||||
id_type *idp = dbus_watch_get_data(watch);
|
||||
if (idp) removeWatch(dbus_data->eld, *idp);
|
||||
}
|
||||
|
||||
static void
|
||||
toggle_dbus_watch(DBusWatch *watch, void *data) {
|
||||
toggle_dbus_watch(DBusWatch *watch, void *data UNUSED) {
|
||||
id_type *idp = dbus_watch_get_data(watch);
|
||||
if (idp) toggleWatch(dbus_data->eld, *idp, dbus_watch_get_enabled(watch));
|
||||
}
|
||||
|
||||
static void
|
||||
on_dbus_timer_ready(id_type timer_id, void *data) {
|
||||
on_dbus_timer_ready(id_type timer_id UNUSED, void *data) {
|
||||
if (data) {
|
||||
DBusTimeout *t = (DBusTimeout*)data;
|
||||
dbus_timeout_handle(t);
|
||||
@@ -123,20 +123,20 @@ add_dbus_timeout(DBusTimeout *timeout, void *data) {
|
||||
}
|
||||
|
||||
static void
|
||||
remove_dbus_timeout(DBusTimeout *timeout, void *data) {
|
||||
remove_dbus_timeout(DBusTimeout *timeout, void *data UNUSED) {
|
||||
id_type *idp = dbus_timeout_get_data(timeout);
|
||||
if (idp) removeTimer(dbus_data->eld, *idp);
|
||||
}
|
||||
|
||||
static void
|
||||
toggle_dbus_timeout(DBusTimeout *timeout, void *data) {
|
||||
toggle_dbus_timeout(DBusTimeout *timeout, void *data UNUSED) {
|
||||
id_type *idp = dbus_timeout_get_data(timeout);
|
||||
if (idp) toggleTimer(dbus_data->eld, *idp, dbus_timeout_get_enabled(timeout));
|
||||
}
|
||||
|
||||
|
||||
DBusConnection*
|
||||
glfw_dbus_connect_to(const char *path, const char* err_msg, const char *name, GLFWbool register_on_bus) {
|
||||
glfw_dbus_connect_to(const char *path, const char* err_msg, const char *name, bool register_on_bus) {
|
||||
DBusError err;
|
||||
dbus_error_init(&err);
|
||||
DBusConnection *ans = dbus_connection_open_private(path, &err);
|
||||
@@ -178,7 +178,7 @@ glfw_dbus_session_bus_dispatch() {
|
||||
}
|
||||
|
||||
void
|
||||
glfw_dbus_terminate(_GLFWDBUSData *dbus) {
|
||||
glfw_dbus_terminate(_GLFWDBUSData *dbus UNUSED) {
|
||||
if (dbus_data) {
|
||||
dbus_data->eld = NULL;
|
||||
dbus_data = NULL;
|
||||
@@ -195,14 +195,14 @@ glfw_dbus_close_connection(DBusConnection *conn) {
|
||||
dbus_connection_unref(conn);
|
||||
}
|
||||
|
||||
GLFWbool
|
||||
bool
|
||||
glfw_dbus_get_args(DBusMessage *msg, const char *failmsg, ...) {
|
||||
DBusError err;
|
||||
dbus_error_init(&err);
|
||||
va_list ap;
|
||||
va_start(ap, failmsg);
|
||||
int firstarg = va_arg(ap, int);
|
||||
GLFWbool ret = dbus_message_get_args_valist(msg, &err, firstarg, ap) ? GLFW_TRUE : GLFW_FALSE;
|
||||
bool ret = dbus_message_get_args_valist(msg, &err, firstarg, ap) ? true : false;
|
||||
va_end(ap);
|
||||
if (!ret) report_error(&err, failmsg);
|
||||
return ret;
|
||||
@@ -233,25 +233,25 @@ method_reply_received(DBusPendingCall *pending, void *user_data) {
|
||||
}
|
||||
}
|
||||
|
||||
GLFWbool
|
||||
bool
|
||||
call_method_with_msg(DBusConnection *conn, DBusMessage *msg, int timeout, dbus_pending_callback callback, void *user_data) {
|
||||
GLFWbool retval = GLFW_FALSE;
|
||||
bool retval = false;
|
||||
#define REPORT(errs) _glfwInputError(GLFW_PLATFORM_ERROR, "Failed to call DBUS method: node=%s path=%s interface=%s method=%s, with error: %s", dbus_message_get_destination(msg), dbus_message_get_path(msg), dbus_message_get_interface(msg), dbus_message_get_member(msg), errs)
|
||||
if (callback) {
|
||||
DBusPendingCall *pending = NULL;
|
||||
if (dbus_connection_send_with_reply(conn, msg, &pending, timeout)) {
|
||||
MethodResponse *res = malloc(sizeof(MethodResponse));
|
||||
if (!res) return GLFW_FALSE;
|
||||
if (!res) return false;
|
||||
res->callback = callback;
|
||||
res->user_data = user_data;
|
||||
dbus_pending_call_set_notify(pending, method_reply_received, res, free);
|
||||
retval = GLFW_TRUE;
|
||||
retval = true;
|
||||
} else {
|
||||
REPORT("out of memory");
|
||||
}
|
||||
} else {
|
||||
if (dbus_connection_send(conn, msg, NULL)) {
|
||||
retval = GLFW_TRUE;
|
||||
retval = true;
|
||||
} else {
|
||||
REPORT("out of memory");
|
||||
}
|
||||
@@ -260,12 +260,12 @@ call_method_with_msg(DBusConnection *conn, DBusMessage *msg, int timeout, dbus_p
|
||||
#undef REPORT
|
||||
}
|
||||
|
||||
static GLFWbool
|
||||
static bool
|
||||
call_method(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, int timeout, dbus_pending_callback callback, void *user_data, va_list ap) {
|
||||
if (!conn) return GLFW_FALSE;
|
||||
if (!conn) return false;
|
||||
DBusMessage *msg = dbus_message_new_method_call(node, path, interface, method);
|
||||
if (!msg) return GLFW_FALSE;
|
||||
GLFWbool retval = GLFW_FALSE;
|
||||
if (!msg) return false;
|
||||
bool retval = false;
|
||||
|
||||
int firstarg = va_arg(ap, int);
|
||||
if ((firstarg == DBUS_TYPE_INVALID) || dbus_message_append_args_valist(msg, firstarg, ap)) {
|
||||
@@ -278,9 +278,9 @@ call_method(DBusConnection *conn, const char *node, const char *path, const char
|
||||
return retval;
|
||||
}
|
||||
|
||||
GLFWbool
|
||||
bool
|
||||
glfw_dbus_call_method_with_reply(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, int timeout, dbus_pending_callback callback, void* user_data, ...) {
|
||||
GLFWbool retval;
|
||||
bool retval;
|
||||
va_list ap;
|
||||
va_start(ap, user_data);
|
||||
retval = call_method(conn, node, path, interface, method, timeout, callback, user_data, ap);
|
||||
@@ -288,9 +288,9 @@ glfw_dbus_call_method_with_reply(DBusConnection *conn, const char *node, const c
|
||||
return retval;
|
||||
}
|
||||
|
||||
GLFWbool
|
||||
bool
|
||||
glfw_dbus_call_method_no_reply(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...) {
|
||||
GLFWbool retval;
|
||||
bool retval;
|
||||
va_list ap;
|
||||
va_start(ap, method);
|
||||
retval = call_method(conn, node, path, interface, method, DBUS_TIMEOUT_USE_DEFAULT, NULL, NULL, ap);
|
||||
|
||||
14
glfw/dbus_glfw.h
vendored
14
glfw/dbus_glfw.h
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 XKB - www.glfw.org
|
||||
// GLFW 3.4 XKB - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2018 Kovid Goyal <kovid@kovidgoyal.net>
|
||||
//
|
||||
@@ -37,18 +37,18 @@ typedef struct {
|
||||
} _GLFWDBUSData;
|
||||
|
||||
|
||||
GLFWbool glfw_dbus_init(_GLFWDBUSData *dbus, EventLoopData *eld);
|
||||
bool glfw_dbus_init(_GLFWDBUSData *dbus, EventLoopData *eld);
|
||||
void glfw_dbus_terminate(_GLFWDBUSData *dbus);
|
||||
DBusConnection* glfw_dbus_connect_to(const char *path, const char* err_msg, const char* name, GLFWbool register_on_bus);
|
||||
DBusConnection* glfw_dbus_connect_to(const char *path, const char* err_msg, const char* name, bool register_on_bus);
|
||||
void glfw_dbus_close_connection(DBusConnection *conn);
|
||||
GLFWbool
|
||||
bool
|
||||
call_method_with_msg(DBusConnection *conn, DBusMessage *msg, int timeout, dbus_pending_callback callback, void *user_data);
|
||||
GLFWbool
|
||||
bool
|
||||
glfw_dbus_call_method_no_reply(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...);
|
||||
GLFWbool
|
||||
bool
|
||||
glfw_dbus_call_method_with_reply(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, int timeout_ms, dbus_pending_callback callback, void *user_data, ...);
|
||||
void glfw_dbus_dispatch(DBusConnection *);
|
||||
void glfw_dbus_session_bus_dispatch(void);
|
||||
GLFWbool glfw_dbus_get_args(DBusMessage *msg, const char *failmsg, ...);
|
||||
bool glfw_dbus_get_args(DBusMessage *msg, const char *failmsg, ...);
|
||||
int glfw_dbus_match_signal(DBusMessage *msg, const char *interface, ...);
|
||||
DBusConnection* glfw_dbus_session_bus(void);
|
||||
|
||||
112
glfw/egl_context.c
vendored
112
glfw/egl_context.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 EGL - www.glfw.org
|
||||
// GLFW 3.4 EGL - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// Please use C89 style variable declarations in this file because VS 2010
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -85,7 +87,7 @@ static int getEGLConfigAttrib(EGLConfig config, int attrib)
|
||||
|
||||
// Return the EGLConfig most closely matching the specified hints
|
||||
//
|
||||
static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
||||
static bool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* desired,
|
||||
EGLConfig* result)
|
||||
{
|
||||
@@ -98,7 +100,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
||||
if (!nativeCount)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: No EGLConfigs returned");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
nativeConfigs = calloc(nativeCount, sizeof(EGLConfig));
|
||||
@@ -170,7 +172,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
||||
u->stencilBits = getEGLConfigAttrib(n, EGL_STENCIL_SIZE);
|
||||
|
||||
u->samples = getEGLConfigAttrib(n, EGL_SAMPLES);
|
||||
u->doublebuffer = GLFW_TRUE;
|
||||
u->doublebuffer = true;
|
||||
|
||||
u->handle = (uintptr_t) n;
|
||||
usableCount++;
|
||||
@@ -241,10 +243,10 @@ static int extensionSupportedEGL(const char* extension)
|
||||
if (extensions)
|
||||
{
|
||||
if (_glfwStringInExtensionString(extension, extensions))
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
static GLFWglproc getProcAddressEGL(const char* procname)
|
||||
@@ -253,8 +255,8 @@ static GLFWglproc getProcAddressEGL(const char* procname)
|
||||
|
||||
if (window->context.egl.client)
|
||||
{
|
||||
GLFWglproc proc = (GLFWglproc) _glfw_dlsym(window->context.egl.client,
|
||||
procname);
|
||||
GLFWglproc proc = NULL;
|
||||
glfw_dlsym(proc, window->context.egl.client, procname);
|
||||
if (proc)
|
||||
return proc;
|
||||
}
|
||||
@@ -297,7 +299,7 @@ static void destroyContextEGL(_GLFWwindow* window)
|
||||
|
||||
// Initialize EGL
|
||||
//
|
||||
GLFWbool _glfwInitEGL(void)
|
||||
bool _glfwInitEGL(void)
|
||||
{
|
||||
int i;
|
||||
const char* sonames[] =
|
||||
@@ -318,7 +320,7 @@ GLFWbool _glfwInitEGL(void)
|
||||
};
|
||||
|
||||
if (_glfw.egl.handle)
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
|
||||
for (i = 0; sonames[i]; i++)
|
||||
{
|
||||
@@ -330,43 +332,27 @@ GLFWbool _glfwInitEGL(void)
|
||||
if (!_glfw.egl.handle)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: Library not found");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfw.egl.prefix = (strncmp(sonames[i], "lib", 3) == 0);
|
||||
|
||||
_glfw.egl.GetConfigAttrib = (PFN_eglGetConfigAttrib)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigAttrib");
|
||||
_glfw.egl.GetConfigs = (PFN_eglGetConfigs)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigs");
|
||||
_glfw.egl.GetDisplay = (PFN_eglGetDisplay)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglGetDisplay");
|
||||
_glfw.egl.GetError = (PFN_eglGetError)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglGetError");
|
||||
_glfw.egl.Initialize = (PFN_eglInitialize)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglInitialize");
|
||||
_glfw.egl.Terminate = (PFN_eglTerminate)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglTerminate");
|
||||
_glfw.egl.BindAPI = (PFN_eglBindAPI)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglBindAPI");
|
||||
_glfw.egl.CreateContext = (PFN_eglCreateContext)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglCreateContext");
|
||||
_glfw.egl.DestroySurface = (PFN_eglDestroySurface)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglDestroySurface");
|
||||
_glfw.egl.DestroyContext = (PFN_eglDestroyContext)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglDestroyContext");
|
||||
_glfw.egl.CreateWindowSurface = (PFN_eglCreateWindowSurface)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglCreateWindowSurface");
|
||||
_glfw.egl.MakeCurrent = (PFN_eglMakeCurrent)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglMakeCurrent");
|
||||
_glfw.egl.SwapBuffers = (PFN_eglSwapBuffers)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglSwapBuffers");
|
||||
_glfw.egl.SwapInterval = (PFN_eglSwapInterval)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglSwapInterval");
|
||||
_glfw.egl.QueryString = (PFN_eglQueryString)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglQueryString");
|
||||
_glfw.egl.GetProcAddress = (PFN_eglGetProcAddress)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglGetProcAddress");
|
||||
glfw_dlsym(_glfw.egl.GetConfigAttrib, _glfw.egl.handle, "eglGetConfigAttrib");
|
||||
glfw_dlsym(_glfw.egl.GetConfigs, _glfw.egl.handle, "eglGetConfigs");
|
||||
glfw_dlsym(_glfw.egl.GetDisplay, _glfw.egl.handle, "eglGetDisplay");
|
||||
glfw_dlsym(_glfw.egl.GetError, _glfw.egl.handle, "eglGetError");
|
||||
glfw_dlsym(_glfw.egl.Initialize, _glfw.egl.handle, "eglInitialize");
|
||||
glfw_dlsym(_glfw.egl.Terminate, _glfw.egl.handle, "eglTerminate");
|
||||
glfw_dlsym(_glfw.egl.BindAPI, _glfw.egl.handle, "eglBindAPI");
|
||||
glfw_dlsym(_glfw.egl.CreateContext, _glfw.egl.handle, "eglCreateContext");
|
||||
glfw_dlsym(_glfw.egl.DestroySurface, _glfw.egl.handle, "eglDestroySurface");
|
||||
glfw_dlsym(_glfw.egl.DestroyContext, _glfw.egl.handle, "eglDestroyContext");
|
||||
glfw_dlsym(_glfw.egl.CreateWindowSurface, _glfw.egl.handle, "eglCreateWindowSurface");
|
||||
glfw_dlsym(_glfw.egl.MakeCurrent, _glfw.egl.handle, "eglMakeCurrent");
|
||||
glfw_dlsym(_glfw.egl.SwapBuffers, _glfw.egl.handle, "eglSwapBuffers");
|
||||
glfw_dlsym(_glfw.egl.SwapInterval, _glfw.egl.handle, "eglSwapInterval");
|
||||
glfw_dlsym(_glfw.egl.QueryString, _glfw.egl.handle, "eglQueryString");
|
||||
glfw_dlsym(_glfw.egl.GetProcAddress, _glfw.egl.handle, "eglGetProcAddress");
|
||||
|
||||
if (!_glfw.egl.GetConfigAttrib ||
|
||||
!_glfw.egl.GetConfigs ||
|
||||
@@ -389,7 +375,7 @@ GLFWbool _glfwInitEGL(void)
|
||||
"EGL: Failed to load required entry points");
|
||||
|
||||
_glfwTerminateEGL();
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY);
|
||||
@@ -400,7 +386,7 @@ GLFWbool _glfwInitEGL(void)
|
||||
getEGLErrorString(eglGetError()));
|
||||
|
||||
_glfwTerminateEGL();
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!eglInitialize(_glfw.egl.display, &_glfw.egl.major, &_glfw.egl.minor))
|
||||
@@ -410,7 +396,7 @@ GLFWbool _glfwInitEGL(void)
|
||||
getEGLErrorString(eglGetError()));
|
||||
|
||||
_glfwTerminateEGL();
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfw.egl.KHR_create_context =
|
||||
@@ -424,7 +410,7 @@ GLFWbool _glfwInitEGL(void)
|
||||
_glfw.egl.KHR_context_flush_control =
|
||||
extensionSupportedEGL("EGL_KHR_context_flush_control");
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Terminate EGL
|
||||
@@ -446,14 +432,14 @@ void _glfwTerminateEGL(void)
|
||||
|
||||
#define setAttrib(a, v) \
|
||||
{ \
|
||||
assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
||||
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
||||
attribs[index++] = a; \
|
||||
attribs[index++] = v; \
|
||||
}
|
||||
|
||||
// Create the OpenGL or OpenGL ES context
|
||||
//
|
||||
GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
bool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
@@ -465,7 +451,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
if (!_glfw.egl.display)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: API not available");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctxconfig->share)
|
||||
@@ -475,7 +461,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||
"EGL: Failed to find a suitable EGLConfig");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||
@@ -485,7 +471,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"EGL: Failed to bind OpenGL ES: %s",
|
||||
getEGLErrorString(eglGetError()));
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -495,7 +481,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"EGL: Failed to bind OpenGL: %s",
|
||||
getEGLErrorString(eglGetError()));
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,7 +522,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
if (ctxconfig->noerror)
|
||||
{
|
||||
if (_glfw.egl.KHR_create_context_no_error)
|
||||
setAttrib(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE);
|
||||
setAttrib(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, true);
|
||||
}
|
||||
|
||||
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
||||
@@ -581,7 +567,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"EGL: Failed to create context: %s",
|
||||
getEGLErrorString(eglGetError()));
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set up attributes for surface creation
|
||||
@@ -607,7 +593,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGL: Failed to create window surface: %s",
|
||||
getEGLErrorString(eglGetError()));
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
window->context.egl.config = config;
|
||||
@@ -695,7 +681,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"EGL: Failed to load client library");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -706,7 +692,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
window->context.getProcAddress = getProcAddressEGL;
|
||||
window->context.destroy = destroyContextEGL;
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef setAttrib
|
||||
@@ -714,7 +700,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
// Returns the Visual and depth of the chosen EGLConfig
|
||||
//
|
||||
#if defined(_GLFW_X11)
|
||||
GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
|
||||
bool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig UNUSED,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig,
|
||||
Visual** visual, int* depth)
|
||||
@@ -729,7 +715,7 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
|
||||
{
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||
"EGL: Failed to find a suitable EGLConfig");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
eglGetConfigAttrib(_glfw.egl.display, native,
|
||||
@@ -743,14 +729,14 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGL: Failed to retrieve Visual for EGLConfig");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
*visual = result->visual;
|
||||
*depth = result->depth;
|
||||
|
||||
XFree(result);
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
#endif // _GLFW_X11
|
||||
|
||||
|
||||
22
glfw/egl_context.h
vendored
22
glfw/egl_context.h
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 EGL - www.glfw.org
|
||||
// GLFW 3.4 EGL - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -173,13 +173,13 @@ typedef struct _GLFWlibraryEGL
|
||||
{
|
||||
EGLDisplay display;
|
||||
EGLint major, minor;
|
||||
GLFWbool prefix;
|
||||
bool prefix;
|
||||
|
||||
GLFWbool KHR_create_context;
|
||||
GLFWbool KHR_create_context_no_error;
|
||||
GLFWbool KHR_gl_colorspace;
|
||||
GLFWbool KHR_get_all_proc_addresses;
|
||||
GLFWbool KHR_context_flush_control;
|
||||
bool KHR_create_context;
|
||||
bool KHR_create_context_no_error;
|
||||
bool KHR_gl_colorspace;
|
||||
bool KHR_get_all_proc_addresses;
|
||||
bool KHR_context_flush_control;
|
||||
|
||||
void* handle;
|
||||
|
||||
@@ -203,13 +203,13 @@ typedef struct _GLFWlibraryEGL
|
||||
} _GLFWlibraryEGL;
|
||||
|
||||
|
||||
GLFWbool _glfwInitEGL(void);
|
||||
bool _glfwInitEGL(void);
|
||||
void _glfwTerminateEGL(void);
|
||||
GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
bool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
#if defined(_GLFW_X11)
|
||||
GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
|
||||
bool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig,
|
||||
Visual** visual, int* depth);
|
||||
|
||||
37
glfw/glfw.py
37
glfw/glfw.py
@@ -8,7 +8,6 @@ import re
|
||||
import sys
|
||||
|
||||
_plat = sys.platform.lower()
|
||||
is_macos = 'darwin' in _plat
|
||||
is_freebsd = 'freebsd' in _plat
|
||||
is_netbsd = 'netbsd' in _plat
|
||||
is_dragonflybsd = 'dragonfly' in _plat
|
||||
@@ -23,26 +22,12 @@ def wayland_protocol_file_name(base, ext='c'):
|
||||
|
||||
def init_env(env, pkg_config, at_least_version, test_compile, module='x11'):
|
||||
ans = env.copy()
|
||||
ans.cflags = [
|
||||
x for x in ans.cflags
|
||||
if x not in '-Wpedantic -Wextra -pedantic-errors'.split()
|
||||
]
|
||||
if not is_macos:
|
||||
ans.cflags.append('-pthread')
|
||||
ans.ldpaths.append('-pthread')
|
||||
ans.cflags.append('-fpic')
|
||||
ans.cppflags.append('-D_GLFW_' + module.upper())
|
||||
ans.cppflags.append('-D_GLFW_BUILD_DLL')
|
||||
|
||||
if is_macos:
|
||||
ans.cppflags.append('-DGL_SILENCE_DEPRECATION')
|
||||
ans.ldpaths.extend(
|
||||
"-framework Cocoa -framework IOKit -framework CoreFoundation -framework CoreVideo".
|
||||
split()
|
||||
)
|
||||
else:
|
||||
ans.ldpaths.extend('-lrt -lm -ldl'.split())
|
||||
sinfo = json.load(open(os.path.join(base, 'source-info.json')))
|
||||
with open(os.path.join(base, 'source-info.json')) as f:
|
||||
sinfo = json.load(f)
|
||||
module_sources = list(sinfo[module]['sources'])
|
||||
if module in ('x11', 'wayland'):
|
||||
remove = 'linux_joystick.c' if is_bsd else 'null_joystick.c'
|
||||
@@ -52,6 +37,9 @@ def init_env(env, pkg_config, at_least_version, test_compile, module='x11'):
|
||||
ans.all_headers = [x for x in os.listdir(base) if x.endswith('.h')]
|
||||
|
||||
if module in ('x11', 'wayland'):
|
||||
ans.cflags.append('-pthread')
|
||||
ans.ldpaths.append('-pthread')
|
||||
ans.ldpaths.extend('-lrt -lm -ldl'.split())
|
||||
at_least_version('xkbcommon', 0, 5)
|
||||
|
||||
if module == 'x11':
|
||||
@@ -60,6 +48,7 @@ def init_env(env, pkg_config, at_least_version, test_compile, module='x11'):
|
||||
ans.ldpaths.extend(pkg_config(dep, '--libs'))
|
||||
|
||||
elif module == 'cocoa':
|
||||
ans.cppflags.append('-DGL_SILENCE_DEPRECATION')
|
||||
for f in 'Cocoa IOKit CoreFoundation CoreVideo'.split():
|
||||
ans.ldpaths.extend(('-framework', f))
|
||||
|
||||
@@ -88,7 +77,8 @@ def init_env(env, pkg_config, at_least_version, test_compile, module='x11'):
|
||||
return ans
|
||||
|
||||
|
||||
def build_wayland_protocols(env, run_tool, emphasis, newer, dest_dir):
|
||||
def build_wayland_protocols(env, Command, parallel_run, emphasis, newer, dest_dir):
|
||||
items = []
|
||||
for protocol in env.wayland_protocols:
|
||||
src = os.path.join(env.wayland_packagedir, protocol)
|
||||
if not os.path.exists(src):
|
||||
@@ -98,8 +88,12 @@ def build_wayland_protocols(env, run_tool, emphasis, newer, dest_dir):
|
||||
dest = os.path.join(dest_dir, dest)
|
||||
if newer(dest, src):
|
||||
q = 'client-header' if ext == 'h' else env.wayland_scanner_code
|
||||
run_tool([env.wayland_scanner, q, src, dest],
|
||||
desc='Generating {} ...'.format(emphasis(os.path.basename(dest))))
|
||||
items.append(Command(
|
||||
'Generating {} ...'.format(emphasis(os.path.basename(dest))),
|
||||
[env.wayland_scanner, q, src, dest],
|
||||
lambda: True, None, None, None))
|
||||
if items:
|
||||
parallel_run(items)
|
||||
|
||||
|
||||
class Arg:
|
||||
@@ -156,7 +150,8 @@ class Function:
|
||||
|
||||
|
||||
def generate_wrappers(glfw_header):
|
||||
src = open(glfw_header).read()
|
||||
with open(glfw_header) as f:
|
||||
src = f.read()
|
||||
functions = []
|
||||
first = None
|
||||
for m in re.finditer(r'^GLFWAPI\s+(.+[)]);\s*$', src, flags=re.MULTILINE):
|
||||
|
||||
144
glfw/glfw3.h
vendored
144
glfw/glfw3.h
vendored
@@ -1,9 +1,9 @@
|
||||
/*************************************************************************
|
||||
* GLFW 3.3 - www.glfw.org
|
||||
* GLFW 3.4 - www.glfw.org
|
||||
* A library for OpenGL, window and input
|
||||
*------------------------------------------------------------------------
|
||||
* Copyright (c) 2002-2006 Marcus Geelnard
|
||||
* Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
* Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -261,7 +261,7 @@ extern "C" {
|
||||
* backward-compatible.
|
||||
* @ingroup init
|
||||
*/
|
||||
#define GLFW_VERSION_MINOR 3
|
||||
#define GLFW_VERSION_MINOR 4
|
||||
/*! @brief The revision number of the GLFW library.
|
||||
*
|
||||
* This is incremented when a bug fix release is made that does not contain any
|
||||
@@ -271,24 +271,6 @@ extern "C" {
|
||||
#define GLFW_VERSION_REVISION 0
|
||||
/*! @} */
|
||||
|
||||
/*! @name Boolean values
|
||||
* @{ */
|
||||
/*! @brief One.
|
||||
*
|
||||
* One. Seriously. You don't _need_ to use this symbol in your code. It's
|
||||
* semantic sugar for the number 1. You can also use `1` or `true` or `_True`
|
||||
* or `GL_TRUE` or whatever you want.
|
||||
*/
|
||||
#define GLFW_TRUE true
|
||||
/*! @brief Zero.
|
||||
*
|
||||
* Zero. Seriously. You don't _need_ to use this symbol in your code. It's
|
||||
* semantic sugar for the number 0. You can also use `0` or `false` or
|
||||
* `_False` or `GL_FALSE` or whatever you want.
|
||||
*/
|
||||
#define GLFW_FALSE false
|
||||
/*! @} */
|
||||
|
||||
/*! @name Key and button actions
|
||||
* @{ */
|
||||
/*! @brief The key or mouse button was released.
|
||||
@@ -342,7 +324,7 @@ extern "C" {
|
||||
*
|
||||
* The naming of the key codes follow these rules:
|
||||
* - The US keyboard layout is used
|
||||
* - Names of printable alpha-numeric characters are used (e.g. "A", "R",
|
||||
* - Names of printable alphanumeric characters are used (e.g. "A", "R",
|
||||
* "3", etc.)
|
||||
* - For non-alphanumeric characters, Unicode:ish names are used (e.g.
|
||||
* "COMMA", "LEFT_SQUARE_BRACKET", etc.). Note that some names do not
|
||||
@@ -410,6 +392,7 @@ extern "C" {
|
||||
#define GLFW_KEY_WORLD_1 161 /* non-US #1 */
|
||||
#define GLFW_KEY_WORLD_2 162 /* non-US #2 */
|
||||
#define GLFW_KEY_PLUS 163
|
||||
#define GLFW_KEY_UNDERSCORE 164
|
||||
|
||||
/* Function keys */
|
||||
#define GLFW_KEY_ESCAPE 256
|
||||
@@ -922,62 +905,62 @@ extern "C" {
|
||||
#define GLFW_CLIENT_API 0x00022001
|
||||
/*! @brief Context client API major version hint and attribute.
|
||||
*
|
||||
* Context client API major version [hint](@ref GLFW_CLIENT_API_hint) and
|
||||
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
||||
* Context client API major version [hint](@ref GLFW_CONTEXT_VERSION_MAJOR_hint)
|
||||
* and [attribute](@ref GLFW_CONTEXT_VERSION_MAJOR_attrib).
|
||||
*/
|
||||
#define GLFW_CONTEXT_VERSION_MAJOR 0x00022002
|
||||
/*! @brief Context client API minor version hint and attribute.
|
||||
*
|
||||
* Context client API minor version [hint](@ref GLFW_CLIENT_API_hint) and
|
||||
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
||||
* Context client API minor version [hint](@ref GLFW_CONTEXT_VERSION_MINOR_hint)
|
||||
* and [attribute](@ref GLFW_CONTEXT_VERSION_MINOR_attrib).
|
||||
*/
|
||||
#define GLFW_CONTEXT_VERSION_MINOR 0x00022003
|
||||
/*! @brief Context client API revision number hint and attribute.
|
||||
*
|
||||
* Context client API revision number [hint](@ref GLFW_CLIENT_API_hint) and
|
||||
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
||||
* Context client API revision number
|
||||
* [attribute](@ref GLFW_CONTEXT_REVISION_attrib).
|
||||
*/
|
||||
#define GLFW_CONTEXT_REVISION 0x00022004
|
||||
/*! @brief Context robustness hint and attribute.
|
||||
*
|
||||
* Context client API revision number [hint](@ref GLFW_CLIENT_API_hint) and
|
||||
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
||||
* Context client API revision number [hint](@ref GLFW_CONTEXT_ROBUSTNESS_hint)
|
||||
* and [attribute](@ref GLFW_CONTEXT_ROBUSTNESS_attrib).
|
||||
*/
|
||||
#define GLFW_CONTEXT_ROBUSTNESS 0x00022005
|
||||
/*! @brief OpenGL forward-compatibility hint and attribute.
|
||||
*
|
||||
* OpenGL forward-compatibility [hint](@ref GLFW_CLIENT_API_hint) and
|
||||
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
||||
* OpenGL forward-compatibility [hint](@ref GLFW_OPENGL_FORWARD_COMPAT_hint)
|
||||
* and [attribute](@ref GLFW_OPENGL_FORWARD_COMPAT_attrib).
|
||||
*/
|
||||
#define GLFW_OPENGL_FORWARD_COMPAT 0x00022006
|
||||
/*! @brief OpenGL debug context hint and attribute.
|
||||
*
|
||||
* OpenGL debug context [hint](@ref GLFW_CLIENT_API_hint) and
|
||||
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
||||
* OpenGL debug context [hint](@ref GLFW_OPENGL_DEBUG_CONTEXT_hint) and
|
||||
* [attribute](@ref GLFW_OPENGL_DEBUG_CONTEXT_attrib).
|
||||
*/
|
||||
#define GLFW_OPENGL_DEBUG_CONTEXT 0x00022007
|
||||
/*! @brief OpenGL profile hint and attribute.
|
||||
*
|
||||
* OpenGL profile [hint](@ref GLFW_CLIENT_API_hint) and
|
||||
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
||||
* OpenGL profile [hint](@ref GLFW_OPENGL_PROFILE_hint) and
|
||||
* [attribute](@ref GLFW_OPENGL_PROFILE_attrib).
|
||||
*/
|
||||
#define GLFW_OPENGL_PROFILE 0x00022008
|
||||
/*! @brief Context flush-on-release hint and attribute.
|
||||
*
|
||||
* Context flush-on-release [hint](@ref GLFW_CLIENT_API_hint) and
|
||||
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
||||
* Context flush-on-release [hint](@ref GLFW_CONTEXT_RELEASE_BEHAVIOR_hint) and
|
||||
* [attribute](@ref GLFW_CONTEXT_RELEASE_BEHAVIOR_attrib).
|
||||
*/
|
||||
#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009
|
||||
/*! @brief Context error suppression hint and attribute.
|
||||
*
|
||||
* Context error suppression [hint](@ref GLFW_CLIENT_API_hint) and
|
||||
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
||||
* Context error suppression [hint](@ref GLFW_CONTEXT_NO_ERROR_hint) and
|
||||
* [attribute](@ref GLFW_CONTEXT_NO_ERROR_attrib).
|
||||
*/
|
||||
#define GLFW_CONTEXT_NO_ERROR 0x0002200A
|
||||
/*! @brief Context creation API hint and attribute.
|
||||
*
|
||||
* Context creation API [hint](@ref GLFW_CLIENT_API_hint) and
|
||||
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
||||
* Context creation API [hint](@ref GLFW_CONTEXT_CREATION_API_hint) and
|
||||
* [attribute](@ref GLFW_CONTEXT_CREATION_API_attrib).
|
||||
*/
|
||||
#define GLFW_CONTEXT_CREATION_API 0x0002200B
|
||||
/*! @brief Window content area scaling window
|
||||
@@ -1221,8 +1204,8 @@ typedef void (* GLFWwindowrefreshfun)(GLFWwindow*);
|
||||
* This is the function signature for window focus callback functions.
|
||||
*
|
||||
* @param[in] window The window that gained or lost input focus.
|
||||
* @param[in] focused `GLFW_TRUE` if the window was given input focus, or
|
||||
* `GLFW_FALSE` if it lost it.
|
||||
* @param[in] focused `true` if the window was given input focus, or
|
||||
* `false` if it lost it.
|
||||
*
|
||||
* @sa @ref window_focus
|
||||
* @sa @ref glfwSetWindowFocusCallback
|
||||
@@ -1238,7 +1221,7 @@ typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int);
|
||||
* This is the function signature for window occlusion callback functions.
|
||||
*
|
||||
* @param[in] window The window whose occlusion state changed.
|
||||
* @param[in] occluded `GLFW_TRUE` if the window was occluded, or `GLFW_FALSE`
|
||||
* @param[in] occluded `true` if the window was occluded, or `false`
|
||||
* if the window is no longer occluded.
|
||||
*
|
||||
* @sa @ref window_occlusion
|
||||
@@ -1257,8 +1240,8 @@ typedef void (* GLFWwindowocclusionfun)(GLFWwindow*, bool);
|
||||
* functions.
|
||||
*
|
||||
* @param[in] window The window that was iconified or restored.
|
||||
* @param[in] iconified `GLFW_TRUE` if the window was iconified, or
|
||||
* `GLFW_FALSE` if it was restored.
|
||||
* @param[in] iconified `true` if the window was iconified, or
|
||||
* `false` if it was restored.
|
||||
*
|
||||
* @sa @ref window_iconify
|
||||
* @sa @ref glfwSetWindowIconifyCallback
|
||||
@@ -1275,8 +1258,8 @@ typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int);
|
||||
* functions.
|
||||
*
|
||||
* @param[in] window The window that was maximized or restored.
|
||||
* @param[in] iconified `GLFW_TRUE` if the window was maximized, or
|
||||
* `GLFW_FALSE` if it was restored.
|
||||
* @param[in] iconified `true` if the window was maximized, or
|
||||
* `false` if it was restored.
|
||||
*
|
||||
* @sa @ref window_maximize
|
||||
* @sa glfwSetWindowMaximizeCallback
|
||||
@@ -1368,8 +1351,8 @@ typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double);
|
||||
* This is the function signature for cursor enter/leave callback functions.
|
||||
*
|
||||
* @param[in] window The window that received the event.
|
||||
* @param[in] entered `GLFW_TRUE` if the cursor entered the window's client
|
||||
* area, or `GLFW_FALSE` if it left it.
|
||||
* @param[in] entered `true` if the cursor entered the window's client
|
||||
* area, or `false` if it left it.
|
||||
*
|
||||
* @sa @ref cursor_enter
|
||||
* @sa @ref glfwSetCursorEnterCallback
|
||||
@@ -1621,9 +1604,9 @@ typedef struct GLFWgamepadstate
|
||||
* succeeds, you should call @ref glfwTerminate before the application exits.
|
||||
*
|
||||
* Additional calls to this function after successful initialization but before
|
||||
* termination will return `GLFW_TRUE` immediately.
|
||||
* termination will return `true` immediately.
|
||||
*
|
||||
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
|
||||
* @return `true` if successful, or `false` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_PLATFORM_ERROR.
|
||||
@@ -1645,7 +1628,6 @@ typedef struct GLFWgamepadstate
|
||||
GLFWAPI int glfwInit(void);
|
||||
GLFWAPI void glfwRunMainLoop(GLFWtickcallback callback, void *callback_data);
|
||||
GLFWAPI void glfwStopMainLoop(void);
|
||||
GLFWAPI void glfwRequestTickCallback(void);
|
||||
GLFWAPI unsigned long long glfwAddTimer(double interval, bool repeats, GLFWuserdatafun callback, void * callback_data, GLFWuserdatafun free_callback);
|
||||
GLFWAPI void glfwUpdateTimer(unsigned long long timer_id, double interval, bool enabled);
|
||||
GLFWAPI void glfwRemoveTimer(unsigned long long);
|
||||
@@ -2193,7 +2175,7 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @wayland Gamma handling is a priviledged protocol, this function
|
||||
* @remark @wayland Gamma handling is a privileged protocol, this function
|
||||
* will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@@ -2217,7 +2199,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @wayland Gamma handling is a priviledged protocol, this function
|
||||
* @remark @wayland Gamma handling is a privileged protocol, this function
|
||||
* will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR while
|
||||
* returning `NULL`.
|
||||
*
|
||||
@@ -2261,7 +2243,7 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);
|
||||
*
|
||||
* @remark @win32 The gamma ramp size must be 256.
|
||||
*
|
||||
* @remark @wayland Gamma handling is a priviledged protocol, this function
|
||||
* @remark @wayland Gamma handling is a privileged protocol, this function
|
||||
* will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @pointer_lifetime The specified gamma ramp is copied before this function
|
||||
@@ -2471,7 +2453,7 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
|
||||
* @remark @macos On OS X 10.10 and later the window frame will not be rendered
|
||||
* at full resolution on Retina displays unless the
|
||||
* [GLFW_COCOA_RETINA_FRAMEBUFFER](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint)
|
||||
* hint is `GLFW_TRUE` and the `NSHighResolutionCapable` key is enabled in the
|
||||
* hint is `true` and the `NSHighResolutionCapable` key is enabled in the
|
||||
* application bundle's `Info.plist`. For more information, see
|
||||
* [High Resolution Guidelines for OS X](https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html)
|
||||
* in the Mac Developer Library. The GLFW test and example programs use
|
||||
@@ -2480,7 +2462,7 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
|
||||
*
|
||||
* @remark @macos When activating frame autosaving with
|
||||
* [GLFW_COCOA_FRAME_NAME](@ref GLFW_COCOA_FRAME_NAME_hint), the specified
|
||||
* window size and position may be overriden by previously saved values.
|
||||
* window size and position may be overridden by previously saved values.
|
||||
*
|
||||
* @remark @x11 Some window managers will not respect the placement of
|
||||
* initially hidden windows.
|
||||
@@ -3272,7 +3254,7 @@ GLFWAPI void glfwRequestWindowAttention(GLFWwindow* window);
|
||||
* supported. Currently (macOS, Windows, X11 and Wayland).
|
||||
*
|
||||
* @param[in] window The window with which the bell is associated.
|
||||
* @return GLFW_TRUE if the bell succeeded otherwise GLFW_FALSE
|
||||
* @return true if the bell succeeded otherwise false
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
@@ -3422,7 +3404,7 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);
|
||||
*
|
||||
* @param[in] window The window to set the attribute for.
|
||||
* @param[in] attrib A supported window attribute.
|
||||
* @param[in] value `GLFW_TRUE` or `GLFW_FALSE`.
|
||||
* @param[in] value `true` or `false`.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
|
||||
@@ -3804,23 +3786,23 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
|
||||
* and unlimited cursor movement. This is useful for implementing for
|
||||
* example 3D camera controls.
|
||||
*
|
||||
* If the mode is `GLFW_STICKY_KEYS`, the value must be either `GLFW_TRUE` to
|
||||
* enable sticky keys, or `GLFW_FALSE` to disable it. If sticky keys are
|
||||
* If the mode is `GLFW_STICKY_KEYS`, the value must be either `true` to
|
||||
* enable sticky keys, or `false` to disable it. If sticky keys are
|
||||
* enabled, a key press will ensure that @ref glfwGetKey returns `GLFW_PRESS`
|
||||
* the next time it is called even if the key had been released before the
|
||||
* call. This is useful when you are only interested in whether keys have been
|
||||
* pressed but not when or in which order.
|
||||
*
|
||||
* If the mode is `GLFW_STICKY_MOUSE_BUTTONS`, the value must be either
|
||||
* `GLFW_TRUE` to enable sticky mouse buttons, or `GLFW_FALSE` to disable it.
|
||||
* `true` to enable sticky mouse buttons, or `false` to disable it.
|
||||
* If sticky mouse buttons are enabled, a mouse button press will ensure that
|
||||
* @ref glfwGetMouseButton returns `GLFW_PRESS` the next time it is called even
|
||||
* if the mouse button had been released before the call. This is useful when
|
||||
* you are only interested in whether mouse buttons have been pressed but not
|
||||
* when or in which order.
|
||||
*
|
||||
* If the mode is `GLFW_LOCK_KEY_MODS`, the value must be either `GLFW_TRUE` to
|
||||
* enable lock key modifier bits, or `GLFW_FALSE` to disable them. If enabled,
|
||||
* If the mode is `GLFW_LOCK_KEY_MODS`, the value must be either `true` to
|
||||
* enable lock key modifier bits, or `false` to disable them. If enabled,
|
||||
* callbacks that receive modifier bits will also have the @ref
|
||||
* GLFW_MOD_CAPS_LOCK bit set when the event was generated with Caps Lock on,
|
||||
* and the @ref GLFW_MOD_NUM_LOCK bit when Num Lock was on.
|
||||
@@ -4365,7 +4347,7 @@ GLFWAPI GLFWliveresizefun glfwSetLiveResizeCallback(GLFWwindow* window, GLFWlive
|
||||
* work.
|
||||
*
|
||||
* @param[in] jid The [joystick](@ref joysticks) to query.
|
||||
* @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise.
|
||||
* @return `true` if the joystick is present, or `false` otherwise.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
|
||||
@@ -4542,7 +4524,7 @@ GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count);
|
||||
*/
|
||||
GLFWAPI const char* glfwGetJoystickName(int jid);
|
||||
|
||||
/*! @brief Returns the SDL comaptible GUID of the specified joystick.
|
||||
/*! @brief Returns the SDL compatible GUID of the specified joystick.
|
||||
*
|
||||
* This function returns the SDL compatible GUID, as a UTF-8 encoded
|
||||
* hexadecimal string, of the specified joystick. The returned string is
|
||||
@@ -4639,13 +4621,13 @@ GLFWAPI void* glfwGetJoystickUserPointer(int jid);
|
||||
* a gamepad mapping.
|
||||
*
|
||||
* If the specified joystick is present but does not have a gamepad mapping
|
||||
* this function will return `GLFW_FALSE` but will not generate an error. Call
|
||||
* this function will return `false` but will not generate an error. Call
|
||||
* @ref glfwJoystickPresent to check if a joystick is present regardless of
|
||||
* whether it has a mapping.
|
||||
*
|
||||
* @param[in] jid The [joystick](@ref joysticks) to query.
|
||||
* @return `GLFW_TRUE` if a joystick is both present and has a gamepad mapping,
|
||||
* or `GLFW_FALSE` otherwise.
|
||||
* @return `true` if a joystick is both present and has a gamepad mapping,
|
||||
* or `false` otherwise.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_INVALID_ENUM.
|
||||
@@ -4706,7 +4688,7 @@ GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun);
|
||||
* default.
|
||||
*
|
||||
* @param[in] string The string containing the gamepad mappings.
|
||||
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
|
||||
* @return `true` if successful, or `false` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
@@ -4756,11 +4738,11 @@ GLFWAPI const char* glfwGetGamepadName(int jid);
|
||||
|
||||
/*! @brief Retrieves the state of the specified joystick remapped as a gamepad.
|
||||
*
|
||||
* This function retrives the state of the specified joystick remapped to
|
||||
* This function retrieves the state of the specified joystick remapped to
|
||||
* an Xbox-like gamepad.
|
||||
*
|
||||
* If the specified joystick is not present or does not have a gamepad mapping
|
||||
* this function will return `GLFW_FALSE` but will not generate an error. Call
|
||||
* this function will return `false` but will not generate an error. Call
|
||||
* @ref glfwJoystickPresent to check whether it is present regardless of
|
||||
* whether it has a mapping.
|
||||
*
|
||||
@@ -4773,7 +4755,7 @@ GLFWAPI const char* glfwGetGamepadName(int jid);
|
||||
*
|
||||
* @param[in] jid The [joystick](@ref joysticks) to query.
|
||||
* @param[out] state The gamepad input state of the joystick.
|
||||
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if no joystick is
|
||||
* @return `true` if successful, or `false` if no joystick is
|
||||
* connected, it has no gamepad mapping or an [error](@ref error_handling)
|
||||
* occurred.
|
||||
*
|
||||
@@ -5106,7 +5088,7 @@ GLFWAPI void glfwSwapInterval(int interval);
|
||||
* and `vkEnumerateDeviceExtensionProperties` instead.
|
||||
*
|
||||
* @param[in] extension The ASCII encoded name of the extension.
|
||||
* @return `GLFW_TRUE` if the extension is available, or `GLFW_FALSE`
|
||||
* @return `true` if the extension is available, or `false`
|
||||
* otherwise.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
@@ -5179,7 +5161,7 @@ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname);
|
||||
* and @ref glfwGetPhysicalDevicePresentationSupport to check whether a queue
|
||||
* family of a physical device supports image presentation.
|
||||
*
|
||||
* @return `GLFW_TRUE` if Vulkan is minimally available, or `GLFW_FALSE`
|
||||
* @return `true` if Vulkan is minimally available, or `false`
|
||||
* otherwise.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||
@@ -5291,7 +5273,7 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* p
|
||||
*
|
||||
* If Vulkan or the required window surface creation instance extensions are
|
||||
* not available on the machine, or if the specified instance was not created
|
||||
* with the required extensions, this function returns `GLFW_FALSE` and
|
||||
* with the required extensions, this function returns `false` and
|
||||
* generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported
|
||||
* to check whether Vulkan is at least minimally available and @ref
|
||||
* glfwGetRequiredInstanceExtensions to check what instance extensions are
|
||||
@@ -5300,13 +5282,13 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* p
|
||||
* @param[in] instance The instance that the physical device belongs to.
|
||||
* @param[in] device The physical device that the queue family belongs to.
|
||||
* @param[in] queuefamily The index of the queue family to query.
|
||||
* @return `GLFW_TRUE` if the queue family supports presentation, or
|
||||
* `GLFW_FALSE` otherwise.
|
||||
* @return `true` if the queue family supports presentation, or
|
||||
* `false` otherwise.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @macos This function currently always returns `GLFW_TRUE`, as the
|
||||
* @remark @macos This function currently always returns `true`, as the
|
||||
* `VK_MVK_macos_surface` extension does not provide
|
||||
* a `vkGetPhysicalDevice*PresentationSupport` type function.
|
||||
*
|
||||
|
||||
151
glfw/glx_context.c
vendored
151
glfw/glx_context.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 GLX - www.glfw.org
|
||||
// GLFW 3.4 GLX - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -47,7 +49,7 @@ static int getGLXFBConfigAttrib(GLXFBConfig fbconfig, int attrib)
|
||||
|
||||
// Return the GLXFBConfig most closely matching the specified hints
|
||||
//
|
||||
static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
|
||||
static bool chooseGLXFBConfig(const _GLFWfbconfig* desired,
|
||||
GLXFBConfig* result)
|
||||
{
|
||||
GLXFBConfig* nativeConfigs;
|
||||
@@ -55,20 +57,20 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
|
||||
const _GLFWfbconfig* closest;
|
||||
int i, nativeCount, usableCount;
|
||||
const char* vendor;
|
||||
GLFWbool trustWindowBit = GLFW_TRUE;
|
||||
bool trustWindowBit = true;
|
||||
|
||||
// HACK: This is a (hopefully temporary) workaround for Chromium
|
||||
// (VirtualBox GL) not setting the window bit on any GLXFBConfigs
|
||||
vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR);
|
||||
if (vendor && strcmp(vendor, "Chromium") == 0)
|
||||
trustWindowBit = GLFW_FALSE;
|
||||
trustWindowBit = false;
|
||||
|
||||
nativeConfigs =
|
||||
glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, &nativeCount);
|
||||
if (!nativeConfigs || !nativeCount)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
|
||||
@@ -116,9 +118,9 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
|
||||
u->auxBuffers = getGLXFBConfigAttrib(n, GLX_AUX_BUFFERS);
|
||||
|
||||
if (getGLXFBConfigAttrib(n, GLX_STEREO))
|
||||
u->stereo = GLFW_TRUE;
|
||||
u->stereo = true;
|
||||
if (getGLXFBConfigAttrib(n, GLX_DOUBLEBUFFER))
|
||||
u->doublebuffer = GLFW_TRUE;
|
||||
u->doublebuffer = true;
|
||||
|
||||
if (_glfw.glx.ARB_multisample)
|
||||
u->samples = getGLXFBConfigAttrib(n, GLX_SAMPLES);
|
||||
@@ -142,7 +144,7 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
|
||||
|
||||
// Create the OpenGL context using legacy API
|
||||
//
|
||||
static GLXContext createLegacyContextGLX(_GLFWwindow* window,
|
||||
static GLXContext createLegacyContextGLX(_GLFWwindow* window UNUSED,
|
||||
GLXFBConfig fbconfig,
|
||||
GLXContext share)
|
||||
{
|
||||
@@ -210,10 +212,10 @@ static int extensionSupportedGLX(const char* extension)
|
||||
if (extensions)
|
||||
{
|
||||
if (_glfwStringInExtensionString(extension, extensions))
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
static GLFWglproc getProcAddressGLX(const char* procname)
|
||||
@@ -222,12 +224,13 @@ static GLFWglproc getProcAddressGLX(const char* procname)
|
||||
return _glfw.glx.GetProcAddress((const GLubyte*) procname);
|
||||
else if (_glfw.glx.GetProcAddressARB)
|
||||
return _glfw.glx.GetProcAddressARB((const GLubyte*) procname);
|
||||
else
|
||||
return _glfw_dlsym(_glfw.glx.handle, procname);
|
||||
else {
|
||||
GLFWglproc ans = NULL;
|
||||
glfw_dlsym(ans, _glfw.glx.handle, procname);
|
||||
return ans;
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy the OpenGL context
|
||||
//
|
||||
static void destroyContextGLX(_GLFWwindow* window)
|
||||
{
|
||||
if (window->context.glx.window)
|
||||
@@ -250,7 +253,7 @@ static void destroyContextGLX(_GLFWwindow* window)
|
||||
|
||||
// Initialize GLX
|
||||
//
|
||||
GLFWbool _glfwInitGLX(void)
|
||||
bool _glfwInitGLX(void)
|
||||
{
|
||||
int i;
|
||||
const char* sonames[] =
|
||||
@@ -267,7 +270,7 @@ GLFWbool _glfwInitGLX(void)
|
||||
};
|
||||
|
||||
if (_glfw.glx.handle)
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
|
||||
for (i = 0; sonames[i]; i++)
|
||||
{
|
||||
@@ -279,39 +282,24 @@ GLFWbool _glfwInitGLX(void)
|
||||
if (!_glfw.glx.handle)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: Failed to load GLX");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfw.glx.GetFBConfigs =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXGetFBConfigs");
|
||||
_glfw.glx.GetFBConfigAttrib =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXGetFBConfigAttrib");
|
||||
_glfw.glx.GetClientString =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXGetClientString");
|
||||
_glfw.glx.QueryExtension =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXQueryExtension");
|
||||
_glfw.glx.QueryVersion =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXQueryVersion");
|
||||
_glfw.glx.DestroyContext =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXDestroyContext");
|
||||
_glfw.glx.MakeCurrent =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXMakeCurrent");
|
||||
_glfw.glx.SwapBuffers =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXSwapBuffers");
|
||||
_glfw.glx.QueryExtensionsString =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXQueryExtensionsString");
|
||||
_glfw.glx.CreateNewContext =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXCreateNewContext");
|
||||
_glfw.glx.CreateWindow =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXCreateWindow");
|
||||
_glfw.glx.DestroyWindow =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXDestroyWindow");
|
||||
_glfw.glx.GetProcAddress =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXGetProcAddress");
|
||||
_glfw.glx.GetProcAddressARB =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXGetProcAddressARB");
|
||||
_glfw.glx.GetVisualFromFBConfig =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXGetVisualFromFBConfig");
|
||||
glfw_dlsym(_glfw.glx.GetFBConfigs, _glfw.glx.handle, "glXGetFBConfigs");
|
||||
glfw_dlsym(_glfw.glx.GetFBConfigAttrib, _glfw.glx.handle, "glXGetFBConfigAttrib");
|
||||
glfw_dlsym(_glfw.glx.GetClientString, _glfw.glx.handle, "glXGetClientString");
|
||||
glfw_dlsym(_glfw.glx.QueryExtension, _glfw.glx.handle, "glXQueryExtension");
|
||||
glfw_dlsym(_glfw.glx.QueryVersion, _glfw.glx.handle, "glXQueryVersion");
|
||||
glfw_dlsym(_glfw.glx.DestroyContext, _glfw.glx.handle, "glXDestroyContext");
|
||||
glfw_dlsym(_glfw.glx.MakeCurrent, _glfw.glx.handle, "glXMakeCurrent");
|
||||
glfw_dlsym(_glfw.glx.SwapBuffers, _glfw.glx.handle, "glXSwapBuffers");
|
||||
glfw_dlsym(_glfw.glx.QueryExtensionsString, _glfw.glx.handle, "glXQueryExtensionsString");
|
||||
glfw_dlsym(_glfw.glx.CreateNewContext, _glfw.glx.handle, "glXCreateNewContext");
|
||||
glfw_dlsym(_glfw.glx.CreateWindow, _glfw.glx.handle, "glXCreateWindow");
|
||||
glfw_dlsym(_glfw.glx.DestroyWindow, _glfw.glx.handle, "glXDestroyWindow");
|
||||
glfw_dlsym(_glfw.glx.GetProcAddress, _glfw.glx.handle, "glXGetProcAddress");
|
||||
glfw_dlsym(_glfw.glx.GetProcAddressARB, _glfw.glx.handle, "glXGetProcAddressARB");
|
||||
glfw_dlsym(_glfw.glx.GetVisualFromFBConfig, _glfw.glx.handle, "glXGetVisualFromFBConfig");
|
||||
|
||||
if (!_glfw.glx.GetFBConfigs ||
|
||||
!_glfw.glx.GetFBConfigAttrib ||
|
||||
@@ -331,7 +319,7 @@ GLFWbool _glfwInitGLX(void)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"GLX: Failed to load required entry points");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!glXQueryExtension(_glfw.x11.display,
|
||||
@@ -339,21 +327,21 @@ GLFWbool _glfwInitGLX(void)
|
||||
&_glfw.glx.eventBase))
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: GLX extension not found");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!glXQueryVersion(_glfw.x11.display, &_glfw.glx.major, &_glfw.glx.minor))
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"GLX: Failed to query GLX version");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_glfw.glx.major == 1 && _glfw.glx.minor < 3)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"GLX: GLX version 1.3 is required");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (extensionSupportedGLX("GLX_EXT_swap_control"))
|
||||
@@ -362,7 +350,7 @@ GLFWbool _glfwInitGLX(void)
|
||||
getProcAddressGLX("glXSwapIntervalEXT");
|
||||
|
||||
if (_glfw.glx.SwapIntervalEXT)
|
||||
_glfw.glx.EXT_swap_control = GLFW_TRUE;
|
||||
_glfw.glx.EXT_swap_control = true;
|
||||
}
|
||||
|
||||
if (extensionSupportedGLX("GLX_SGI_swap_control"))
|
||||
@@ -371,7 +359,7 @@ GLFWbool _glfwInitGLX(void)
|
||||
getProcAddressGLX("glXSwapIntervalSGI");
|
||||
|
||||
if (_glfw.glx.SwapIntervalSGI)
|
||||
_glfw.glx.SGI_swap_control = GLFW_TRUE;
|
||||
_glfw.glx.SGI_swap_control = true;
|
||||
}
|
||||
|
||||
if (extensionSupportedGLX("GLX_MESA_swap_control"))
|
||||
@@ -380,17 +368,17 @@ GLFWbool _glfwInitGLX(void)
|
||||
getProcAddressGLX("glXSwapIntervalMESA");
|
||||
|
||||
if (_glfw.glx.SwapIntervalMESA)
|
||||
_glfw.glx.MESA_swap_control = GLFW_TRUE;
|
||||
_glfw.glx.MESA_swap_control = true;
|
||||
}
|
||||
|
||||
if (extensionSupportedGLX("GLX_ARB_multisample"))
|
||||
_glfw.glx.ARB_multisample = GLFW_TRUE;
|
||||
_glfw.glx.ARB_multisample = true;
|
||||
|
||||
if (extensionSupportedGLX("GLX_ARB_framebuffer_sRGB"))
|
||||
_glfw.glx.ARB_framebuffer_sRGB = GLFW_TRUE;
|
||||
_glfw.glx.ARB_framebuffer_sRGB = true;
|
||||
|
||||
if (extensionSupportedGLX("GLX_EXT_framebuffer_sRGB"))
|
||||
_glfw.glx.EXT_framebuffer_sRGB = GLFW_TRUE;
|
||||
_glfw.glx.EXT_framebuffer_sRGB = true;
|
||||
|
||||
if (extensionSupportedGLX("GLX_ARB_create_context"))
|
||||
{
|
||||
@@ -398,25 +386,25 @@ GLFWbool _glfwInitGLX(void)
|
||||
getProcAddressGLX("glXCreateContextAttribsARB");
|
||||
|
||||
if (_glfw.glx.CreateContextAttribsARB)
|
||||
_glfw.glx.ARB_create_context = GLFW_TRUE;
|
||||
_glfw.glx.ARB_create_context = true;
|
||||
}
|
||||
|
||||
if (extensionSupportedGLX("GLX_ARB_create_context_robustness"))
|
||||
_glfw.glx.ARB_create_context_robustness = GLFW_TRUE;
|
||||
_glfw.glx.ARB_create_context_robustness = true;
|
||||
|
||||
if (extensionSupportedGLX("GLX_ARB_create_context_profile"))
|
||||
_glfw.glx.ARB_create_context_profile = GLFW_TRUE;
|
||||
_glfw.glx.ARB_create_context_profile = true;
|
||||
|
||||
if (extensionSupportedGLX("GLX_EXT_create_context_es2_profile"))
|
||||
_glfw.glx.EXT_create_context_es2_profile = GLFW_TRUE;
|
||||
_glfw.glx.EXT_create_context_es2_profile = true;
|
||||
|
||||
if (extensionSupportedGLX("GLX_ARB_create_context_no_error"))
|
||||
_glfw.glx.ARB_create_context_no_error = GLFW_TRUE;
|
||||
_glfw.glx.ARB_create_context_no_error = true;
|
||||
|
||||
if (extensionSupportedGLX("GLX_ARB_context_flush_control"))
|
||||
_glfw.glx.ARB_context_flush_control = GLFW_TRUE;
|
||||
_glfw.glx.ARB_context_flush_control = true;
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Terminate GLX
|
||||
@@ -435,14 +423,14 @@ void _glfwTerminateGLX(void)
|
||||
|
||||
#define setAttrib(a, v) \
|
||||
{ \
|
||||
assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
||||
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
||||
attribs[index++] = a; \
|
||||
attribs[index++] = v; \
|
||||
}
|
||||
|
||||
// Create the OpenGL or OpenGL ES context
|
||||
//
|
||||
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
bool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
@@ -457,7 +445,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||
"GLX: Failed to find a suitable GLXFBConfig");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||
@@ -468,7 +456,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"GLX: OpenGL ES requested but GLX_EXT_create_context_es2_profile is unavailable");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,7 +466,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"GLX: Forward compatibility requested but GLX_ARB_create_context_profile is unavailable");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,7 +477,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"GLX: An OpenGL profile requested but GLX_ARB_create_context_profile is unavailable");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -554,7 +542,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
if (ctxconfig->noerror)
|
||||
{
|
||||
if (_glfw.glx.ARB_create_context_no_error)
|
||||
setAttrib(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
|
||||
setAttrib(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, true);
|
||||
}
|
||||
|
||||
// NOTE: Only request an explicitly versioned context when necessary, as
|
||||
@@ -590,7 +578,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
if (_glfw.x11.errorCode == _glfw.glx.errorBase + GLXBadProfileARB &&
|
||||
ctxconfig->client == GLFW_OPENGL_API &&
|
||||
ctxconfig->profile == GLFW_OPENGL_ANY_PROFILE &&
|
||||
ctxconfig->forward == GLFW_FALSE)
|
||||
ctxconfig->forward == false)
|
||||
{
|
||||
window->context.glx.handle =
|
||||
createLegacyContextGLX(window, native, share);
|
||||
@@ -608,7 +596,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
if (!window->context.glx.handle)
|
||||
{
|
||||
_glfwInputErrorX11(GLFW_VERSION_UNAVAILABLE, "GLX: Failed to create context");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
window->context.glx.window =
|
||||
@@ -616,7 +604,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
if (!window->context.glx.window)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to create window");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
window->context.makeCurrent = makeContextCurrentGLX;
|
||||
@@ -626,15 +614,15 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
window->context.getProcAddress = getProcAddressGLX;
|
||||
window->context.destroy = destroyContextGLX;
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef setAttrib
|
||||
|
||||
// Returns the Visual and depth of the chosen GLXFBConfig
|
||||
//
|
||||
GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
bool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig UNUSED,
|
||||
const _GLFWctxconfig* ctxconfig UNUSED,
|
||||
const _GLFWfbconfig* fbconfig,
|
||||
Visual** visual, int* depth)
|
||||
{
|
||||
@@ -645,7 +633,7 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
|
||||
{
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||
"GLX: Failed to find a suitable GLXFBConfig");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
result = glXGetVisualFromFBConfig(_glfw.x11.display, native);
|
||||
@@ -653,14 +641,14 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"GLX: Failed to retrieve Visual for GLXFBConfig");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
*visual = result->visual;
|
||||
*depth = result->depth;
|
||||
|
||||
XFree(result);
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -695,4 +683,3 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
|
||||
|
||||
return window->context.glx.window;
|
||||
}
|
||||
|
||||
|
||||
39
glfw/glx_context.h
vendored
39
glfw/glx_context.h
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 GLX - www.glfw.org
|
||||
// GLFW 3.4 GLX - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -107,8 +107,8 @@ typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display*,GLXFBConfig,GLX
|
||||
#define glXCreateWindow _glfw.glx.CreateWindow
|
||||
#define glXDestroyWindow _glfw.glx.DestroyWindow
|
||||
|
||||
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX glx
|
||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx
|
||||
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX glx;
|
||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx;
|
||||
|
||||
|
||||
// GLX-specific per-context data
|
||||
@@ -153,29 +153,28 @@ typedef struct _GLFWlibraryGLX
|
||||
PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT;
|
||||
PFNGLXSWAPINTERVALMESAPROC SwapIntervalMESA;
|
||||
PFNGLXCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
|
||||
GLFWbool SGI_swap_control;
|
||||
GLFWbool EXT_swap_control;
|
||||
GLFWbool MESA_swap_control;
|
||||
GLFWbool ARB_multisample;
|
||||
GLFWbool ARB_framebuffer_sRGB;
|
||||
GLFWbool EXT_framebuffer_sRGB;
|
||||
GLFWbool ARB_create_context;
|
||||
GLFWbool ARB_create_context_profile;
|
||||
GLFWbool ARB_create_context_robustness;
|
||||
GLFWbool EXT_create_context_es2_profile;
|
||||
GLFWbool ARB_create_context_no_error;
|
||||
GLFWbool ARB_context_flush_control;
|
||||
bool SGI_swap_control;
|
||||
bool EXT_swap_control;
|
||||
bool MESA_swap_control;
|
||||
bool ARB_multisample;
|
||||
bool ARB_framebuffer_sRGB;
|
||||
bool EXT_framebuffer_sRGB;
|
||||
bool ARB_create_context;
|
||||
bool ARB_create_context_profile;
|
||||
bool ARB_create_context_robustness;
|
||||
bool EXT_create_context_es2_profile;
|
||||
bool ARB_create_context_no_error;
|
||||
bool ARB_context_flush_control;
|
||||
|
||||
} _GLFWlibraryGLX;
|
||||
|
||||
GLFWbool _glfwInitGLX(void);
|
||||
bool _glfwInitGLX(void);
|
||||
void _glfwTerminateGLX(void);
|
||||
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
bool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
void _glfwDestroyContextGLX(_GLFWwindow* window);
|
||||
GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
|
||||
bool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig,
|
||||
Visual** visual, int* depth);
|
||||
|
||||
|
||||
78
glfw/ibus_glfw.c
vendored
78
glfw/ibus_glfw.c
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 XKB - www.glfw.org
|
||||
// GLFW 3.4 XKB - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2018 Kovid Goyal <kovid@kovidgoyal.net>
|
||||
//
|
||||
@@ -50,14 +50,14 @@ enum Capabilities {
|
||||
};
|
||||
|
||||
|
||||
static inline GLFWbool
|
||||
static inline bool
|
||||
test_env_var(const char *name, const char *val) {
|
||||
const char *q = getenv(name);
|
||||
return (q && strcmp(q, val) == 0) ? GLFW_TRUE : GLFW_FALSE;
|
||||
return (q && strcmp(q, val) == 0) ? true : false;
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
MIN(size_t a, size_t b) {
|
||||
GLFW_MIN(size_t a, size_t b) {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ send_text(const char *text, int state) {
|
||||
// Connection handling {{{
|
||||
|
||||
static DBusHandlerResult
|
||||
message_handler(DBusConnection *conn, DBusMessage *msg, void *user_data) {
|
||||
message_handler(DBusConnection *conn UNUSED, DBusMessage *msg, void *user_data) {
|
||||
// To monitor signals from IBUS, use
|
||||
// dbus-monitor --address `ibus address` "type='signal',interface='org.freedesktop.IBus.InputContext'"
|
||||
_GLFWIBUSData *ibus = (_GLFWIBUSData*)user_data;
|
||||
@@ -151,7 +151,7 @@ get_ibus_address_file_name(void) {
|
||||
addr = getenv("IBUS_ADDRESS");
|
||||
int offset = 0;
|
||||
if (addr && addr[0]) {
|
||||
memcpy(ans, addr, MIN(strlen(addr), sizeof(ans)));
|
||||
memcpy(ans, addr, GLFW_MIN(strlen(addr), sizeof(ans)));
|
||||
return ans;
|
||||
}
|
||||
|
||||
@@ -193,39 +193,39 @@ get_ibus_address_file_name(void) {
|
||||
}
|
||||
|
||||
|
||||
static inline GLFWbool
|
||||
static inline bool
|
||||
read_ibus_address(_GLFWIBUSData *ibus) {
|
||||
static char buf[1024];
|
||||
struct stat s;
|
||||
FILE *addr_file = fopen(ibus->address_file_name, "r");
|
||||
if (!addr_file) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to open IBUS address file: %s with error: %s", ibus->address_file_name, strerror(errno));
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
int stat_result = fstat(fileno(addr_file), &s);
|
||||
GLFWbool found = GLFW_FALSE;
|
||||
bool found = false;
|
||||
while (fgets(buf, sizeof(buf), addr_file)) {
|
||||
if (strncmp(buf, "IBUS_ADDRESS=", sizeof("IBUS_ADDRESS=")-1) == 0) {
|
||||
size_t sz = strlen(buf);
|
||||
if (buf[sz-1] == '\n') buf[sz-1] = 0;
|
||||
if (buf[sz-2] == '\r') buf[sz-2] = 0;
|
||||
found = GLFW_TRUE;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(addr_file); addr_file = NULL;
|
||||
if (stat_result != 0) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to stat IBUS address file: %s with error: %s", ibus->address_file_name, strerror(errno));
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
ibus->address_file_mtime = s.st_mtime;
|
||||
if (found) {
|
||||
free((void*)ibus->address);
|
||||
ibus->address = _glfw_strdup(buf + sizeof("IBUS_ADDRESS=") - 1);
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Could not find IBUS_ADDRESS in %s", ibus->address_file_name);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -245,35 +245,35 @@ input_context_created(DBusMessage *msg, const char* errmsg, void *data) {
|
||||
dbus_connection_try_register_object_path(ibus->conn, ibus->input_ctx_path, &ibus_vtable, ibus, NULL);
|
||||
enum Capabilities caps = IBUS_CAP_FOCUS | IBUS_CAP_PREEDIT_TEXT;
|
||||
if (!glfw_dbus_call_method_no_reply(ibus->conn, IBUS_SERVICE, ibus->input_ctx_path, IBUS_INPUT_INTERFACE, "SetCapabilities", DBUS_TYPE_UINT32, &caps, DBUS_TYPE_INVALID)) return;
|
||||
ibus->ok = GLFW_TRUE;
|
||||
glfw_ibus_set_focused(ibus, GLFW_FALSE);
|
||||
ibus->ok = true;
|
||||
glfw_ibus_set_focused(ibus, false);
|
||||
glfw_ibus_set_cursor_geometry(ibus, 0, 0, 0, 0);
|
||||
debug("Connected to IBUS daemon for IME input management\n");
|
||||
}
|
||||
|
||||
GLFWbool
|
||||
bool
|
||||
setup_connection(_GLFWIBUSData *ibus) {
|
||||
const char *client_name = "GLFW_Application";
|
||||
const char *address_file_name = get_ibus_address_file_name();
|
||||
ibus->ok = GLFW_FALSE;
|
||||
if (!address_file_name) return GLFW_FALSE;
|
||||
ibus->ok = false;
|
||||
if (!address_file_name) return false;
|
||||
free((void*)ibus->address_file_name);
|
||||
ibus->address_file_name = _glfw_strdup(address_file_name);
|
||||
if (!read_ibus_address(ibus)) return GLFW_FALSE;
|
||||
if (!read_ibus_address(ibus)) return false;
|
||||
if (ibus->conn) {
|
||||
glfw_dbus_close_connection(ibus->conn);
|
||||
ibus->conn = NULL;
|
||||
}
|
||||
debug("Connecting to IBUS daemon @ %s for IME input management\n", ibus->address);
|
||||
ibus->conn = glfw_dbus_connect_to(ibus->address, "Failed to connect to the IBUS daemon, with error", "ibus", GLFW_FALSE);
|
||||
if (!ibus->conn) return GLFW_FALSE;
|
||||
ibus->conn = glfw_dbus_connect_to(ibus->address, "Failed to connect to the IBUS daemon, with error", "ibus", false);
|
||||
if (!ibus->conn) return false;
|
||||
free((void*)ibus->input_ctx_path); ibus->input_ctx_path = NULL;
|
||||
if (!glfw_dbus_call_method_with_reply(
|
||||
ibus->conn, IBUS_SERVICE, IBUS_PATH, IBUS_INTERFACE, "CreateInputContext", DBUS_TIMEOUT_USE_DEFAULT, input_context_created, ibus,
|
||||
DBUS_TYPE_STRING, &client_name, DBUS_TYPE_INVALID)) {
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -281,7 +281,7 @@ void
|
||||
glfw_connect_to_ibus(_GLFWIBUSData *ibus) {
|
||||
if (ibus->inited) return;
|
||||
if (!test_env_var("GLFW_IM_MODULE", "ibus")) return;
|
||||
ibus->inited = GLFW_TRUE;
|
||||
ibus->inited = true;
|
||||
setup_connection(ibus);
|
||||
}
|
||||
|
||||
@@ -297,21 +297,21 @@ glfw_ibus_terminate(_GLFWIBUSData *ibus) {
|
||||
F(address_file_name);
|
||||
#undef F
|
||||
|
||||
ibus->ok = GLFW_FALSE;
|
||||
ibus->ok = false;
|
||||
}
|
||||
|
||||
static GLFWbool
|
||||
static bool
|
||||
check_connection(_GLFWIBUSData *ibus) {
|
||||
if (!ibus->inited) return GLFW_FALSE;
|
||||
if (!ibus->inited) return false;
|
||||
if (ibus->conn && dbus_connection_get_is_connected(ibus->conn)) {
|
||||
return ibus->ok;
|
||||
}
|
||||
struct stat s;
|
||||
if (stat(ibus->address_file_name, &s) != 0 || s.st_mtime != ibus->address_file_mtime) {
|
||||
if (!read_ibus_address(ibus)) return GLFW_FALSE;
|
||||
if (!read_ibus_address(ibus)) return false;
|
||||
setup_connection(ibus);
|
||||
}
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -329,7 +329,7 @@ simple_message(_GLFWIBUSData *ibus, const char *method) {
|
||||
}
|
||||
|
||||
void
|
||||
glfw_ibus_set_focused(_GLFWIBUSData *ibus, GLFWbool focused) {
|
||||
glfw_ibus_set_focused(_GLFWIBUSData *ibus, bool focused) {
|
||||
simple_message(ibus, focused ? "FocusIn" : "FocusOut");
|
||||
}
|
||||
|
||||
@@ -394,24 +394,24 @@ void
|
||||
key_event_processed(DBusMessage *msg, const char* errmsg, void *data) {
|
||||
uint32_t handled = 0;
|
||||
KeyEvent *ev = (KeyEvent*)data;
|
||||
GLFWbool is_release = ev->action == GLFW_RELEASE;
|
||||
GLFWbool failed = GLFW_FALSE;
|
||||
bool is_release = ev->action == GLFW_RELEASE;
|
||||
bool failed = false;
|
||||
if (errmsg) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "IBUS: Failed to process key with error: %s", errmsg);
|
||||
failed = GLFW_TRUE;
|
||||
failed = true;
|
||||
} else {
|
||||
glfw_dbus_get_args(msg, "Failed to get IBUS handled key from reply", DBUS_TYPE_BOOLEAN, &handled, DBUS_TYPE_INVALID);
|
||||
debug("IBUS processed scancode: 0x%x release: %d handled: %u\n", ev->keycode, is_release, handled);
|
||||
}
|
||||
glfw_xkb_key_from_ime(ev, handled ? GLFW_TRUE : GLFW_FALSE, failed);
|
||||
glfw_xkb_key_from_ime(ev, handled ? true : false, failed);
|
||||
free(ev);
|
||||
}
|
||||
|
||||
GLFWbool
|
||||
bool
|
||||
ibus_process_key(const KeyEvent *ev_, _GLFWIBUSData *ibus) {
|
||||
if (!check_connection(ibus)) return GLFW_FALSE;
|
||||
if (!check_connection(ibus)) return false;
|
||||
KeyEvent *ev = malloc(sizeof(KeyEvent));
|
||||
if (!ev) return GLFW_FALSE;
|
||||
if (!ev) return false;
|
||||
memcpy(ev, ev_, sizeof(KeyEvent));
|
||||
uint32_t state = ibus_key_state(ev->glfw_modifiers, ev->action);
|
||||
if (!glfw_dbus_call_method_with_reply(
|
||||
@@ -420,7 +420,7 @@ ibus_process_key(const KeyEvent *ev_, _GLFWIBUSData *ibus) {
|
||||
DBUS_TYPE_UINT32, &ev->ibus_sym, DBUS_TYPE_UINT32, &ev->ibus_keycode, DBUS_TYPE_UINT32,
|
||||
&state, DBUS_TYPE_INVALID)) {
|
||||
free(ev);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
8
glfw/ibus_glfw.h
vendored
8
glfw/ibus_glfw.h
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 XKB - www.glfw.org
|
||||
// GLFW 3.4 XKB - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2018 Kovid Goyal <kovid@kovidgoyal.net>
|
||||
//
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
typedef struct {
|
||||
GLFWbool ok, inited;
|
||||
bool ok, inited;
|
||||
time_t address_file_mtime;
|
||||
DBusConnection *conn;
|
||||
const char *input_ctx_path, *address_file_name, *address;
|
||||
@@ -49,7 +49,7 @@ typedef struct {
|
||||
|
||||
void glfw_connect_to_ibus(_GLFWIBUSData *ibus);
|
||||
void glfw_ibus_terminate(_GLFWIBUSData *ibus);
|
||||
void glfw_ibus_set_focused(_GLFWIBUSData *ibus, GLFWbool focused);
|
||||
void glfw_ibus_set_focused(_GLFWIBUSData *ibus, bool focused);
|
||||
void glfw_ibus_dispatch(_GLFWIBUSData *ibus);
|
||||
GLFWbool ibus_process_key(const KeyEvent *ev_, _GLFWIBUSData *ibus);
|
||||
bool ibus_process_key(const KeyEvent *ev_, _GLFWIBUSData *ibus);
|
||||
void glfw_ibus_set_cursor_geometry(_GLFWIBUSData *ibus, int x, int y, int w, int h);
|
||||
|
||||
36
glfw/init.c
vendored
36
glfw/init.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// Please use C89 style variable declarations in this file because VS 2010
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
#include "mappings.h"
|
||||
@@ -41,7 +43,7 @@
|
||||
|
||||
// Global state shared between compilation units of GLFW
|
||||
//
|
||||
_GLFWlibrary _glfw = { GLFW_FALSE };
|
||||
_GLFWlibrary _glfw = { false };
|
||||
|
||||
// These are outside of _glfw so they can be used before initialization and
|
||||
// after termination
|
||||
@@ -50,12 +52,12 @@ static _GLFWerror _glfwMainThreadError;
|
||||
static GLFWerrorfun _glfwErrorCallback;
|
||||
static _GLFWinitconfig _glfwInitHints =
|
||||
{
|
||||
GLFW_TRUE, // hat buttons
|
||||
GLFW_FALSE, // debug keyboard
|
||||
GLFW_TRUE, // enable joystick
|
||||
true, // hat buttons
|
||||
false, // debug keyboard
|
||||
true, // enable joystick
|
||||
{
|
||||
GLFW_TRUE, // macOS menu bar
|
||||
GLFW_TRUE // macOS bundle chdir
|
||||
true, // macOS menu bar
|
||||
true // macOS bundle chdir
|
||||
}
|
||||
};
|
||||
|
||||
@@ -92,7 +94,7 @@ static void terminate(void)
|
||||
_glfwTerminateVulkan();
|
||||
_glfwPlatformTerminate();
|
||||
|
||||
_glfw.initialized = GLFW_FALSE;
|
||||
_glfw.initialized = false;
|
||||
|
||||
while (_glfw.errorListHead)
|
||||
{
|
||||
@@ -215,7 +217,7 @@ _glfwDebug(const char *format, ...) {
|
||||
GLFWAPI int glfwInit(void)
|
||||
{
|
||||
if (_glfw.initialized)
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
|
||||
memset(&_glfw, 0, sizeof(_glfw));
|
||||
_glfw.hints.init = _glfwInitHints;
|
||||
@@ -223,7 +225,7 @@ GLFWAPI int glfwInit(void)
|
||||
if (!_glfwPlatformInit())
|
||||
{
|
||||
terminate();
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_glfwPlatformCreateMutex(&_glfw.errorLock) ||
|
||||
@@ -231,12 +233,12 @@ GLFWAPI int glfwInit(void)
|
||||
!_glfwPlatformCreateTls(&_glfw.contextSlot))
|
||||
{
|
||||
terminate();
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfwPlatformSetTls(&_glfw.errorSlot, &_glfwMainThreadError);
|
||||
|
||||
_glfw.initialized = GLFW_TRUE;
|
||||
_glfw.initialized = true;
|
||||
_glfw.timer.offset = _glfwPlatformGetTimerValue();
|
||||
|
||||
glfwDefaultWindowHints();
|
||||
@@ -249,12 +251,12 @@ GLFWAPI int glfwInit(void)
|
||||
if (!glfwUpdateGamepadMappings(_glfwDefaultMappings[i]))
|
||||
{
|
||||
terminate();
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
GLFWAPI void glfwTerminate(void)
|
||||
@@ -342,10 +344,6 @@ GLFWAPI void glfwRunMainLoop(GLFWtickcallback callback, void *data)
|
||||
_glfwPlatformRunMainLoop(callback, data);
|
||||
}
|
||||
|
||||
GLFWAPI void glfwRequestTickCallback(void) {
|
||||
_glfwPlatformRequestTickCallback();
|
||||
}
|
||||
|
||||
GLFWAPI void glfwStopMainLoop(void) {
|
||||
_GLFW_REQUIRE_INIT();
|
||||
_glfwPlatformStopMainLoop();
|
||||
|
||||
97
glfw/input.c
vendored
97
glfw/input.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// Please use C89 style variable declarations in this file because VS 2010
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -58,17 +60,17 @@ static _GLFWmapping* findMapping(const char* guid)
|
||||
|
||||
// Checks whether a gamepad mapping element is present in the hardware
|
||||
//
|
||||
static GLFWbool isValidElementForJoystick(const _GLFWmapelement* e,
|
||||
static bool isValidElementForJoystick(const _GLFWmapelement* e,
|
||||
const _GLFWjoystick* js)
|
||||
{
|
||||
if (e->type == _GLFW_JOYSTICK_HATBIT && (e->index >> 4) >= js->hatCount)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
else if (e->type == _GLFW_JOYSTICK_BUTTON && e->index >= js->buttonCount)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
else if (e->type == _GLFW_JOYSTICK_AXIS && e->index >= js->axisCount)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Finds a mapping based on joystick GUID and verifies element indices
|
||||
@@ -110,7 +112,7 @@ static _GLFWmapping* findValidMapping(const _GLFWjoystick* js)
|
||||
|
||||
// Parses an SDL_GameControllerDB line and adds it to the mapping list
|
||||
//
|
||||
static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
|
||||
static bool parseMapping(_GLFWmapping* mapping, const char* string)
|
||||
{
|
||||
const char* c = string;
|
||||
size_t i, length;
|
||||
@@ -148,7 +150,7 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
|
||||
if (length != 32 || c[length] != ',')
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE, NULL);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(mapping->guid, c, length);
|
||||
@@ -158,7 +160,7 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
|
||||
if (length >= sizeof(mapping->name) || c[length] != ',')
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE, NULL);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(mapping->name, c, length);
|
||||
@@ -168,7 +170,7 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
|
||||
{
|
||||
// TODO: Implement output modifiers
|
||||
if (*c == '+' || *c == '-')
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
for (i = 0; i < sizeof(fields) / sizeof(fields[0]); i++)
|
||||
{
|
||||
@@ -229,7 +231,7 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
|
||||
{
|
||||
length = strlen(_GLFW_PLATFORM_MAPPING_NAME);
|
||||
if (strncmp(c, _GLFW_PLATFORM_MAPPING_NAME, length) != 0)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -246,7 +248,7 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
|
||||
}
|
||||
|
||||
_glfwPlatformUpdateGamepadGUID(mapping->guid);
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -254,19 +256,19 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
|
||||
////// GLFW event API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Notifies shared code of a key event
|
||||
// Notifies shared code of a physical key event
|
||||
//
|
||||
void _glfwInputKeyboard(_GLFWwindow* window, int key, int scancode, int action, int mods, const char* text, int state)
|
||||
{
|
||||
if (key >= 0 && key <= GLFW_KEY_LAST)
|
||||
{
|
||||
GLFWbool repeated = GLFW_FALSE;
|
||||
bool repeated = false;
|
||||
|
||||
if (action == GLFW_RELEASE && window->keys[key] == GLFW_RELEASE)
|
||||
return;
|
||||
|
||||
if (action == GLFW_PRESS && window->keys[key] == GLFW_PRESS)
|
||||
repeated = GLFW_TRUE;
|
||||
repeated = true;
|
||||
|
||||
if (action == GLFW_RELEASE && window->stickyKeys)
|
||||
window->keys[key] = _GLFW_STICK;
|
||||
@@ -328,7 +330,7 @@ void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos)
|
||||
|
||||
// Notifies shared code of a cursor enter/leave event
|
||||
//
|
||||
void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered)
|
||||
void _glfwInputCursorEnter(_GLFWwindow* window, bool entered)
|
||||
{
|
||||
if (window->callbacks.cursorEnter)
|
||||
window->callbacks.cursorEnter((GLFWwindow*) window, entered);
|
||||
@@ -406,10 +408,10 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
|
||||
return NULL;
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
js->present = GLFW_TRUE;
|
||||
js->present = true;
|
||||
js->name = _glfw_strdup(name);
|
||||
js->axes = calloc(axisCount, sizeof(float));
|
||||
js->buttons = calloc(buttonCount + hatCount * 4, 1);
|
||||
js->buttons = calloc(buttonCount + (size_t) hatCount * 4, 1);
|
||||
js->hats = calloc(hatCount, 1);
|
||||
js->axisCount = axisCount;
|
||||
js->buttonCount = buttonCount;
|
||||
@@ -488,6 +490,7 @@ const char* _glfwGetKeyName(int key)
|
||||
case GLFW_KEY_WORLD_1: return "WORLD 1";
|
||||
case GLFW_KEY_WORLD_2: return "WORLD 2";
|
||||
case GLFW_KEY_PLUS: return "PLUS";
|
||||
case GLFW_KEY_UNDERSCORE: return "UNDERSCORE";
|
||||
|
||||
// Function keys
|
||||
case GLFW_KEY_ESCAPE: return "ESCAPE";
|
||||
@@ -546,7 +549,7 @@ const char* _glfwGetKeyName(int key)
|
||||
case GLFW_KEY_KP_8: return "KEYPAD 8";
|
||||
case GLFW_KEY_KP_9: return "KEYPAD 9";
|
||||
case GLFW_KEY_KP_DIVIDE: return "KEYPAD DIVIDE";
|
||||
case GLFW_KEY_KP_MULTIPLY: return "KEYPAD MULTPLY";
|
||||
case GLFW_KEY_KP_MULTIPLY: return "KEYPAD MULTIPLY";
|
||||
case GLFW_KEY_KP_SUBTRACT: return "KEYPAD SUBTRACT";
|
||||
case GLFW_KEY_KP_ADD: return "KEYPAD ADD";
|
||||
case GLFW_KEY_KP_DECIMAL: return "KEYPAD DECIMAL";
|
||||
@@ -565,15 +568,17 @@ const char* _glfwGetKeyName(int key)
|
||||
}
|
||||
}
|
||||
|
||||
// Center the cursor in the middle of the content area of the specified window
|
||||
// Center the cursor in the content area of the specified window
|
||||
//
|
||||
void _glfwCenterCursorInContentArea(_GLFWwindow* window)
|
||||
{
|
||||
int width, height;
|
||||
|
||||
_glfwPlatformGetWindowSize(window, &width, &height);
|
||||
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW public API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -632,7 +637,7 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
||||
}
|
||||
else if (mode == GLFW_STICKY_KEYS)
|
||||
{
|
||||
value = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
value = value ? true : false;
|
||||
if (window->stickyKeys == value)
|
||||
return;
|
||||
|
||||
@@ -652,7 +657,7 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
||||
}
|
||||
else if (mode == GLFW_STICKY_MOUSE_BUTTONS)
|
||||
{
|
||||
value = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
value = value ? true : false;
|
||||
if (window->stickyMouseButtons == value)
|
||||
return;
|
||||
|
||||
@@ -671,7 +676,9 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
||||
window->stickyMouseButtons = value;
|
||||
}
|
||||
else if (mode == GLFW_LOCK_KEY_MODS)
|
||||
window->lockKeyMods = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
{
|
||||
window->lockKeyMods = value ? true : false;
|
||||
}
|
||||
else
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
|
||||
}
|
||||
@@ -987,17 +994,17 @@ GLFWAPI int glfwJoystickPresent(int jid)
|
||||
assert(jid >= GLFW_JOYSTICK_1);
|
||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(false);
|
||||
|
||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->present)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
return _glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE);
|
||||
}
|
||||
@@ -1189,7 +1196,7 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string)
|
||||
|
||||
assert(string != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(false);
|
||||
|
||||
while (*c)
|
||||
{
|
||||
@@ -1239,7 +1246,7 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string)
|
||||
js->mapping = findValidMapping(js);
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
GLFWAPI int glfwJoystickIsGamepad(int jid)
|
||||
@@ -1249,20 +1256,20 @@ GLFWAPI int glfwJoystickIsGamepad(int jid)
|
||||
assert(jid >= GLFW_JOYSTICK_1);
|
||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(false);
|
||||
|
||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->present)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
return js->mapping != NULL;
|
||||
}
|
||||
@@ -1306,23 +1313,23 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
|
||||
|
||||
memset(state, 0, sizeof(GLFWgamepadstate));
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(false);
|
||||
|
||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->present)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_ALL))
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
if (!js->mapping)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
for (i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++)
|
||||
{
|
||||
@@ -1358,15 +1365,17 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
|
||||
const unsigned int bit = e->index & 0xf;
|
||||
if (js->hats[hat] & bit)
|
||||
state->axes[i] = 1.f;
|
||||
else
|
||||
state->axes[i] = -1.f;
|
||||
}
|
||||
else if (e->type == _GLFW_JOYSTICK_BUTTON)
|
||||
state->axes[i] = (float) js->buttons[e->index];
|
||||
state->axes[i] = js->buttons[e->index] * 2.f - 1.f;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
|
||||
GLFWAPI void glfwSetClipboardString(GLFWwindow* handle UNUSED, const char* string)
|
||||
{
|
||||
assert(string != NULL);
|
||||
|
||||
@@ -1374,14 +1383,14 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
|
||||
_glfwPlatformSetClipboardString(string);
|
||||
}
|
||||
|
||||
GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle)
|
||||
GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle UNUSED)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
return _glfwPlatformGetClipboardString();
|
||||
}
|
||||
|
||||
#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND)
|
||||
GLFWAPI void glfwSetPrimarySelectionString(GLFWwindow* handle, const char* string)
|
||||
GLFWAPI void glfwSetPrimarySelectionString(GLFWwindow* handle UNUSED, const char* string)
|
||||
{
|
||||
assert(string != NULL);
|
||||
|
||||
@@ -1389,7 +1398,7 @@ GLFWAPI void glfwSetPrimarySelectionString(GLFWwindow* handle, const char* strin
|
||||
_glfwPlatformSetPrimarySelectionString(string);
|
||||
}
|
||||
|
||||
GLFWAPI const char* glfwGetPrimarySelectionString(GLFWwindow* handle)
|
||||
GLFWAPI const char* glfwGetPrimarySelectionString(GLFWwindow* handle UNUSED)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
return _glfwPlatformGetPrimarySelectionString();
|
||||
|
||||
163
glfw/internal.h
vendored
163
glfw/internal.h
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -60,7 +60,6 @@
|
||||
|
||||
#define _GLFW_MESSAGE_SIZE 1024
|
||||
|
||||
typedef bool GLFWbool;
|
||||
typedef unsigned long long GLFWid;
|
||||
|
||||
typedef struct _GLFWerror _GLFWerror;
|
||||
@@ -196,6 +195,13 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void);
|
||||
#error "No supported window creation API selected"
|
||||
#endif
|
||||
|
||||
#define remove_i_from_array(array, i, count) { \
|
||||
(count)--; \
|
||||
if ((i) < (count)) { \
|
||||
memmove((array) + (i), (array) + (i) + 1, sizeof((array)[0]) * ((count) - (i))); \
|
||||
}}
|
||||
|
||||
|
||||
// Constructs a version number string from the public header macros
|
||||
#define _GLFW_CONCAT_VERSION(m, n, r) #m "." #n "." #r
|
||||
#define _GLFW_MAKE_VERSION(m, n, r) _GLFW_CONCAT_VERSION(m, n, r)
|
||||
@@ -219,12 +225,32 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void);
|
||||
|
||||
// Swaps the provided pointers
|
||||
#define _GLFW_SWAP_POINTERS(x, y) \
|
||||
{ \
|
||||
void* t; \
|
||||
do{ \
|
||||
__typeof__(x) t; \
|
||||
t = x; \
|
||||
x = y; \
|
||||
y = t; \
|
||||
}
|
||||
}while(0)
|
||||
|
||||
|
||||
// Suppress some pedantic warnings
|
||||
#ifdef __clang__
|
||||
#define START_ALLOW_CASE_RANGE _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wpedantic\"")
|
||||
#define END_ALLOW_CASE_RANGE _Pragma("clang diagnostic pop")
|
||||
#define ALLOW_UNUSED_RESULT _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wunused-result\"")
|
||||
#define END_ALLOW_UNUSED_RESULT _Pragma("clang diagnostic pop")
|
||||
#else
|
||||
#define START_ALLOW_CASE_RANGE _Pragma("GCC diagnostic ignored \"-Wpedantic\"")
|
||||
#define END_ALLOW_CASE_RANGE _Pragma("GCC diagnostic pop")
|
||||
#define ALLOW_UNUSED_RESULT _Pragma("GCC diagnostic ignored \"-Wunused-result\"")
|
||||
#define END_ALLOW_UNUSED_RESULT _Pragma("GCC diagnostic pop")
|
||||
#endif
|
||||
|
||||
// dlsym that works with -Wpedantic
|
||||
#define glfw_dlsym(dest, handle, name) do {*(void **)&(dest) = _glfw_dlsym(handle, name);}while (0)
|
||||
|
||||
// Mark function arguments as unused
|
||||
#define UNUSED __attribute__ ((unused))
|
||||
|
||||
// Per-thread error structure
|
||||
//
|
||||
@@ -241,12 +267,12 @@ struct _GLFWerror
|
||||
//
|
||||
struct _GLFWinitconfig
|
||||
{
|
||||
GLFWbool hatButtons;
|
||||
GLFWbool debugKeyboard;
|
||||
GLFWbool enableJoysticks;
|
||||
bool hatButtons;
|
||||
bool debugKeyboard;
|
||||
bool enableJoysticks;
|
||||
struct {
|
||||
GLFWbool menubar;
|
||||
GLFWbool chdir;
|
||||
bool menubar;
|
||||
bool chdir;
|
||||
} ns;
|
||||
};
|
||||
|
||||
@@ -261,18 +287,18 @@ struct _GLFWwndconfig
|
||||
int width;
|
||||
int height;
|
||||
const char* title;
|
||||
GLFWbool resizable;
|
||||
GLFWbool visible;
|
||||
GLFWbool decorated;
|
||||
GLFWbool focused;
|
||||
GLFWbool autoIconify;
|
||||
GLFWbool floating;
|
||||
GLFWbool maximized;
|
||||
GLFWbool centerCursor;
|
||||
GLFWbool focusOnShow;
|
||||
GLFWbool scaleToMonitor;
|
||||
bool resizable;
|
||||
bool visible;
|
||||
bool decorated;
|
||||
bool focused;
|
||||
bool autoIconify;
|
||||
bool floating;
|
||||
bool maximized;
|
||||
bool centerCursor;
|
||||
bool focusOnShow;
|
||||
bool scaleToMonitor;
|
||||
struct {
|
||||
GLFWbool retina;
|
||||
bool retina;
|
||||
char frameName[256];
|
||||
} ns;
|
||||
struct {
|
||||
@@ -296,15 +322,15 @@ struct _GLFWctxconfig
|
||||
int source;
|
||||
int major;
|
||||
int minor;
|
||||
GLFWbool forward;
|
||||
GLFWbool debug;
|
||||
GLFWbool noerror;
|
||||
bool forward;
|
||||
bool debug;
|
||||
bool noerror;
|
||||
int profile;
|
||||
int robustness;
|
||||
int release;
|
||||
_GLFWwindow* share;
|
||||
struct {
|
||||
GLFWbool offline;
|
||||
bool offline;
|
||||
} nsgl;
|
||||
};
|
||||
|
||||
@@ -329,11 +355,11 @@ struct _GLFWfbconfig
|
||||
int accumBlueBits;
|
||||
int accumAlphaBits;
|
||||
int auxBuffers;
|
||||
GLFWbool stereo;
|
||||
bool stereo;
|
||||
int samples;
|
||||
GLFWbool sRGB;
|
||||
GLFWbool doublebuffer;
|
||||
GLFWbool transparent;
|
||||
bool sRGB;
|
||||
bool doublebuffer;
|
||||
bool transparent;
|
||||
uintptr_t handle;
|
||||
};
|
||||
|
||||
@@ -344,7 +370,7 @@ struct _GLFWcontext
|
||||
int client;
|
||||
int source;
|
||||
int major, minor, revision;
|
||||
GLFWbool forward, debug, noerror;
|
||||
bool forward, debug, noerror;
|
||||
int profile;
|
||||
int robustness;
|
||||
int release;
|
||||
@@ -361,7 +387,7 @@ struct _GLFWcontext
|
||||
_GLFWdestroycontextfun destroy;
|
||||
|
||||
// This is defined in the context API's context.h
|
||||
_GLFW_PLATFORM_CONTEXT_STATE;
|
||||
_GLFW_PLATFORM_CONTEXT_STATE
|
||||
// This is defined in egl_context.h
|
||||
_GLFW_EGL_CONTEXT_STATE;
|
||||
// This is defined in osmesa_context.h
|
||||
@@ -375,12 +401,12 @@ struct _GLFWwindow
|
||||
struct _GLFWwindow* next;
|
||||
|
||||
// Window settings and state
|
||||
GLFWbool resizable;
|
||||
GLFWbool decorated;
|
||||
GLFWbool autoIconify;
|
||||
GLFWbool floating;
|
||||
GLFWbool focusOnShow;
|
||||
GLFWbool shouldClose;
|
||||
bool resizable;
|
||||
bool decorated;
|
||||
bool autoIconify;
|
||||
bool floating;
|
||||
bool focusOnShow;
|
||||
bool shouldClose;
|
||||
void* userPointer;
|
||||
GLFWid id;
|
||||
GLFWvidmode videoMode;
|
||||
@@ -391,9 +417,9 @@ struct _GLFWwindow
|
||||
int maxwidth, maxheight;
|
||||
int numer, denom;
|
||||
|
||||
GLFWbool stickyKeys;
|
||||
GLFWbool stickyMouseButtons;
|
||||
GLFWbool lockKeyMods;
|
||||
bool stickyKeys;
|
||||
bool stickyMouseButtons;
|
||||
bool lockKeyMods;
|
||||
int cursorMode;
|
||||
char mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1];
|
||||
char keys[GLFW_KEY_LAST + 1];
|
||||
@@ -484,7 +510,7 @@ struct _GLFWmapping
|
||||
//
|
||||
struct _GLFWjoystick
|
||||
{
|
||||
GLFWbool present;
|
||||
bool present;
|
||||
float* axes;
|
||||
int axisCount;
|
||||
unsigned char* buttons;
|
||||
@@ -520,7 +546,7 @@ struct _GLFWmutex
|
||||
//
|
||||
struct _GLFWlibrary
|
||||
{
|
||||
GLFWbool initialized;
|
||||
bool initialized;
|
||||
|
||||
struct {
|
||||
_GLFWinitconfig init;
|
||||
@@ -553,23 +579,23 @@ struct _GLFWlibrary
|
||||
} timer;
|
||||
|
||||
struct {
|
||||
GLFWbool available;
|
||||
bool available;
|
||||
void* handle;
|
||||
char* extensions[2];
|
||||
#if !defined(_GLFW_VULKAN_STATIC)
|
||||
PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
|
||||
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
|
||||
#endif
|
||||
GLFWbool KHR_surface;
|
||||
bool KHR_surface;
|
||||
#if defined(_GLFW_WIN32)
|
||||
GLFWbool KHR_win32_surface;
|
||||
bool KHR_win32_surface;
|
||||
#elif defined(_GLFW_COCOA)
|
||||
GLFWbool MVK_macos_surface;
|
||||
bool MVK_macos_surface;
|
||||
#elif defined(_GLFW_X11)
|
||||
GLFWbool KHR_xlib_surface;
|
||||
GLFWbool KHR_xcb_surface;
|
||||
bool KHR_xlib_surface;
|
||||
bool KHR_xcb_surface;
|
||||
#elif defined(_GLFW_WAYLAND)
|
||||
GLFWbool KHR_wayland_surface;
|
||||
bool KHR_wayland_surface;
|
||||
#endif
|
||||
} vk;
|
||||
|
||||
@@ -581,9 +607,9 @@ struct _GLFWlibrary
|
||||
// This is defined in the window API's platform.h
|
||||
_GLFW_PLATFORM_LIBRARY_WINDOW_STATE;
|
||||
// This is defined in the context API's context.h
|
||||
_GLFW_PLATFORM_LIBRARY_CONTEXT_STATE;
|
||||
_GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
|
||||
// This is defined in the platform's joystick.h
|
||||
_GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE;
|
||||
_GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE
|
||||
// This is defined in egl_context.h
|
||||
_GLFW_EGL_LIBRARY_CONTEXT_STATE;
|
||||
// This is defined in osmesa_context.h
|
||||
@@ -622,7 +648,7 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
||||
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height);
|
||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count);
|
||||
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode);
|
||||
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
|
||||
bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
|
||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
|
||||
|
||||
void _glfwPlatformSetClipboardString(const char* string);
|
||||
@@ -682,9 +708,9 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window);
|
||||
int _glfwPlatformWindowHovered(_GLFWwindow* window);
|
||||
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window);
|
||||
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window);
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled);
|
||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled);
|
||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled);
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, bool enabled);
|
||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, bool enabled);
|
||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, bool enabled);
|
||||
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity);
|
||||
void _glfwPlatformUpdateIMEState(_GLFWwindow *w, int which, int a, int b, int c, int d);
|
||||
|
||||
@@ -702,12 +728,12 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
||||
const VkAllocationCallbacks* allocator,
|
||||
VkSurfaceKHR* surface);
|
||||
|
||||
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls);
|
||||
bool _glfwPlatformCreateTls(_GLFWtls* tls);
|
||||
void _glfwPlatformDestroyTls(_GLFWtls* tls);
|
||||
void* _glfwPlatformGetTls(_GLFWtls* tls);
|
||||
void _glfwPlatformSetTls(_GLFWtls* tls, void* value);
|
||||
|
||||
GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex);
|
||||
bool _glfwPlatformCreateMutex(_GLFWmutex* mutex);
|
||||
void _glfwPlatformDestroyMutex(_GLFWmutex* mutex);
|
||||
void _glfwPlatformLockMutex(_GLFWmutex* mutex);
|
||||
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex);
|
||||
@@ -717,15 +743,15 @@ void _glfwPlatformUnlockMutex(_GLFWmutex* mutex);
|
||||
////// GLFW event API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused);
|
||||
void _glfwInputWindowOcclusion(_GLFWwindow* window, GLFWbool occluded);
|
||||
void _glfwInputWindowFocus(_GLFWwindow* window, bool focused);
|
||||
void _glfwInputWindowOcclusion(_GLFWwindow* window, bool occluded);
|
||||
void _glfwInputWindowPos(_GLFWwindow* window, int xpos, int ypos);
|
||||
void _glfwInputWindowSize(_GLFWwindow* window, int width, int height);
|
||||
void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height);
|
||||
void _glfwInputWindowContentScale(_GLFWwindow* window,
|
||||
float xscale, float yscale);
|
||||
void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified);
|
||||
void _glfwInputWindowMaximize(_GLFWwindow* window, GLFWbool maximized);
|
||||
void _glfwInputWindowIconify(_GLFWwindow* window, bool iconified);
|
||||
void _glfwInputWindowMaximize(_GLFWwindow* window, bool maximized);
|
||||
void _glfwInputWindowDamage(_GLFWwindow* window);
|
||||
void _glfwInputWindowCloseRequest(_GLFWwindow* window);
|
||||
void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor);
|
||||
@@ -734,7 +760,7 @@ void _glfwInputKeyboard(_GLFWwindow* window, int key, int scancode, int action,
|
||||
void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset, int flags);
|
||||
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods);
|
||||
void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos);
|
||||
void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered);
|
||||
void _glfwInputCursorEnter(_GLFWwindow* window, bool entered);
|
||||
void _glfwInputDrop(_GLFWwindow* window, int count, const char** names);
|
||||
void _glfwInputJoystick(_GLFWjoystick* js, int event);
|
||||
void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value);
|
||||
@@ -764,13 +790,13 @@ void _glfwDebug(const char* format, ...);
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions);
|
||||
bool _glfwStringInExtensionString(const char* string, const char* extensions);
|
||||
const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
|
||||
const _GLFWfbconfig* alternatives,
|
||||
unsigned int count);
|
||||
GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
bool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig);
|
||||
GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig);
|
||||
bool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig);
|
||||
|
||||
const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor,
|
||||
const GLFWvidmode* desired);
|
||||
@@ -790,16 +816,15 @@ void _glfwFreeJoystick(_GLFWjoystick* js);
|
||||
const char* _glfwGetKeyName(int key);
|
||||
void _glfwCenterCursorInContentArea(_GLFWwindow* window);
|
||||
|
||||
GLFWbool _glfwInitVulkan(int mode);
|
||||
bool _glfwInitVulkan(int mode);
|
||||
void _glfwTerminateVulkan(void);
|
||||
const char* _glfwGetVulkanResultString(VkResult result);
|
||||
_GLFWwindow* _glfwFocusedWindow(void);
|
||||
_GLFWwindow* _glfwWindowForId(GLFWid id);
|
||||
void _glfwPlatformRunMainLoop(GLFWtickcallback, void*);
|
||||
void _glfwPlatformRequestTickCallback(void);
|
||||
void _glfwPlatformStopMainLoop(void);
|
||||
unsigned long long _glfwPlatformAddTimer(double interval, bool repeats, GLFWuserdatafun callback, void *callback_data, GLFWuserdatafun free_callback);
|
||||
void _glfwPlatformUpdateTimer(unsigned long long timer_id, double interval, GLFWbool enabled);
|
||||
void _glfwPlatformUpdateTimer(unsigned long long timer_id, double interval, bool enabled);
|
||||
void _glfwPlatformRemoveTimer(unsigned long long timer_id);
|
||||
|
||||
char* _glfw_strdup(const char* source);
|
||||
|
||||
95
glfw/linux_joystick.c
vendored
95
glfw/linux_joystick.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Linux - www.glfw.org
|
||||
// GLFW 3.4 Linux - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -104,9 +106,7 @@ static void handleAbsEvent(_GLFWjoystick* js, int code, int value)
|
||||
//
|
||||
static void pollAbsState(_GLFWjoystick* js)
|
||||
{
|
||||
int code;
|
||||
|
||||
for (code = 0; code < ABS_CNT; code++)
|
||||
for (int code = 0; code < ABS_CNT; code++)
|
||||
{
|
||||
if (js->linjs.absMap[code] < 0)
|
||||
continue;
|
||||
@@ -124,53 +124,52 @@ static void pollAbsState(_GLFWjoystick* js)
|
||||
|
||||
// Attempt to open the specified joystick device
|
||||
//
|
||||
static GLFWbool openJoystickDevice(const char* path)
|
||||
static bool openJoystickDevice(const char* path)
|
||||
{
|
||||
int jid, code;
|
||||
char name[256] = "";
|
||||
char guid[33] = "";
|
||||
char evBits[(EV_CNT + 7) / 8] = {0};
|
||||
char keyBits[(KEY_CNT + 7) / 8] = {0};
|
||||
char absBits[(ABS_CNT + 7) / 8] = {0};
|
||||
int axisCount = 0, buttonCount = 0, hatCount = 0;
|
||||
struct input_id id;
|
||||
_GLFWjoystickLinux linjs = {0};
|
||||
_GLFWjoystick* js = NULL;
|
||||
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
if (!_glfw.joysticks[jid].present)
|
||||
continue;
|
||||
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_GLFWjoystickLinux linjs = {0};
|
||||
linjs.fd = open(path, O_RDONLY | O_NONBLOCK);
|
||||
if (linjs.fd == -1)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
if (ioctl(linjs.fd, EVIOCGBIT(0, sizeof(evBits)), evBits) < 0 ||
|
||||
ioctl(linjs.fd, EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits) < 0 ||
|
||||
ioctl(linjs.fd, EVIOCGBIT(EV_ABS, sizeof(absBits)), absBits) < 0 ||
|
||||
ioctl(linjs.fd, EVIOCGID, &id) < 0)
|
||||
char evBits[(EV_CNT + 7) / 8] = {0};
|
||||
char keyBits[(KEY_CNT + 7) / 8] = {0};
|
||||
char absBits[(ABS_CNT + 7) / 8] = {0};
|
||||
struct input_id id;
|
||||
|
||||
if (ioctl(linjs.fd, (int32_t)EVIOCGBIT(0, sizeof(evBits)), evBits) < 0 ||
|
||||
ioctl(linjs.fd, (int32_t)EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits) < 0 ||
|
||||
ioctl(linjs.fd, (int32_t)EVIOCGBIT(EV_ABS, sizeof(absBits)), absBits) < 0 ||
|
||||
ioctl(linjs.fd, (int32_t)EVIOCGID, &id) < 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Linux: Failed to query input device: %s",
|
||||
strerror(errno));
|
||||
close(linjs.fd);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure this device supports the events expected of a joystick
|
||||
if (!isBitSet(EV_KEY, evBits) || !isBitSet(EV_ABS, evBits))
|
||||
{
|
||||
close(linjs.fd);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ioctl(linjs.fd, EVIOCGNAME(sizeof(name)), name) < 0)
|
||||
char name[256] = "";
|
||||
|
||||
if (ioctl(linjs.fd, (int32_t)EVIOCGNAME(sizeof(name)), name) < 0)
|
||||
strncpy(name, "Unknown", sizeof(name));
|
||||
|
||||
char guid[33] = "";
|
||||
|
||||
// Generate a joystick GUID that matches the SDL 2.0.5+ one
|
||||
if (id.vendor && id.product && id.version)
|
||||
{
|
||||
@@ -189,7 +188,9 @@ static GLFWbool openJoystickDevice(const char* path)
|
||||
name[8], name[9], name[10]);
|
||||
}
|
||||
|
||||
for (code = BTN_MISC; code < KEY_CNT; code++)
|
||||
int axisCount = 0, buttonCount = 0, hatCount = 0;
|
||||
|
||||
for (int code = BTN_MISC; code < KEY_CNT; code++)
|
||||
{
|
||||
if (!isBitSet(code, keyBits))
|
||||
continue;
|
||||
@@ -198,7 +199,7 @@ static GLFWbool openJoystickDevice(const char* path)
|
||||
buttonCount++;
|
||||
}
|
||||
|
||||
for (code = 0; code < ABS_CNT; code++)
|
||||
for (int code = 0; code < ABS_CNT; code++)
|
||||
{
|
||||
linjs.absMap[code] = -1;
|
||||
if (!isBitSet(code, absBits))
|
||||
@@ -221,11 +222,11 @@ static GLFWbool openJoystickDevice(const char* path)
|
||||
}
|
||||
}
|
||||
|
||||
js = _glfwAllocJoystick(name, guid, axisCount, buttonCount, hatCount);
|
||||
_GLFWjoystick* js = _glfwAllocJoystick(name, guid, axisCount, buttonCount, hatCount);
|
||||
if (!js)
|
||||
{
|
||||
close(linjs.fd);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
strncpy(linjs.path, path, sizeof(linjs.path) - 1);
|
||||
@@ -234,7 +235,7 @@ static GLFWbool openJoystickDevice(const char* path)
|
||||
pollAbsState(js);
|
||||
|
||||
_glfwInputJoystick(js, GLFW_CONNECTED);
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef isBitSet
|
||||
@@ -264,10 +265,8 @@ static int compareJoysticks(const void* fp, const void* sp)
|
||||
|
||||
// Initialize joystick interface
|
||||
//
|
||||
GLFWbool _glfwInitJoysticksLinux(void)
|
||||
bool _glfwInitJoysticksLinux(void)
|
||||
{
|
||||
DIR* dir;
|
||||
int count = 0;
|
||||
const char* dirname = "/dev/input";
|
||||
|
||||
_glfw.linjs.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
|
||||
@@ -286,10 +285,12 @@ GLFWbool _glfwInitJoysticksLinux(void)
|
||||
if (regcomp(&_glfw.linjs.regex, "^event[0-9]\\+$", 0) != 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Linux: Failed to compile regex");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
dir = opendir(dirname);
|
||||
int count = 0;
|
||||
|
||||
DIR* dir = opendir(dirname);
|
||||
if (dir)
|
||||
{
|
||||
struct dirent* entry;
|
||||
@@ -314,8 +315,8 @@ GLFWbool _glfwInitJoysticksLinux(void)
|
||||
|
||||
// Continue with no joysticks if enumeration fails
|
||||
|
||||
qsort(_glfw.joysticks, count, sizeof(_GLFWjoystick), compareJoysticks);
|
||||
return GLFW_TRUE;
|
||||
qsort(_glfw.joysticks, count, sizeof(_glfw.joysticks[0]), compareJoysticks);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Close all opened joystick handles
|
||||
@@ -344,12 +345,12 @@ void _glfwTerminateJoysticksLinux(void)
|
||||
|
||||
void _glfwDetectJoystickConnectionLinux(void)
|
||||
{
|
||||
ssize_t offset = 0;
|
||||
char buffer[16384];
|
||||
|
||||
if (_glfw.linjs.inotify <= 0)
|
||||
return;
|
||||
|
||||
ssize_t offset = 0;
|
||||
char buffer[16384];
|
||||
const ssize_t size = read(_glfw.linjs.inotify, buffer, sizeof(buffer));
|
||||
|
||||
while (size > offset)
|
||||
@@ -369,9 +370,7 @@ void _glfwDetectJoystickConnectionLinux(void)
|
||||
openJoystickDevice(path);
|
||||
else if (e->mask & IN_DELETE)
|
||||
{
|
||||
int jid;
|
||||
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
|
||||
{
|
||||
@@ -388,7 +387,7 @@ void _glfwDetectJoystickConnectionLinux(void)
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode UNUSED)
|
||||
{
|
||||
// Read all queued events (non-blocking)
|
||||
for (;;)
|
||||
@@ -408,10 +407,10 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||
if (e.type == EV_SYN)
|
||||
{
|
||||
if (e.code == SYN_DROPPED)
|
||||
_glfw.linjs.dropped = GLFW_TRUE;
|
||||
_glfw.linjs.dropped = true;
|
||||
else if (e.code == SYN_REPORT)
|
||||
{
|
||||
_glfw.linjs.dropped = GLFW_FALSE;
|
||||
_glfw.linjs.dropped = false;
|
||||
pollAbsState(js);
|
||||
}
|
||||
}
|
||||
@@ -428,6 +427,6 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||
return js->present;
|
||||
}
|
||||
|
||||
void _glfwPlatformUpdateGamepadGUID(char* guid)
|
||||
void _glfwPlatformUpdateGamepadGUID(char* guid UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
9
glfw/linux_joystick.h
vendored
9
glfw/linux_joystick.h
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Linux - www.glfw.org
|
||||
// GLFW 3.4 Linux - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
|
||||
//
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <regex.h>
|
||||
|
||||
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickLinux linjs
|
||||
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs
|
||||
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs;
|
||||
|
||||
#define _GLFW_PLATFORM_MAPPING_NAME "Linux"
|
||||
|
||||
@@ -52,11 +52,10 @@ typedef struct _GLFWlibraryLinux
|
||||
int inotify;
|
||||
int watch;
|
||||
regex_t regex;
|
||||
GLFWbool dropped;
|
||||
bool dropped;
|
||||
} _GLFWlibraryLinux;
|
||||
|
||||
|
||||
GLFWbool _glfwInitJoysticksLinux(void);
|
||||
bool _glfwInitJoysticksLinux(void);
|
||||
void _glfwTerminateJoysticksLinux(void);
|
||||
void _glfwDetectJoystickConnectionLinux(void);
|
||||
|
||||
|
||||
3
glfw/linux_notify.c
vendored
3
glfw/linux_notify.c
vendored
@@ -43,8 +43,7 @@ notification_created(DBusMessage *msg, const char* errmsg, void *data) {
|
||||
}
|
||||
|
||||
static DBusHandlerResult
|
||||
message_handler(DBusConnection *conn, DBusMessage *msg, void *user_data) {
|
||||
(void)(user_data);
|
||||
message_handler(DBusConnection *conn UNUSED, DBusMessage *msg, void *user_data UNUSED) {
|
||||
/* printf("session_bus message_handler invoked interface: %s member: %s\n", dbus_message_get_interface(msg), dbus_message_get_member(msg)); */
|
||||
if (dbus_message_is_signal(msg, NOTIFICATIONS_IFACE, "ActionInvoked")) {
|
||||
uint32_t notification_id;
|
||||
|
||||
19
glfw/main_loop.h
vendored
19
glfw/main_loop.h
vendored
@@ -12,25 +12,28 @@
|
||||
#define GLFW_LOOP_BACKEND x11
|
||||
#endif
|
||||
|
||||
static GLFWbool keep_going = GLFW_FALSE;
|
||||
static bool keep_going = false;
|
||||
|
||||
void _glfwPlatformRequestTickCallback() {
|
||||
}
|
||||
|
||||
void _glfwPlatformStopMainLoop(void) {
|
||||
if (keep_going) {
|
||||
keep_going = GLFW_FALSE;
|
||||
keep_going = false;
|
||||
_glfwPlatformPostEmptyEvent();
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformRunMainLoop(GLFWtickcallback tick_callback, void* data) {
|
||||
keep_going = GLFW_TRUE;
|
||||
keep_going = 1;
|
||||
EventLoopData *eld = &_glfw.GLFW_LOOP_BACKEND.eventLoopData;
|
||||
while(keep_going) {
|
||||
_glfwPlatformWaitEvents();
|
||||
EVDBG("loop tick");
|
||||
tick_callback(data);
|
||||
EVDBG("--------- loop tick, wakeups_happened: %d ----------", eld->wakeup_data_read);
|
||||
if (eld->wakeup_data_read) {
|
||||
eld->wakeup_data_read = false;
|
||||
tick_callback(data);
|
||||
}
|
||||
}
|
||||
EVDBG("main loop exiting");
|
||||
}
|
||||
|
||||
unsigned long long _glfwPlatformAddTimer(double interval, bool repeats, GLFWuserdatafreefun callback, void *callback_data, GLFWuserdatafreefun free_callback) {
|
||||
@@ -41,7 +44,7 @@ void _glfwPlatformRemoveTimer(unsigned long long timer_id) {
|
||||
removeTimer(&_glfw.GLFW_LOOP_BACKEND.eventLoopData, timer_id);
|
||||
}
|
||||
|
||||
void _glfwPlatformUpdateTimer(unsigned long long timer_id, double interval, GLFWbool enabled) {
|
||||
void _glfwPlatformUpdateTimer(unsigned long long timer_id, double interval, bool enabled) {
|
||||
changeTimerInterval(&_glfw.GLFW_LOOP_BACKEND.eventLoopData, timer_id, interval);
|
||||
toggleTimer(&_glfw.GLFW_LOOP_BACKEND.eventLoopData, timer_id, enabled);
|
||||
}
|
||||
|
||||
4
glfw/mappings.h
vendored
4
glfw/mappings.h
vendored
@@ -1,7 +1,7 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
34
glfw/monitor.c
vendored
34
glfw/monitor.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// Please use C89 style variable declarations in this file because VS 2010
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -60,25 +62,25 @@ static int compareVideoModes(const void* fp, const void* sp)
|
||||
|
||||
// Retrieves the available modes for the specified monitor
|
||||
//
|
||||
static GLFWbool refreshVideoModes(_GLFWmonitor* monitor)
|
||||
static bool refreshVideoModes(_GLFWmonitor* monitor)
|
||||
{
|
||||
int modeCount;
|
||||
GLFWvidmode* modes;
|
||||
|
||||
if (monitor->modes)
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
|
||||
modes = _glfwPlatformGetVideoModes(monitor, &modeCount);
|
||||
if (!modes)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
qsort(modes, modeCount, sizeof(GLFWvidmode), compareVideoModes);
|
||||
qsort(modes, modeCount, sizeof(modes[0]), compareVideoModes);
|
||||
|
||||
free(monitor->modes);
|
||||
monitor->modes = modes;
|
||||
monitor->modeCount = modeCount;
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +102,7 @@ void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement)
|
||||
{
|
||||
memmove(_glfw.monitors + 1,
|
||||
_glfw.monitors,
|
||||
(_glfw.monitorCount - 1) * sizeof(_GLFWmonitor*));
|
||||
((size_t) _glfw.monitorCount - 1) * sizeof(_GLFWmonitor*));
|
||||
_glfw.monitors[0] = monitor;
|
||||
}
|
||||
else
|
||||
@@ -127,10 +129,7 @@ void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement)
|
||||
{
|
||||
if (_glfw.monitors[i] == monitor)
|
||||
{
|
||||
_glfw.monitorCount--;
|
||||
memmove(_glfw.monitors + i,
|
||||
_glfw.monitors + i + 1,
|
||||
(_glfw.monitorCount - i) * sizeof(_GLFWmonitor*));
|
||||
remove_i_from_array(_glfw.monitors, i, _glfw.monitorCount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -330,7 +329,9 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos)
|
||||
_glfwPlatformGetMonitorPos(monitor, xpos, ypos);
|
||||
}
|
||||
|
||||
GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle, int* xpos, int* ypos, int* width, int* height)
|
||||
GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle,
|
||||
int* xpos, int* ypos,
|
||||
int* width, int* height)
|
||||
{
|
||||
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||
assert(monitor != NULL);
|
||||
@@ -451,7 +452,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
|
||||
GLFWgammaramp ramp;
|
||||
const GLFWgammaramp* original;
|
||||
assert(handle != NULL);
|
||||
assert(gamma >= 0.f);
|
||||
assert(gamma > 0.f);
|
||||
assert(gamma <= FLT_MAX);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
@@ -461,6 +462,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
|
||||
_glfwInputError(GLFW_INVALID_VALUE, "Invalid gamma value %f", gamma);
|
||||
return;
|
||||
}
|
||||
|
||||
original = glfwGetGammaRamp(handle);
|
||||
if (!original)
|
||||
return;
|
||||
@@ -475,10 +477,8 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
|
||||
value = i / (float) (original->size - 1);
|
||||
// Apply gamma curve
|
||||
value = powf(value, 1.f / gamma) * 65535.f + 0.5f;
|
||||
|
||||
// Clamp to value range
|
||||
if (value > 65535.f)
|
||||
value = 65535.f;
|
||||
value = fminf(value, 65535.f);
|
||||
|
||||
values[i] = (unsigned short) value;
|
||||
}
|
||||
|
||||
13
glfw/nsgl_context.h
vendored
13
glfw/nsgl_context.h
vendored
@@ -1,7 +1,7 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 macOS - www.glfw.org
|
||||
// GLFW 3.4 macOS - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,8 +24,8 @@
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL nsgl
|
||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl
|
||||
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL nsgl;
|
||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl;
|
||||
|
||||
|
||||
// NSGL-specific per-context data
|
||||
@@ -47,10 +47,9 @@ typedef struct _GLFWlibraryNSGL
|
||||
} _GLFWlibraryNSGL;
|
||||
|
||||
|
||||
GLFWbool _glfwInitNSGL(void);
|
||||
bool _glfwInitNSGL(void);
|
||||
void _glfwTerminateNSGL(void);
|
||||
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
bool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
void _glfwDestroyContextNSGL(_GLFWwindow* window);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 macOS - www.glfw.org
|
||||
// GLFW 3.4 macOS - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -23,6 +23,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -43,18 +45,17 @@ static void swapBuffersNSGL(_GLFWwindow* window)
|
||||
[window->context.nsgl.object flushBuffer];
|
||||
}
|
||||
|
||||
static void swapIntervalNSGL(int interval)
|
||||
static void swapIntervalNSGL(int interval UNUSED)
|
||||
{
|
||||
// As of Mojave this does not work so we use CVDisplayLink instead
|
||||
(void)(interval);
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"NSGL: Swap intervals do not work on macOS");
|
||||
}
|
||||
|
||||
static int extensionSupportedNSGL(const char* extension)
|
||||
static int extensionSupportedNSGL(const char* extension UNUSED)
|
||||
{
|
||||
// There are no NSGL extensions
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
static GLFWglproc getProcAddressNSGL(const char* procname)
|
||||
@@ -63,16 +64,15 @@ static GLFWglproc getProcAddressNSGL(const char* procname)
|
||||
procname,
|
||||
kCFStringEncodingASCII);
|
||||
|
||||
GLFWglproc symbol = CFBundleGetFunctionPointerForName(_glfw.nsgl.framework,
|
||||
symbolName);
|
||||
GLFWglproc symbol;
|
||||
*(void **) &symbol = CFBundleGetFunctionPointerForName(_glfw.nsgl.framework,
|
||||
symbolName);
|
||||
|
||||
CFRelease(symbolName);
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
||||
// Destroy the OpenGL context
|
||||
//
|
||||
static void destroyContextNSGL(_GLFWwindow* window)
|
||||
{
|
||||
[window->context.nsgl.pixelFormat release];
|
||||
@@ -89,10 +89,10 @@ static void destroyContextNSGL(_GLFWwindow* window)
|
||||
|
||||
// Initialize OpenGL support
|
||||
//
|
||||
GLFWbool _glfwInitNSGL(void)
|
||||
bool _glfwInitNSGL(void)
|
||||
{
|
||||
if (_glfw.nsgl.framework)
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
|
||||
_glfw.nsgl.framework =
|
||||
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
|
||||
@@ -100,10 +100,10 @@ GLFWbool _glfwInitNSGL(void)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"NSGL: Failed to locate OpenGL framework");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Terminate OpenGL support
|
||||
@@ -114,7 +114,7 @@ void _glfwTerminateNSGL(void)
|
||||
|
||||
// Create the OpenGL context
|
||||
//
|
||||
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
bool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
@@ -122,7 +122,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"NSGL: OpenGL ES is not available on macOS");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctxconfig->major > 2)
|
||||
@@ -131,14 +131,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"NSGL: The targeted version of macOS does not support OpenGL 3.0 or 3.1 but may support 3.2 and above");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (!ctxconfig->forward || ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE)
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"NSGL: The targeted version of macOS only supports forward-compatible core profile contexts for OpenGL 3.2 and above");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,7 +232,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||
"NSGL: Stereo rendering is deprecated");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
#else
|
||||
addAttrib(NSOpenGLPFAStereo);
|
||||
#endif
|
||||
@@ -275,7 +268,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||
"NSGL: Failed to find a suitable pixel format");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
NSOpenGLContext* share = NULL;
|
||||
@@ -290,13 +283,14 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"NSGL: Failed to create OpenGL context");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fbconfig->transparent)
|
||||
{
|
||||
GLint opaque = 0;
|
||||
[window->context.nsgl.object setValues:&opaque forParameter:NSOpenGLContextParameterSurfaceOpacity];
|
||||
[window->context.nsgl.object setValues:&opaque
|
||||
forParameter:NSOpenGLContextParameterSurfaceOpacity];
|
||||
}
|
||||
|
||||
if (window->ns.retina)
|
||||
@@ -315,7 +309,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
window->context.getProcAddress = getProcAddressNSGL;
|
||||
window->context.destroy = destroyContextNSGL;
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
8
glfw/null_init.c
vendored
8
glfw/null_init.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2016 Google Inc.
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -35,7 +37,7 @@
|
||||
int _glfwPlatformInit(void)
|
||||
{
|
||||
_glfwInitTimerPOSIX();
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwPlatformTerminate(void)
|
||||
|
||||
8
glfw/null_joystick.c
vendored
8
glfw/null_joystick.c
vendored
@@ -1,7 +1,7 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -23,6 +23,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -33,7 +35,7 @@
|
||||
|
||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
void _glfwPlatformUpdateGamepadGUID(char* guid)
|
||||
|
||||
7
glfw/null_joystick.h
vendored
7
glfw/null_joystick.h
vendored
@@ -1,7 +1,7 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -25,7 +25,6 @@
|
||||
//========================================================================
|
||||
|
||||
#define _GLFW_PLATFORM_JOYSTICK_STATE int nulljs
|
||||
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE int nulljs
|
||||
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE int nulljs;
|
||||
|
||||
#define _GLFW_PLATFORM_MAPPING_NAME ""
|
||||
|
||||
|
||||
15
glfw/null_monitor.c
vendored
15
glfw/null_monitor.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2016 Google Inc.
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2016-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -49,7 +51,9 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
||||
*yscale = 1.f;
|
||||
}
|
||||
|
||||
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height)
|
||||
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
|
||||
int* xpos, int* ypos,
|
||||
int* width, int* height)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -62,11 +66,12 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
||||
{
|
||||
}
|
||||
|
||||
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
4
glfw/null_platform.h
vendored
4
glfw/null_platform.h
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2016 Google Inc.
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
47
glfw/null_window.c
vendored
47
glfw/null_window.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2016 Google Inc.
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2016-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -34,7 +36,7 @@ static int createNativeWindow(_GLFWwindow* window,
|
||||
window->null.width = wndconfig->width;
|
||||
window->null.height = wndconfig->height;
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +50,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
if (!createNativeWindow(window, wndconfig))
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
if (ctxconfig->client != GLFW_NO_API)
|
||||
{
|
||||
@@ -56,18 +58,18 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
|
||||
{
|
||||
if (!_glfwInitOSMesa())
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "Null: EGL not available");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
@@ -167,28 +169,28 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
|
||||
|
||||
int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
int _glfwPlatformWindowHovered(_GLFWwindow* window)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, bool enabled)
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
|
||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, bool enabled)
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, bool enabled)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -212,7 +214,7 @@ void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
|
||||
|
||||
int _glfwPlatformWindowBell(_GLFWwindow* window)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
|
||||
@@ -229,22 +231,22 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window)
|
||||
|
||||
int _glfwPlatformWindowFocused(_GLFWwindow* window)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
int _glfwPlatformWindowOccluded(_GLFWwindow* window)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
int _glfwPlatformWindowIconified(_GLFWwindow* window)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
int _glfwPlatformWindowVisible(_GLFWwindow* window)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
void _glfwPlatformPollEvents(void)
|
||||
@@ -279,12 +281,12 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
||||
const GLFWimage* image,
|
||||
int xhot, int yhot, int count)
|
||||
{
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
||||
{
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
||||
@@ -322,7 +324,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
||||
VkPhysicalDevice device,
|
||||
uint32_t queuefamily)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
||||
@@ -333,3 +335,4 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
||||
// This seems like the most appropriate error to return here
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
|
||||
73
glfw/osmesa_context.c
vendored
73
glfw/osmesa_context.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 OSMesa - www.glfw.org
|
||||
// GLFW 3.4 OSMesa - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2016 Google Inc.
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// Please use C89 style variable declarations in this file because VS 2010
|
||||
//========================================================================
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -47,7 +49,7 @@ static void makeContextCurrentOSMesa(_GLFWwindow* window)
|
||||
free(window->context.osmesa.buffer);
|
||||
|
||||
// Allocate the new buffer (width * height * 8-bit RGBA)
|
||||
window->context.osmesa.buffer = calloc(4, width * height);
|
||||
window->context.osmesa.buffer = calloc(4, (size_t) width * height);
|
||||
window->context.osmesa.width = width;
|
||||
window->context.osmesa.height = height;
|
||||
}
|
||||
@@ -87,20 +89,20 @@ static void destroyContextOSMesa(_GLFWwindow* window)
|
||||
}
|
||||
}
|
||||
|
||||
static void swapBuffersOSMesa(_GLFWwindow* window)
|
||||
static void swapBuffersOSMesa(_GLFWwindow* window UNUSED)
|
||||
{
|
||||
// No double buffering on OSMesa
|
||||
}
|
||||
|
||||
static void swapIntervalOSMesa(int interval)
|
||||
static void swapIntervalOSMesa(int interval UNUSED)
|
||||
{
|
||||
// No swap interval on OSMesa
|
||||
}
|
||||
|
||||
static int extensionSupportedOSMesa(const char* extension)
|
||||
static int extensionSupportedOSMesa(const char* extension UNUSED)
|
||||
{
|
||||
// OSMesa does not have extensions
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -108,7 +110,7 @@ static int extensionSupportedOSMesa(const char* extension)
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWbool _glfwInitOSMesa(void)
|
||||
bool _glfwInitOSMesa(void)
|
||||
{
|
||||
int i;
|
||||
const char* sonames[] =
|
||||
@@ -130,7 +132,7 @@ GLFWbool _glfwInitOSMesa(void)
|
||||
};
|
||||
|
||||
if (_glfw.osmesa.handle)
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
|
||||
for (i = 0; sonames[i]; i++)
|
||||
{
|
||||
@@ -142,23 +144,16 @@ GLFWbool _glfwInitOSMesa(void)
|
||||
if (!_glfw.osmesa.handle)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "OSMesa: Library not found");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfw.osmesa.CreateContextExt = (PFN_OSMesaCreateContextExt)
|
||||
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaCreateContextExt");
|
||||
_glfw.osmesa.CreateContextAttribs = (PFN_OSMesaCreateContextAttribs)
|
||||
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaCreateContextAttribs");
|
||||
_glfw.osmesa.DestroyContext = (PFN_OSMesaDestroyContext)
|
||||
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaDestroyContext");
|
||||
_glfw.osmesa.MakeCurrent = (PFN_OSMesaMakeCurrent)
|
||||
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaMakeCurrent");
|
||||
_glfw.osmesa.GetColorBuffer = (PFN_OSMesaGetColorBuffer)
|
||||
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetColorBuffer");
|
||||
_glfw.osmesa.GetDepthBuffer = (PFN_OSMesaGetDepthBuffer)
|
||||
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetDepthBuffer");
|
||||
_glfw.osmesa.GetProcAddress = (PFN_OSMesaGetProcAddress)
|
||||
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetProcAddress");
|
||||
glfw_dlsym(_glfw.osmesa.CreateContextExt, _glfw.osmesa.handle, "OSMesaCreateContextExt");
|
||||
glfw_dlsym(_glfw.osmesa.CreateContextAttribs, _glfw.osmesa.handle, "OSMesaCreateContextAttribs");
|
||||
glfw_dlsym(_glfw.osmesa.DestroyContext, _glfw.osmesa.handle, "OSMesaDestroyContext");
|
||||
glfw_dlsym(_glfw.osmesa.MakeCurrent, _glfw.osmesa.handle, "OSMesaMakeCurrent");
|
||||
glfw_dlsym(_glfw.osmesa.GetColorBuffer, _glfw.osmesa.handle, "OSMesaGetColorBuffer");
|
||||
glfw_dlsym(_glfw.osmesa.GetDepthBuffer, _glfw.osmesa.handle, "OSMesaGetDepthBuffer");
|
||||
glfw_dlsym(_glfw.osmesa.GetProcAddress, _glfw.osmesa.handle, "OSMesaGetProcAddress");
|
||||
|
||||
if (!_glfw.osmesa.CreateContextExt ||
|
||||
!_glfw.osmesa.DestroyContext ||
|
||||
@@ -171,10 +166,10 @@ GLFWbool _glfwInitOSMesa(void)
|
||||
"OSMesa: Failed to load required entry points");
|
||||
|
||||
_glfwTerminateOSMesa();
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwTerminateOSMesa(void)
|
||||
@@ -188,12 +183,12 @@ void _glfwTerminateOSMesa(void)
|
||||
|
||||
#define setAttrib(a, v) \
|
||||
{ \
|
||||
assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
||||
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
||||
attribs[index++] = a; \
|
||||
attribs[index++] = v; \
|
||||
}
|
||||
|
||||
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
bool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
@@ -207,7 +202,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"OSMesa: OpenGL ES is not available on OSMesa");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctxconfig->share)
|
||||
@@ -241,7 +236,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"OSMesa: Forward-compatible contexts not supported");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
setAttrib(0, 0);
|
||||
@@ -255,7 +250,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"OSMesa: OpenGL profiles unavailable");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
window->context.osmesa.handle =
|
||||
@@ -270,7 +265,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"OSMesa: Failed to create context");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
window->context.makeCurrent = makeContextCurrentOSMesa;
|
||||
@@ -280,7 +275,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
window->context.getProcAddress = getProcAddressOSMesa;
|
||||
window->context.destroy = destroyContextOSMesa;
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef setAttrib
|
||||
@@ -298,7 +293,7 @@ GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width,
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(false);
|
||||
|
||||
if (!OSMesaGetColorBuffer(window->context.osmesa.handle,
|
||||
&mesaWidth, &mesaHeight,
|
||||
@@ -306,7 +301,7 @@ GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width,
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"OSMesa: Failed to retrieve color buffer");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (width)
|
||||
@@ -318,7 +313,7 @@ GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width,
|
||||
if (buffer)
|
||||
*buffer = mesaBuffer;
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
|
||||
@@ -331,7 +326,7 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(false);
|
||||
|
||||
if (!OSMesaGetDepthBuffer(window->context.osmesa.handle,
|
||||
&mesaWidth, &mesaHeight,
|
||||
@@ -339,7 +334,7 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"OSMesa: Failed to retrieve depth buffer");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (width)
|
||||
@@ -351,7 +346,7 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
|
||||
if (buffer)
|
||||
*buffer = mesaBuffer;
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle)
|
||||
|
||||
8
glfw/osmesa_context.h
vendored
8
glfw/osmesa_context.h
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 OSMesa - www.glfw.org
|
||||
// GLFW 3.4 OSMesa - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2016 Google Inc.
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -86,9 +86,9 @@ typedef struct _GLFWlibraryOSMesa
|
||||
} _GLFWlibraryOSMesa;
|
||||
|
||||
|
||||
GLFWbool _glfwInitOSMesa(void);
|
||||
bool _glfwInitOSMesa(void);
|
||||
void _glfwTerminateOSMesa(void);
|
||||
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
bool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
|
||||
|
||||
32
glfw/posix_thread.c
vendored
32
glfw/posix_thread.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 POSIX - www.glfw.org
|
||||
// GLFW 3.4 POSIX - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -35,19 +37,19 @@
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls)
|
||||
bool _glfwPlatformCreateTls(_GLFWtls* tls)
|
||||
{
|
||||
assert(tls->posix.allocated == GLFW_FALSE);
|
||||
assert(tls->posix.allocated == false);
|
||||
|
||||
if (pthread_key_create(&tls->posix.key, NULL) != 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"POSIX: Failed to create context TLS");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
tls->posix.allocated = GLFW_TRUE;
|
||||
return GLFW_TRUE;
|
||||
tls->posix.allocated = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwPlatformDestroyTls(_GLFWtls* tls)
|
||||
@@ -59,27 +61,27 @@ void _glfwPlatformDestroyTls(_GLFWtls* tls)
|
||||
|
||||
void* _glfwPlatformGetTls(_GLFWtls* tls)
|
||||
{
|
||||
assert(tls->posix.allocated == GLFW_TRUE);
|
||||
assert(tls->posix.allocated == true);
|
||||
return pthread_getspecific(tls->posix.key);
|
||||
}
|
||||
|
||||
void _glfwPlatformSetTls(_GLFWtls* tls, void* value)
|
||||
{
|
||||
assert(tls->posix.allocated == GLFW_TRUE);
|
||||
assert(tls->posix.allocated == true);
|
||||
pthread_setspecific(tls->posix.key, value);
|
||||
}
|
||||
|
||||
GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex)
|
||||
bool _glfwPlatformCreateMutex(_GLFWmutex* mutex)
|
||||
{
|
||||
assert(mutex->posix.allocated == GLFW_FALSE);
|
||||
assert(mutex->posix.allocated == false);
|
||||
|
||||
if (pthread_mutex_init(&mutex->posix.handle, NULL) != 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "POSIX: Failed to create mutex");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
return mutex->posix.allocated = GLFW_TRUE;
|
||||
return mutex->posix.allocated = true;
|
||||
}
|
||||
|
||||
void _glfwPlatformDestroyMutex(_GLFWmutex* mutex)
|
||||
@@ -91,13 +93,13 @@ void _glfwPlatformDestroyMutex(_GLFWmutex* mutex)
|
||||
|
||||
void _glfwPlatformLockMutex(_GLFWmutex* mutex)
|
||||
{
|
||||
assert(mutex->posix.allocated == GLFW_TRUE);
|
||||
assert(mutex->posix.allocated == true);
|
||||
pthread_mutex_lock(&mutex->posix.handle);
|
||||
}
|
||||
|
||||
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex)
|
||||
{
|
||||
assert(mutex->posix.allocated == GLFW_TRUE);
|
||||
assert(mutex->posix.allocated == true);
|
||||
pthread_mutex_unlock(&mutex->posix.handle);
|
||||
}
|
||||
|
||||
|
||||
8
glfw/posix_thread.h
vendored
8
glfw/posix_thread.h
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 POSIX - www.glfw.org
|
||||
// GLFW 3.4 POSIX - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -35,7 +35,7 @@
|
||||
//
|
||||
typedef struct _GLFWtlsPOSIX
|
||||
{
|
||||
GLFWbool allocated;
|
||||
bool allocated;
|
||||
pthread_key_t key;
|
||||
|
||||
} _GLFWtlsPOSIX;
|
||||
@@ -44,7 +44,7 @@ typedef struct _GLFWtlsPOSIX
|
||||
//
|
||||
typedef struct _GLFWmutexPOSIX
|
||||
{
|
||||
GLFWbool allocated;
|
||||
bool allocated;
|
||||
pthread_mutex_t handle;
|
||||
|
||||
} _GLFWmutexPOSIX;
|
||||
|
||||
10
glfw/posix_time.c
vendored
10
glfw/posix_time.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 POSIX - www.glfw.org
|
||||
// GLFW 3.4 POSIX - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -44,13 +46,13 @@ void _glfwInitTimerPOSIX(void)
|
||||
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
|
||||
{
|
||||
_glfw.timer.posix.monotonic = GLFW_TRUE;
|
||||
_glfw.timer.posix.monotonic = true;
|
||||
_glfw.timer.posix.frequency = 1000000000;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
_glfw.timer.posix.monotonic = GLFW_FALSE;
|
||||
_glfw.timer.posix.monotonic = false;
|
||||
_glfw.timer.posix.frequency = 1000000;
|
||||
}
|
||||
}
|
||||
|
||||
6
glfw/posix_time.h
vendored
6
glfw/posix_time.h
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 POSIX - www.glfw.org
|
||||
// GLFW 3.4 POSIX - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -34,7 +34,7 @@
|
||||
//
|
||||
typedef struct _GLFWtimerPOSIX
|
||||
{
|
||||
GLFWbool monotonic;
|
||||
bool monotonic;
|
||||
uint64_t frequency;
|
||||
|
||||
} _GLFWtimerPOSIX;
|
||||
|
||||
48
glfw/vulkan.c
vendored
48
glfw/vulkan.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// Please use C89 style variable declarations in this file because VS 2010
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -39,14 +41,14 @@
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWbool _glfwInitVulkan(int mode)
|
||||
bool _glfwInitVulkan(int mode)
|
||||
{
|
||||
VkResult err;
|
||||
VkExtensionProperties* ep;
|
||||
uint32_t i, count;
|
||||
|
||||
if (_glfw.vk.available)
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
|
||||
#if !defined(_GLFW_VULKAN_STATIC)
|
||||
#if defined(_GLFW_VULKAN_LIBRARY)
|
||||
@@ -63,10 +65,10 @@ GLFWbool _glfwInitVulkan(int mode)
|
||||
if (mode == _GLFW_REQUIRE_LOADER)
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found");
|
||||
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)
|
||||
*(void **) &_glfw.vk.GetInstanceProcAddr =
|
||||
_glfw_dlsym(_glfw.vk.handle, "vkGetInstanceProcAddr");
|
||||
if (!_glfw.vk.GetInstanceProcAddr)
|
||||
{
|
||||
@@ -74,7 +76,7 @@ GLFWbool _glfwInitVulkan(int mode)
|
||||
"Vulkan: Loader does not export vkGetInstanceProcAddr");
|
||||
|
||||
_glfwTerminateVulkan();
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfw.vk.EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)
|
||||
@@ -85,7 +87,7 @@ GLFWbool _glfwInitVulkan(int mode)
|
||||
"Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties");
|
||||
|
||||
_glfwTerminateVulkan();
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
#endif // _GLFW_VULKAN_STATIC
|
||||
|
||||
@@ -101,7 +103,7 @@ GLFWbool _glfwInitVulkan(int mode)
|
||||
}
|
||||
|
||||
_glfwTerminateVulkan();
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
ep = calloc(count, sizeof(VkExtensionProperties));
|
||||
@@ -115,37 +117,37 @@ GLFWbool _glfwInitVulkan(int mode)
|
||||
|
||||
free(ep);
|
||||
_glfwTerminateVulkan();
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (strcmp(ep[i].extensionName, "VK_KHR_surface") == 0)
|
||||
_glfw.vk.KHR_surface = GLFW_TRUE;
|
||||
_glfw.vk.KHR_surface = true;
|
||||
#if defined(_GLFW_WIN32)
|
||||
else if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0)
|
||||
_glfw.vk.KHR_win32_surface = GLFW_TRUE;
|
||||
_glfw.vk.KHR_win32_surface = true;
|
||||
#elif defined(_GLFW_COCOA)
|
||||
else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0)
|
||||
_glfw.vk.MVK_macos_surface = GLFW_TRUE;
|
||||
_glfw.vk.MVK_macos_surface = true;
|
||||
#elif defined(_GLFW_X11)
|
||||
else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0)
|
||||
_glfw.vk.KHR_xlib_surface = GLFW_TRUE;
|
||||
_glfw.vk.KHR_xlib_surface = true;
|
||||
else if (strcmp(ep[i].extensionName, "VK_KHR_xcb_surface") == 0)
|
||||
_glfw.vk.KHR_xcb_surface = GLFW_TRUE;
|
||||
_glfw.vk.KHR_xcb_surface = true;
|
||||
#elif defined(_GLFW_WAYLAND)
|
||||
else if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0)
|
||||
_glfw.vk.KHR_wayland_surface = GLFW_TRUE;
|
||||
_glfw.vk.KHR_wayland_surface = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
free(ep);
|
||||
|
||||
_glfw.vk.available = GLFW_TRUE;
|
||||
_glfw.vk.available = true;
|
||||
|
||||
_glfwPlatformGetRequiredInstanceExtensions(_glfw.vk.extensions);
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwTerminateVulkan(void)
|
||||
@@ -218,7 +220,7 @@ const char* _glfwGetVulkanResultString(VkResult result)
|
||||
|
||||
GLFWAPI int glfwVulkanSupported(void)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(false);
|
||||
return _glfwInitVulkan(_GLFW_FIND_LOADER);
|
||||
}
|
||||
|
||||
@@ -260,7 +262,7 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance,
|
||||
}
|
||||
#else
|
||||
if (!proc)
|
||||
proc = (GLFWvkproc) _glfw_dlsym(_glfw.vk.handle, procname);
|
||||
*(void **) &proc = _glfw_dlsym(_glfw.vk.handle, procname);
|
||||
#endif
|
||||
|
||||
return proc;
|
||||
@@ -273,16 +275,16 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance,
|
||||
assert(instance != VK_NULL_HANDLE);
|
||||
assert(device != VK_NULL_HANDLE);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(false);
|
||||
|
||||
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
if (!_glfw.vk.extensions[0])
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"Vulkan: Window surface creation extensions not found");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
return _glfwPlatformGetPhysicalDevicePresentationSupport(instance,
|
||||
|
||||
743
glfw/wgl_context.c
vendored
743
glfw/wgl_context.c
vendored
@@ -1,743 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 WGL - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
// Returns the specified attribute of the specified pixel format
|
||||
//
|
||||
static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib)
|
||||
{
|
||||
int value = 0;
|
||||
|
||||
assert(_glfw.wgl.ARB_pixel_format);
|
||||
|
||||
if (!_glfw.wgl.GetPixelFormatAttribivARB(window->context.wgl.dc,
|
||||
pixelFormat,
|
||||
0, 1, &attrib, &value))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to retrieve pixel format attribute");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// Return a list of available and usable framebuffer configs
|
||||
//
|
||||
static int choosePixelFormat(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
_GLFWfbconfig* usableConfigs;
|
||||
const _GLFWfbconfig* closest;
|
||||
int i, pixelFormat, nativeCount, usableCount;
|
||||
|
||||
if (_glfw.wgl.ARB_pixel_format)
|
||||
{
|
||||
nativeCount = getPixelFormatAttrib(window,
|
||||
1,
|
||||
WGL_NUMBER_PIXEL_FORMATS_ARB);
|
||||
}
|
||||
else
|
||||
{
|
||||
nativeCount = DescribePixelFormat(window->context.wgl.dc,
|
||||
1,
|
||||
sizeof(PIXELFORMATDESCRIPTOR),
|
||||
NULL);
|
||||
}
|
||||
|
||||
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
|
||||
usableCount = 0;
|
||||
|
||||
for (i = 0; i < nativeCount; i++)
|
||||
{
|
||||
const int n = i + 1;
|
||||
_GLFWfbconfig* u = usableConfigs + usableCount;
|
||||
|
||||
if (_glfw.wgl.ARB_pixel_format)
|
||||
{
|
||||
// Get pixel format attributes through "modern" extension
|
||||
|
||||
if (!getPixelFormatAttrib(window, n, WGL_SUPPORT_OPENGL_ARB) ||
|
||||
!getPixelFormatAttrib(window, n, WGL_DRAW_TO_WINDOW_ARB))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (getPixelFormatAttrib(window, n, WGL_PIXEL_TYPE_ARB) !=
|
||||
WGL_TYPE_RGBA_ARB)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (getPixelFormatAttrib(window, n, WGL_ACCELERATION_ARB) ==
|
||||
WGL_NO_ACCELERATION_ARB)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
u->redBits = getPixelFormatAttrib(window, n, WGL_RED_BITS_ARB);
|
||||
u->greenBits = getPixelFormatAttrib(window, n, WGL_GREEN_BITS_ARB);
|
||||
u->blueBits = getPixelFormatAttrib(window, n, WGL_BLUE_BITS_ARB);
|
||||
u->alphaBits = getPixelFormatAttrib(window, n, WGL_ALPHA_BITS_ARB);
|
||||
|
||||
u->depthBits = getPixelFormatAttrib(window, n, WGL_DEPTH_BITS_ARB);
|
||||
u->stencilBits = getPixelFormatAttrib(window, n, WGL_STENCIL_BITS_ARB);
|
||||
|
||||
u->accumRedBits = getPixelFormatAttrib(window, n, WGL_ACCUM_RED_BITS_ARB);
|
||||
u->accumGreenBits = getPixelFormatAttrib(window, n, WGL_ACCUM_GREEN_BITS_ARB);
|
||||
u->accumBlueBits = getPixelFormatAttrib(window, n, WGL_ACCUM_BLUE_BITS_ARB);
|
||||
u->accumAlphaBits = getPixelFormatAttrib(window, n, WGL_ACCUM_ALPHA_BITS_ARB);
|
||||
|
||||
u->auxBuffers = getPixelFormatAttrib(window, n, WGL_AUX_BUFFERS_ARB);
|
||||
|
||||
if (getPixelFormatAttrib(window, n, WGL_STEREO_ARB))
|
||||
u->stereo = GLFW_TRUE;
|
||||
if (getPixelFormatAttrib(window, n, WGL_DOUBLE_BUFFER_ARB))
|
||||
u->doublebuffer = GLFW_TRUE;
|
||||
|
||||
if (_glfw.wgl.ARB_multisample)
|
||||
u->samples = getPixelFormatAttrib(window, n, WGL_SAMPLES_ARB);
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||
{
|
||||
if (_glfw.wgl.ARB_framebuffer_sRGB ||
|
||||
_glfw.wgl.EXT_framebuffer_sRGB)
|
||||
{
|
||||
if (getPixelFormatAttrib(window, n, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB))
|
||||
u->sRGB = GLFW_TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_glfw.wgl.EXT_colorspace)
|
||||
{
|
||||
if (getPixelFormatAttrib(window, n, WGL_COLORSPACE_EXT) ==
|
||||
WGL_COLORSPACE_SRGB_EXT)
|
||||
{
|
||||
u->sRGB = GLFW_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get pixel format attributes through legacy PFDs
|
||||
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
|
||||
if (!DescribePixelFormat(window->context.wgl.dc,
|
||||
n,
|
||||
sizeof(PIXELFORMATDESCRIPTOR),
|
||||
&pfd))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(pfd.dwFlags & PFD_DRAW_TO_WINDOW) ||
|
||||
!(pfd.dwFlags & PFD_SUPPORT_OPENGL))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) &&
|
||||
(pfd.dwFlags & PFD_GENERIC_FORMAT))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pfd.iPixelType != PFD_TYPE_RGBA)
|
||||
continue;
|
||||
|
||||
u->redBits = pfd.cRedBits;
|
||||
u->greenBits = pfd.cGreenBits;
|
||||
u->blueBits = pfd.cBlueBits;
|
||||
u->alphaBits = pfd.cAlphaBits;
|
||||
|
||||
u->depthBits = pfd.cDepthBits;
|
||||
u->stencilBits = pfd.cStencilBits;
|
||||
|
||||
u->accumRedBits = pfd.cAccumRedBits;
|
||||
u->accumGreenBits = pfd.cAccumGreenBits;
|
||||
u->accumBlueBits = pfd.cAccumBlueBits;
|
||||
u->accumAlphaBits = pfd.cAccumAlphaBits;
|
||||
|
||||
u->auxBuffers = pfd.cAuxBuffers;
|
||||
|
||||
if (pfd.dwFlags & PFD_STEREO)
|
||||
u->stereo = GLFW_TRUE;
|
||||
if (pfd.dwFlags & PFD_DOUBLEBUFFER)
|
||||
u->doublebuffer = GLFW_TRUE;
|
||||
}
|
||||
|
||||
u->handle = n;
|
||||
usableCount++;
|
||||
}
|
||||
|
||||
if (!usableCount)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"WGL: The driver does not appear to support OpenGL");
|
||||
|
||||
free(usableConfigs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
closest = _glfwChooseFBConfig(fbconfig, usableConfigs, usableCount);
|
||||
if (!closest)
|
||||
{
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||
"WGL: Failed to find a suitable pixel format");
|
||||
|
||||
free(usableConfigs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pixelFormat = (int) closest->handle;
|
||||
free(usableConfigs);
|
||||
|
||||
return pixelFormat;
|
||||
}
|
||||
|
||||
static void makeContextCurrentWGL(_GLFWwindow* window)
|
||||
{
|
||||
if (window)
|
||||
{
|
||||
if (wglMakeCurrent(window->context.wgl.dc, window->context.wgl.handle))
|
||||
_glfwPlatformSetTls(&_glfw.contextSlot, window);
|
||||
else
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to make context current");
|
||||
_glfwPlatformSetTls(&_glfw.contextSlot, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!wglMakeCurrent(NULL, NULL))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to clear current context");
|
||||
}
|
||||
|
||||
_glfwPlatformSetTls(&_glfw.contextSlot, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void swapBuffersWGL(_GLFWwindow* window)
|
||||
{
|
||||
if (!window->monitor)
|
||||
{
|
||||
if (IsWindowsVistaOrGreater())
|
||||
{
|
||||
BOOL enabled;
|
||||
|
||||
// HACK: Use DwmFlush when desktop composition is enabled
|
||||
if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)
|
||||
{
|
||||
int count = abs(window->context.wgl.interval);
|
||||
while (count--)
|
||||
DwmFlush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SwapBuffers(window->context.wgl.dc);
|
||||
}
|
||||
|
||||
static void swapIntervalWGL(int interval)
|
||||
{
|
||||
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||
|
||||
window->context.wgl.interval = interval;
|
||||
|
||||
if (!window->monitor)
|
||||
{
|
||||
if (IsWindowsVistaOrGreater())
|
||||
{
|
||||
BOOL enabled;
|
||||
|
||||
// HACK: Disable WGL swap interval when desktop composition is enabled to
|
||||
// avoid interfering with DWM vsync
|
||||
if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)
|
||||
interval = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (_glfw.wgl.EXT_swap_control)
|
||||
_glfw.wgl.SwapIntervalEXT(interval);
|
||||
}
|
||||
|
||||
static int extensionSupportedWGL(const char* extension)
|
||||
{
|
||||
const char* extensions;
|
||||
|
||||
if (_glfw.wgl.GetExtensionsStringEXT)
|
||||
{
|
||||
extensions = _glfw.wgl.GetExtensionsStringEXT();
|
||||
if (extensions)
|
||||
{
|
||||
if (_glfwStringInExtensionString(extension, extensions))
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (_glfw.wgl.GetExtensionsStringARB)
|
||||
{
|
||||
extensions = _glfw.wgl.GetExtensionsStringARB(wglGetCurrentDC());
|
||||
if (extensions)
|
||||
{
|
||||
if (_glfwStringInExtensionString(extension, extensions))
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
static GLFWglproc getProcAddressWGL(const char* procname)
|
||||
{
|
||||
const GLFWglproc proc = (GLFWglproc) wglGetProcAddress(procname);
|
||||
if (proc)
|
||||
return proc;
|
||||
|
||||
return (GLFWglproc) GetProcAddress(_glfw.wgl.instance, procname);
|
||||
}
|
||||
|
||||
// Destroy the OpenGL context
|
||||
//
|
||||
static void destroyContextWGL(_GLFWwindow* window)
|
||||
{
|
||||
if (window->context.wgl.handle)
|
||||
{
|
||||
wglDeleteContext(window->context.wgl.handle);
|
||||
window->context.wgl.handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Initialize WGL
|
||||
//
|
||||
GLFWbool _glfwInitWGL(void)
|
||||
{
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
HGLRC prc, rc;
|
||||
HDC pdc, dc;
|
||||
|
||||
if (_glfw.wgl.instance)
|
||||
return GLFW_TRUE;
|
||||
|
||||
_glfw.wgl.instance = LoadLibraryA("opengl32.dll");
|
||||
if (!_glfw.wgl.instance)
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to load opengl32.dll");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_glfw.wgl.CreateContext = (PFN_wglCreateContext)
|
||||
GetProcAddress(_glfw.wgl.instance, "wglCreateContext");
|
||||
_glfw.wgl.DeleteContext = (PFN_wglDeleteContext)
|
||||
GetProcAddress(_glfw.wgl.instance, "wglDeleteContext");
|
||||
_glfw.wgl.GetProcAddress = (PFN_wglGetProcAddress)
|
||||
GetProcAddress(_glfw.wgl.instance, "wglGetProcAddress");
|
||||
_glfw.wgl.GetCurrentDC = (PFN_wglGetCurrentDC)
|
||||
GetProcAddress(_glfw.wgl.instance, "wglGetCurrentDC");
|
||||
_glfw.wgl.GetCurrentContext = (PFN_wglGetCurrentContext)
|
||||
GetProcAddress(_glfw.wgl.instance, "wglGetCurrentContext");
|
||||
_glfw.wgl.MakeCurrent = (PFN_wglMakeCurrent)
|
||||
GetProcAddress(_glfw.wgl.instance, "wglMakeCurrent");
|
||||
_glfw.wgl.ShareLists = (PFN_wglShareLists)
|
||||
GetProcAddress(_glfw.wgl.instance, "wglShareLists");
|
||||
|
||||
// NOTE: A dummy context has to be created for opengl32.dll to load the
|
||||
// OpenGL ICD, from which we can then query WGL extensions
|
||||
// NOTE: This code will accept the Microsoft GDI ICD; accelerated context
|
||||
// creation failure occurs during manual pixel format enumeration
|
||||
|
||||
dc = GetDC(_glfw.win32.helperWindowHandle);
|
||||
|
||||
ZeroMemory(&pfd, sizeof(pfd));
|
||||
pfd.nSize = sizeof(pfd);
|
||||
pfd.nVersion = 1;
|
||||
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
||||
pfd.iPixelType = PFD_TYPE_RGBA;
|
||||
pfd.cColorBits = 24;
|
||||
|
||||
if (!SetPixelFormat(dc, ChoosePixelFormat(dc, &pfd), &pfd))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to set pixel format for dummy context");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
rc = wglCreateContext(dc);
|
||||
if (!rc)
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to create dummy context");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
pdc = wglGetCurrentDC();
|
||||
prc = wglGetCurrentContext();
|
||||
|
||||
if (!wglMakeCurrent(dc, rc))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to make dummy context current");
|
||||
wglMakeCurrent(pdc, prc);
|
||||
wglDeleteContext(rc);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
// NOTE: Functions must be loaded first as they're needed to retrieve the
|
||||
// extension string that tells us whether the functions are supported
|
||||
_glfw.wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)
|
||||
wglGetProcAddress("wglGetExtensionsStringEXT");
|
||||
_glfw.wgl.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)
|
||||
wglGetProcAddress("wglGetExtensionsStringARB");
|
||||
_glfw.wgl.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)
|
||||
wglGetProcAddress("wglCreateContextAttribsARB");
|
||||
_glfw.wgl.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)
|
||||
wglGetProcAddress("wglSwapIntervalEXT");
|
||||
_glfw.wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)
|
||||
wglGetProcAddress("wglGetPixelFormatAttribivARB");
|
||||
|
||||
// NOTE: WGL_ARB_extensions_string and WGL_EXT_extensions_string are not
|
||||
// checked below as we are already using them
|
||||
_glfw.wgl.ARB_multisample =
|
||||
extensionSupportedWGL("WGL_ARB_multisample");
|
||||
_glfw.wgl.ARB_framebuffer_sRGB =
|
||||
extensionSupportedWGL("WGL_ARB_framebuffer_sRGB");
|
||||
_glfw.wgl.EXT_framebuffer_sRGB =
|
||||
extensionSupportedWGL("WGL_EXT_framebuffer_sRGB");
|
||||
_glfw.wgl.ARB_create_context =
|
||||
extensionSupportedWGL("WGL_ARB_create_context");
|
||||
_glfw.wgl.ARB_create_context_profile =
|
||||
extensionSupportedWGL("WGL_ARB_create_context_profile");
|
||||
_glfw.wgl.EXT_create_context_es2_profile =
|
||||
extensionSupportedWGL("WGL_EXT_create_context_es2_profile");
|
||||
_glfw.wgl.ARB_create_context_robustness =
|
||||
extensionSupportedWGL("WGL_ARB_create_context_robustness");
|
||||
_glfw.wgl.ARB_create_context_no_error =
|
||||
extensionSupportedWGL("WGL_ARB_create_context_no_error");
|
||||
_glfw.wgl.EXT_swap_control =
|
||||
extensionSupportedWGL("WGL_EXT_swap_control");
|
||||
_glfw.wgl.EXT_colorspace =
|
||||
extensionSupportedWGL("WGL_EXT_colorspace");
|
||||
_glfw.wgl.ARB_pixel_format =
|
||||
extensionSupportedWGL("WGL_ARB_pixel_format");
|
||||
_glfw.wgl.ARB_context_flush_control =
|
||||
extensionSupportedWGL("WGL_ARB_context_flush_control");
|
||||
|
||||
wglMakeCurrent(pdc, prc);
|
||||
wglDeleteContext(rc);
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
// Terminate WGL
|
||||
//
|
||||
void _glfwTerminateWGL(void)
|
||||
{
|
||||
if (_glfw.wgl.instance)
|
||||
FreeLibrary(_glfw.wgl.instance);
|
||||
}
|
||||
|
||||
#define setAttrib(a, v) \
|
||||
{ \
|
||||
assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
||||
attribs[index++] = a; \
|
||||
attribs[index++] = v; \
|
||||
}
|
||||
|
||||
// Create the OpenGL or OpenGL ES context
|
||||
//
|
||||
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
int attribs[40];
|
||||
int pixelFormat;
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
HGLRC share = NULL;
|
||||
|
||||
if (ctxconfig->share)
|
||||
share = ctxconfig->share->context.wgl.handle;
|
||||
|
||||
window->context.wgl.dc = GetDC(window->win32.handle);
|
||||
if (!window->context.wgl.dc)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to retrieve DC for window");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
pixelFormat = choosePixelFormat(window, ctxconfig, fbconfig);
|
||||
if (!pixelFormat)
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (!DescribePixelFormat(window->context.wgl.dc,
|
||||
pixelFormat, sizeof(pfd), &pfd))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to retrieve PFD for selected pixel format");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (!SetPixelFormat(window->context.wgl.dc, pixelFormat, &pfd))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to set selected pixel format");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||
{
|
||||
if (ctxconfig->forward)
|
||||
{
|
||||
if (!_glfw.wgl.ARB_create_context)
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: A forward compatible OpenGL context requested but WGL_ARB_create_context is unavailable");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctxconfig->profile)
|
||||
{
|
||||
if (!_glfw.wgl.ARB_create_context_profile)
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: OpenGL profile requested but WGL_ARB_create_context_profile is unavailable");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_glfw.wgl.ARB_create_context ||
|
||||
!_glfw.wgl.ARB_create_context_profile ||
|
||||
!_glfw.wgl.EXT_create_context_es2_profile)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"WGL: OpenGL ES requested but WGL_ARB_create_context_es2_profile is unavailable");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (_glfw.wgl.ARB_create_context)
|
||||
{
|
||||
int index = 0, mask = 0, flags = 0;
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||
{
|
||||
if (ctxconfig->forward)
|
||||
flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
|
||||
|
||||
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
|
||||
mask |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
|
||||
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
|
||||
mask |= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
|
||||
}
|
||||
else
|
||||
mask |= WGL_CONTEXT_ES2_PROFILE_BIT_EXT;
|
||||
|
||||
if (ctxconfig->debug)
|
||||
flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
|
||||
|
||||
if (ctxconfig->robustness)
|
||||
{
|
||||
if (_glfw.wgl.ARB_create_context_robustness)
|
||||
{
|
||||
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
|
||||
{
|
||||
setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||
WGL_NO_RESET_NOTIFICATION_ARB);
|
||||
}
|
||||
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
|
||||
{
|
||||
setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||
WGL_LOSE_CONTEXT_ON_RESET_ARB);
|
||||
}
|
||||
|
||||
flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctxconfig->release)
|
||||
{
|
||||
if (_glfw.wgl.ARB_context_flush_control)
|
||||
{
|
||||
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
|
||||
{
|
||||
setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
||||
WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
|
||||
}
|
||||
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
|
||||
{
|
||||
setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
||||
WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ctxconfig->noerror)
|
||||
{
|
||||
if (_glfw.wgl.ARB_create_context_no_error)
|
||||
setAttrib(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
|
||||
}
|
||||
|
||||
// NOTE: Only request an explicitly versioned context when necessary, as
|
||||
// explicitly requesting version 1.0 does not always return the
|
||||
// highest version supported by the driver
|
||||
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
||||
{
|
||||
setAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
|
||||
setAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
|
||||
}
|
||||
|
||||
if (flags)
|
||||
setAttrib(WGL_CONTEXT_FLAGS_ARB, flags);
|
||||
|
||||
if (mask)
|
||||
setAttrib(WGL_CONTEXT_PROFILE_MASK_ARB, mask);
|
||||
|
||||
setAttrib(0, 0);
|
||||
|
||||
window->context.wgl.handle =
|
||||
_glfw.wgl.CreateContextAttribsARB(window->context.wgl.dc,
|
||||
share, attribs);
|
||||
if (!window->context.wgl.handle)
|
||||
{
|
||||
const DWORD error = GetLastError();
|
||||
|
||||
if (error == (0xc0070000 | ERROR_INVALID_VERSION_ARB))
|
||||
{
|
||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: Driver does not support OpenGL version %i.%i",
|
||||
ctxconfig->major,
|
||||
ctxconfig->minor);
|
||||
}
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: Driver does not support OpenGL ES version %i.%i",
|
||||
ctxconfig->major,
|
||||
ctxconfig->minor);
|
||||
}
|
||||
}
|
||||
else if (error == (0xc0070000 | ERROR_INVALID_PROFILE_ARB))
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: Driver does not support the requested OpenGL profile");
|
||||
}
|
||||
else if (error == (0xc0070000 | ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB))
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE,
|
||||
"WGL: The share context is not compatible with the requested context");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: Failed to create OpenGL context");
|
||||
}
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: Failed to create OpenGL ES context");
|
||||
}
|
||||
}
|
||||
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
window->context.wgl.handle = wglCreateContext(window->context.wgl.dc);
|
||||
if (!window->context.wgl.handle)
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: Failed to create OpenGL context");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (share)
|
||||
{
|
||||
if (!wglShareLists(share, window->context.wgl.handle))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to enable sharing with specified OpenGL context");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window->context.makeCurrent = makeContextCurrentWGL;
|
||||
window->context.swapBuffers = swapBuffersWGL;
|
||||
window->context.swapInterval = swapIntervalWGL;
|
||||
window->context.extensionSupported = extensionSupportedWGL;
|
||||
window->context.getProcAddress = getProcAddressWGL;
|
||||
window->context.destroy = destroyContextWGL;
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
#undef setAttrib
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW native API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
if (window->context.client == GLFW_NO_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return window->context.wgl.handle;
|
||||
}
|
||||
159
glfw/wgl_context.h
vendored
159
glfw/wgl_context.h
vendored
@@ -1,159 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 WGL - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
|
||||
#define WGL_SUPPORT_OPENGL_ARB 0x2010
|
||||
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
|
||||
#define WGL_PIXEL_TYPE_ARB 0x2013
|
||||
#define WGL_TYPE_RGBA_ARB 0x202b
|
||||
#define WGL_ACCELERATION_ARB 0x2003
|
||||
#define WGL_NO_ACCELERATION_ARB 0x2025
|
||||
#define WGL_RED_BITS_ARB 0x2015
|
||||
#define WGL_RED_SHIFT_ARB 0x2016
|
||||
#define WGL_GREEN_BITS_ARB 0x2017
|
||||
#define WGL_GREEN_SHIFT_ARB 0x2018
|
||||
#define WGL_BLUE_BITS_ARB 0x2019
|
||||
#define WGL_BLUE_SHIFT_ARB 0x201a
|
||||
#define WGL_ALPHA_BITS_ARB 0x201b
|
||||
#define WGL_ALPHA_SHIFT_ARB 0x201c
|
||||
#define WGL_ACCUM_BITS_ARB 0x201d
|
||||
#define WGL_ACCUM_RED_BITS_ARB 0x201e
|
||||
#define WGL_ACCUM_GREEN_BITS_ARB 0x201f
|
||||
#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
|
||||
#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
|
||||
#define WGL_DEPTH_BITS_ARB 0x2022
|
||||
#define WGL_STENCIL_BITS_ARB 0x2023
|
||||
#define WGL_AUX_BUFFERS_ARB 0x2024
|
||||
#define WGL_STEREO_ARB 0x2012
|
||||
#define WGL_DOUBLE_BUFFER_ARB 0x2011
|
||||
#define WGL_SAMPLES_ARB 0x2042
|
||||
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20a9
|
||||
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
|
||||
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
|
||||
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
|
||||
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
|
||||
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
|
||||
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
|
||||
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
|
||||
#define WGL_CONTEXT_FLAGS_ARB 0x2094
|
||||
#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
|
||||
#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
|
||||
#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
|
||||
#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
|
||||
#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
|
||||
#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
|
||||
#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
|
||||
#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
|
||||
#define WGL_CONTEXT_OPENGL_NO_ERROR_ARB 0x31b3
|
||||
#define WGL_COLORSPACE_EXT 0x309d
|
||||
#define WGL_COLORSPACE_SRGB_EXT 0x3089
|
||||
|
||||
#define ERROR_INVALID_VERSION_ARB 0x2095
|
||||
#define ERROR_INVALID_PROFILE_ARB 0x2096
|
||||
#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
|
||||
|
||||
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC)(int);
|
||||
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC)(HDC,int,int,UINT,const int*,int*);
|
||||
typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC)(void);
|
||||
typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC);
|
||||
typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC,HGLRC,const int*);
|
||||
|
||||
typedef HGLRC (WINAPI * PFN_wglCreateContext)(HDC);
|
||||
typedef BOOL (WINAPI * PFN_wglDeleteContext)(HGLRC);
|
||||
typedef PROC (WINAPI * PFN_wglGetProcAddress)(LPCSTR);
|
||||
typedef HDC (WINAPI * PFN_wglGetCurrentDC)(void);
|
||||
typedef HGLRC (WINAPI * PFN_wglGetCurrentContext)(void);
|
||||
typedef BOOL (WINAPI * PFN_wglMakeCurrent)(HDC,HGLRC);
|
||||
typedef BOOL (WINAPI * PFN_wglShareLists)(HGLRC,HGLRC);
|
||||
|
||||
// opengl32.dll function pointer typedefs
|
||||
#define wglCreateContext _glfw.wgl.CreateContext
|
||||
#define wglDeleteContext _glfw.wgl.DeleteContext
|
||||
#define wglGetProcAddress _glfw.wgl.GetProcAddress
|
||||
#define wglGetCurrentDC _glfw.wgl.GetCurrentDC
|
||||
#define wglGetCurrentContext _glfw.wgl.GetCurrentContext
|
||||
#define wglMakeCurrent _glfw.wgl.MakeCurrent
|
||||
#define wglShareLists _glfw.wgl.ShareLists
|
||||
|
||||
#define _GLFW_RECREATION_NOT_NEEDED 0
|
||||
#define _GLFW_RECREATION_REQUIRED 1
|
||||
#define _GLFW_RECREATION_IMPOSSIBLE 2
|
||||
|
||||
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextWGL wgl
|
||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryWGL wgl
|
||||
|
||||
|
||||
// WGL-specific per-context data
|
||||
//
|
||||
typedef struct _GLFWcontextWGL
|
||||
{
|
||||
HDC dc;
|
||||
HGLRC handle;
|
||||
int interval;
|
||||
|
||||
} _GLFWcontextWGL;
|
||||
|
||||
// WGL-specific global data
|
||||
//
|
||||
typedef struct _GLFWlibraryWGL
|
||||
{
|
||||
HINSTANCE instance;
|
||||
PFN_wglCreateContext CreateContext;
|
||||
PFN_wglDeleteContext DeleteContext;
|
||||
PFN_wglGetProcAddress GetProcAddress;
|
||||
PFN_wglGetCurrentDC GetCurrentDC;
|
||||
PFN_wglGetCurrentContext GetCurrentContext;
|
||||
PFN_wglMakeCurrent MakeCurrent;
|
||||
PFN_wglShareLists ShareLists;
|
||||
|
||||
PFNWGLSWAPINTERVALEXTPROC SwapIntervalEXT;
|
||||
PFNWGLGETPIXELFORMATATTRIBIVARBPROC GetPixelFormatAttribivARB;
|
||||
PFNWGLGETEXTENSIONSSTRINGEXTPROC GetExtensionsStringEXT;
|
||||
PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB;
|
||||
PFNWGLCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
|
||||
GLFWbool EXT_swap_control;
|
||||
GLFWbool EXT_colorspace;
|
||||
GLFWbool ARB_multisample;
|
||||
GLFWbool ARB_framebuffer_sRGB;
|
||||
GLFWbool EXT_framebuffer_sRGB;
|
||||
GLFWbool ARB_pixel_format;
|
||||
GLFWbool ARB_create_context;
|
||||
GLFWbool ARB_create_context_profile;
|
||||
GLFWbool EXT_create_context_es2_profile;
|
||||
GLFWbool ARB_create_context_robustness;
|
||||
GLFWbool ARB_create_context_no_error;
|
||||
GLFWbool ARB_context_flush_control;
|
||||
|
||||
} _GLFWlibraryWGL;
|
||||
|
||||
|
||||
GLFWbool _glfwInitWGL(void);
|
||||
void _glfwTerminateWGL(void);
|
||||
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
|
||||
80
glfw/window.c
vendored
80
glfw/window.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
@@ -25,6 +25,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// Please use C89 style variable declarations in this file because VS 2010
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -40,7 +42,7 @@
|
||||
|
||||
// Notifies shared code that a window has lost or received input focus
|
||||
//
|
||||
void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused)
|
||||
void _glfwInputWindowFocus(_GLFWwindow* window, bool focused)
|
||||
{
|
||||
if (window->callbacks.focus)
|
||||
window->callbacks.focus((GLFWwindow*) window, focused);
|
||||
@@ -82,7 +84,7 @@ _GLFWwindow* _glfwFocusedWindow() {
|
||||
_GLFWwindow* _glfwWindowForId(GLFWid id) {
|
||||
_GLFWwindow *w = _glfw.windowListHead;
|
||||
while (w) {
|
||||
if (w->id == _glfw.focusedWindowId) return w;
|
||||
if (w->id == id) return w;
|
||||
w = w->next;
|
||||
}
|
||||
return NULL;
|
||||
@@ -90,7 +92,7 @@ _GLFWwindow* _glfwWindowForId(GLFWid id) {
|
||||
|
||||
// Notifies shared code that a window's occlusion state has changed
|
||||
//
|
||||
void _glfwInputWindowOcclusion(_GLFWwindow* window, GLFWbool occluded)
|
||||
void _glfwInputWindowOcclusion(_GLFWwindow* window, bool occluded)
|
||||
{
|
||||
if (window->callbacks.occlusion)
|
||||
window->callbacks.occlusion((GLFWwindow*) window, occluded);
|
||||
@@ -116,7 +118,7 @@ void _glfwInputWindowSize(_GLFWwindow* window, int width, int height)
|
||||
|
||||
// Notifies shared code that a window has been iconified or restored
|
||||
//
|
||||
void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified)
|
||||
void _glfwInputWindowIconify(_GLFWwindow* window, bool iconified)
|
||||
{
|
||||
if (window->callbacks.iconify)
|
||||
window->callbacks.iconify((GLFWwindow*) window, iconified);
|
||||
@@ -124,7 +126,7 @@ void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified)
|
||||
|
||||
// Notifies shared code that a window has been maximized or restored
|
||||
//
|
||||
void _glfwInputWindowMaximize(_GLFWwindow* window, GLFWbool maximized)
|
||||
void _glfwInputWindowMaximize(_GLFWwindow* window, bool maximized)
|
||||
{
|
||||
if (window->callbacks.maximize)
|
||||
window->callbacks.maximize((GLFWwindow*) window, maximized);
|
||||
@@ -168,7 +170,7 @@ void _glfwInputWindowDamage(_GLFWwindow* window)
|
||||
//
|
||||
void _glfwInputWindowCloseRequest(_GLFWwindow* window)
|
||||
{
|
||||
window->shouldClose = GLFW_TRUE;
|
||||
window->shouldClose = true;
|
||||
|
||||
if (window->callbacks.close)
|
||||
window->callbacks.close((GLFWwindow*) window);
|
||||
@@ -181,7 +183,6 @@ void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor)
|
||||
window->monitor = monitor;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW public API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -300,13 +301,13 @@ void glfwDefaultWindowHints(void)
|
||||
|
||||
// The default is a focused, visible, resizable window with decorations
|
||||
memset(&_glfw.hints.window, 0, sizeof(_glfw.hints.window));
|
||||
_glfw.hints.window.resizable = GLFW_TRUE;
|
||||
_glfw.hints.window.visible = GLFW_TRUE;
|
||||
_glfw.hints.window.decorated = GLFW_TRUE;
|
||||
_glfw.hints.window.focused = GLFW_TRUE;
|
||||
_glfw.hints.window.autoIconify = GLFW_TRUE;
|
||||
_glfw.hints.window.centerCursor = GLFW_TRUE;
|
||||
_glfw.hints.window.focusOnShow = GLFW_TRUE;
|
||||
_glfw.hints.window.resizable = true;
|
||||
_glfw.hints.window.visible = true;
|
||||
_glfw.hints.window.decorated = true;
|
||||
_glfw.hints.window.focused = true;
|
||||
_glfw.hints.window.autoIconify = true;
|
||||
_glfw.hints.window.centerCursor = true;
|
||||
_glfw.hints.window.focusOnShow = true;
|
||||
|
||||
// The default is 24 bits of color, 24 bits of depth and 8 bits of stencil,
|
||||
// double buffered
|
||||
@@ -317,13 +318,13 @@ void glfwDefaultWindowHints(void)
|
||||
_glfw.hints.framebuffer.alphaBits = 8;
|
||||
_glfw.hints.framebuffer.depthBits = 24;
|
||||
_glfw.hints.framebuffer.stencilBits = 8;
|
||||
_glfw.hints.framebuffer.doublebuffer = GLFW_TRUE;
|
||||
_glfw.hints.framebuffer.doublebuffer = true;
|
||||
|
||||
// The default is to select the highest available refresh rate
|
||||
_glfw.hints.refreshRate = GLFW_DONT_CARE;
|
||||
|
||||
// The default is to use full Retina resolution framebuffers
|
||||
_glfw.hints.window.ns.retina = GLFW_TRUE;
|
||||
_glfw.hints.window.ns.retina = true;
|
||||
}
|
||||
|
||||
GLFWAPI void glfwWindowHint(int hint, int value)
|
||||
@@ -366,55 +367,55 @@ GLFWAPI void glfwWindowHint(int hint, int value)
|
||||
_glfw.hints.framebuffer.auxBuffers = value;
|
||||
return;
|
||||
case GLFW_STEREO:
|
||||
_glfw.hints.framebuffer.stereo = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.framebuffer.stereo = value ? true : false;
|
||||
return;
|
||||
case GLFW_DOUBLEBUFFER:
|
||||
_glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.framebuffer.doublebuffer = value ? true : false;
|
||||
return;
|
||||
case GLFW_TRANSPARENT_FRAMEBUFFER:
|
||||
_glfw.hints.framebuffer.transparent = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.framebuffer.transparent = value ? true : false;
|
||||
return;
|
||||
case GLFW_SAMPLES:
|
||||
_glfw.hints.framebuffer.samples = value;
|
||||
return;
|
||||
case GLFW_SRGB_CAPABLE:
|
||||
_glfw.hints.framebuffer.sRGB = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.framebuffer.sRGB = value ? true : false;
|
||||
return;
|
||||
case GLFW_RESIZABLE:
|
||||
_glfw.hints.window.resizable = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.resizable = value ? true : false;
|
||||
return;
|
||||
case GLFW_DECORATED:
|
||||
_glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.decorated = value ? true : false;
|
||||
return;
|
||||
case GLFW_FOCUSED:
|
||||
_glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.focused = value ? true : false;
|
||||
return;
|
||||
case GLFW_AUTO_ICONIFY:
|
||||
_glfw.hints.window.autoIconify = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.autoIconify = value ? true : false;
|
||||
return;
|
||||
case GLFW_FLOATING:
|
||||
_glfw.hints.window.floating = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.floating = value ? true : false;
|
||||
return;
|
||||
case GLFW_MAXIMIZED:
|
||||
_glfw.hints.window.maximized = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.maximized = value ? true : false;
|
||||
return;
|
||||
case GLFW_VISIBLE:
|
||||
_glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.visible = value ? true : false;
|
||||
return;
|
||||
case GLFW_COCOA_RETINA_FRAMEBUFFER:
|
||||
_glfw.hints.window.ns.retina = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.ns.retina = value ? true : false;
|
||||
return;
|
||||
case GLFW_COCOA_GRAPHICS_SWITCHING:
|
||||
_glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.context.nsgl.offline = value ? true : false;
|
||||
return;
|
||||
case GLFW_SCALE_TO_MONITOR:
|
||||
_glfw.hints.window.scaleToMonitor = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.scaleToMonitor = value ? true : false;
|
||||
return;
|
||||
case GLFW_CENTER_CURSOR:
|
||||
_glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.centerCursor = value ? true : false;
|
||||
return;
|
||||
case GLFW_FOCUS_ON_SHOW:
|
||||
_glfw.hints.window.focusOnShow = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.focusOnShow = value ? true : false;
|
||||
return;
|
||||
case GLFW_CLIENT_API:
|
||||
_glfw.hints.context.client = value;
|
||||
@@ -432,13 +433,13 @@ GLFWAPI void glfwWindowHint(int hint, int value)
|
||||
_glfw.hints.context.robustness = value;
|
||||
return;
|
||||
case GLFW_OPENGL_FORWARD_COMPAT:
|
||||
_glfw.hints.context.forward = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.context.forward = value ? true : false;
|
||||
return;
|
||||
case GLFW_OPENGL_DEBUG_CONTEXT:
|
||||
_glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.context.debug = value ? true : false;
|
||||
return;
|
||||
case GLFW_CONTEXT_NO_ERROR:
|
||||
_glfw.hints.context.noerror = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.context.noerror = value ? true : false;
|
||||
return;
|
||||
case GLFW_OPENGL_PROFILE:
|
||||
_glfw.hints.context.profile = value;
|
||||
@@ -836,7 +837,7 @@ GLFWAPI int glfwWindowBell(GLFWwindow* handle)
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(false);
|
||||
|
||||
return _glfwPlatformWindowBell(window);
|
||||
}
|
||||
@@ -932,7 +933,7 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
value = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
value = value ? true : false;
|
||||
|
||||
if (attrib == GLFW_AUTO_ICONIFY)
|
||||
window->autoIconify = value;
|
||||
@@ -1165,6 +1166,5 @@ GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow*
|
||||
GLFWAPI void glfwPostEmptyEvent(void)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
_glfwPlatformPostEmptyEvent();
|
||||
}
|
||||
|
||||
225
glfw/wl_init.c
vendored
225
glfw/wl_init.c
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Wayland - www.glfw.org
|
||||
// GLFW 3.4 Wayland - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
|
||||
//
|
||||
@@ -23,6 +23,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include "internal.h"
|
||||
@@ -31,7 +33,6 @@
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <linux/input.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -39,6 +40,16 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <wayland-client.h>
|
||||
// Needed for the BTN_* defines
|
||||
#ifdef __has_include
|
||||
#if __has_include(<linux/input.h>)
|
||||
#include <linux/input.h>
|
||||
#elif __has_include(<dev/evdev/input.h>)
|
||||
#include <dev/evdev/input.h>
|
||||
#endif
|
||||
#else
|
||||
#include <linux/input.h>
|
||||
#endif
|
||||
|
||||
|
||||
static inline int min(int n1, int n2)
|
||||
@@ -46,7 +57,8 @@ static inline int min(int n1, int n2)
|
||||
return n1 < n2 ? n1 : n2;
|
||||
}
|
||||
|
||||
static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface, int* which)
|
||||
static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface,
|
||||
int* which)
|
||||
{
|
||||
int focus;
|
||||
_GLFWwindow* window = _glfw.windowListHead;
|
||||
@@ -79,12 +91,12 @@ static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface,
|
||||
return window;
|
||||
}
|
||||
|
||||
static void pointerHandleEnter(void* data,
|
||||
struct wl_pointer* pointer,
|
||||
static void pointerHandleEnter(void* data UNUSED,
|
||||
struct wl_pointer* pointer UNUSED,
|
||||
uint32_t serial,
|
||||
struct wl_surface* surface,
|
||||
wl_fixed_t sx,
|
||||
wl_fixed_t sy)
|
||||
wl_fixed_t sx UNUSED,
|
||||
wl_fixed_t sy UNUSED)
|
||||
{
|
||||
// Happens in the case we just destroyed the surface.
|
||||
if (!surface)
|
||||
@@ -103,27 +115,27 @@ static void pointerHandleEnter(void* data,
|
||||
_glfw.wl.pointerSerial = serial;
|
||||
_glfw.wl.pointerFocus = window;
|
||||
|
||||
window->wl.hovered = GLFW_TRUE;
|
||||
window->wl.hovered = true;
|
||||
|
||||
_glfwPlatformSetCursor(window, window->wl.currentCursor);
|
||||
_glfwInputCursorEnter(window, GLFW_TRUE);
|
||||
_glfwInputCursorEnter(window, true);
|
||||
}
|
||||
|
||||
static void pointerHandleLeave(void* data,
|
||||
struct wl_pointer* pointer,
|
||||
static void pointerHandleLeave(void* data UNUSED,
|
||||
struct wl_pointer* pointer UNUSED,
|
||||
uint32_t serial,
|
||||
struct wl_surface* surface)
|
||||
struct wl_surface* surface UNUSED)
|
||||
{
|
||||
_GLFWwindow* window = _glfw.wl.pointerFocus;
|
||||
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
window->wl.hovered = GLFW_FALSE;
|
||||
window->wl.hovered = false;
|
||||
|
||||
_glfw.wl.pointerSerial = serial;
|
||||
_glfw.wl.pointerFocus = NULL;
|
||||
_glfwInputCursorEnter(window, GLFW_FALSE);
|
||||
_glfwInputCursorEnter(window, false);
|
||||
}
|
||||
|
||||
static void setCursor(GLFWCursorShape shape)
|
||||
@@ -154,9 +166,9 @@ static void setCursor(GLFWCursorShape shape)
|
||||
wl_surface_commit(surface);
|
||||
}
|
||||
|
||||
static void pointerHandleMotion(void* data,
|
||||
struct wl_pointer* pointer,
|
||||
uint32_t time,
|
||||
static void pointerHandleMotion(void* data UNUSED,
|
||||
struct wl_pointer* pointer UNUSED,
|
||||
uint32_t time UNUSED,
|
||||
wl_fixed_t sx,
|
||||
wl_fixed_t sy)
|
||||
{
|
||||
@@ -168,18 +180,14 @@ static void pointerHandleMotion(void* data,
|
||||
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
return;
|
||||
else
|
||||
{
|
||||
window->wl.cursorPosX = wl_fixed_to_double(sx);
|
||||
window->wl.cursorPosY = wl_fixed_to_double(sy);
|
||||
}
|
||||
window->wl.cursorPosX = wl_fixed_to_double(sx);
|
||||
window->wl.cursorPosY = wl_fixed_to_double(sy);
|
||||
|
||||
switch (window->wl.decorations.focus)
|
||||
{
|
||||
case mainWindow:
|
||||
_glfwInputCursorPos(window,
|
||||
wl_fixed_to_double(sx),
|
||||
wl_fixed_to_double(sy));
|
||||
window->wl.cursorPosX, window->wl.cursorPosY);
|
||||
return;
|
||||
case topDecoration:
|
||||
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
|
||||
@@ -213,16 +221,15 @@ static void pointerHandleMotion(void* data,
|
||||
setCursor(cursorShape);
|
||||
}
|
||||
|
||||
static void pointerHandleButton(void* data,
|
||||
struct wl_pointer* pointer,
|
||||
static void pointerHandleButton(void* data UNUSED,
|
||||
struct wl_pointer* pointer UNUSED,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
uint32_t time UNUSED,
|
||||
uint32_t button,
|
||||
uint32_t state)
|
||||
{
|
||||
_GLFWwindow* window = _glfw.wl.pointerFocus;
|
||||
int glfwButton;
|
||||
|
||||
uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE;
|
||||
|
||||
if (!window)
|
||||
@@ -301,9 +308,9 @@ static void pointerHandleButton(void* data,
|
||||
_glfw.wl.xkb.states.modifiers);
|
||||
}
|
||||
|
||||
static void pointerHandleAxis(void* data,
|
||||
struct wl_pointer* pointer,
|
||||
uint32_t time,
|
||||
static void pointerHandleAxis(void* data UNUSED,
|
||||
struct wl_pointer* pointer UNUSED,
|
||||
uint32_t time UNUSED,
|
||||
uint32_t axis,
|
||||
wl_fixed_t value)
|
||||
{
|
||||
@@ -331,8 +338,8 @@ static const struct wl_pointer_listener pointerListener = {
|
||||
pointerHandleAxis,
|
||||
};
|
||||
|
||||
static void keyboardHandleKeymap(void* data,
|
||||
struct wl_keyboard* keyboard,
|
||||
static void keyboardHandleKeymap(void* data UNUSED,
|
||||
struct wl_keyboard* keyboard UNUSED,
|
||||
uint32_t format,
|
||||
int fd,
|
||||
uint32_t size)
|
||||
@@ -356,11 +363,11 @@ static void keyboardHandleKeymap(void* data,
|
||||
|
||||
}
|
||||
|
||||
static void keyboardHandleEnter(void* data,
|
||||
struct wl_keyboard* keyboard,
|
||||
uint32_t serial,
|
||||
static void keyboardHandleEnter(void* data UNUSED,
|
||||
struct wl_keyboard* keyboard UNUSED,
|
||||
uint32_t serial UNUSED,
|
||||
struct wl_surface* surface,
|
||||
struct wl_array* keys)
|
||||
struct wl_array* keys UNUSED)
|
||||
{
|
||||
// Happens in the case we just destroyed the surface.
|
||||
if (!surface)
|
||||
@@ -375,13 +382,13 @@ static void keyboardHandleEnter(void* data,
|
||||
}
|
||||
|
||||
_glfw.wl.keyboardFocus = window;
|
||||
_glfwInputWindowFocus(window, GLFW_TRUE);
|
||||
_glfwInputWindowFocus(window, true);
|
||||
}
|
||||
|
||||
static void keyboardHandleLeave(void* data,
|
||||
struct wl_keyboard* keyboard,
|
||||
uint32_t serial,
|
||||
struct wl_surface* surface)
|
||||
static void keyboardHandleLeave(void* data UNUSED,
|
||||
struct wl_keyboard* keyboard UNUSED,
|
||||
uint32_t serial UNUSED,
|
||||
struct wl_surface* surface UNUSED)
|
||||
{
|
||||
_GLFWwindow* window = _glfw.wl.keyboardFocus;
|
||||
|
||||
@@ -389,11 +396,11 @@ static void keyboardHandleLeave(void* data,
|
||||
return;
|
||||
|
||||
_glfw.wl.keyboardFocus = NULL;
|
||||
_glfwInputWindowFocus(window, GLFW_FALSE);
|
||||
_glfwInputWindowFocus(window, false);
|
||||
}
|
||||
|
||||
static void
|
||||
dispatchPendingKeyRepeats(id_type timer_id, void *data) {
|
||||
dispatchPendingKeyRepeats(id_type timer_id UNUSED, void *data UNUSED) {
|
||||
if (_glfw.wl.keyRepeatInfo.keyboardFocus != _glfw.wl.keyboardFocus || _glfw.wl.keyboardRepeatRate == 0) return;
|
||||
glfw_xkb_handle_key_event(_glfw.wl.keyRepeatInfo.keyboardFocus, &_glfw.wl.xkb, _glfw.wl.keyRepeatInfo.key, GLFW_REPEAT);
|
||||
changeTimerInterval(&_glfw.wl.eventLoopData, _glfw.wl.keyRepeatInfo.keyRepeatTimer, (1.0 / (double)_glfw.wl.keyboardRepeatRate));
|
||||
@@ -401,10 +408,10 @@ dispatchPendingKeyRepeats(id_type timer_id, void *data) {
|
||||
}
|
||||
|
||||
|
||||
static void keyboardHandleKey(void* data,
|
||||
struct wl_keyboard* keyboard,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
static void keyboardHandleKey(void* data UNUSED,
|
||||
struct wl_keyboard* keyboard UNUSED,
|
||||
uint32_t serial UNUSED,
|
||||
uint32_t time UNUSED,
|
||||
uint32_t key,
|
||||
uint32_t state)
|
||||
{
|
||||
@@ -413,12 +420,12 @@ static void keyboardHandleKey(void* data,
|
||||
return;
|
||||
int action = state == WL_KEYBOARD_KEY_STATE_PRESSED ? GLFW_PRESS : GLFW_RELEASE;
|
||||
glfw_xkb_handle_key_event(window, &_glfw.wl.xkb, key, action);
|
||||
GLFWbool repeatable = GLFW_FALSE;
|
||||
bool repeatable = false;
|
||||
|
||||
if (action == GLFW_PRESS && _glfw.wl.keyboardRepeatRate > 0 && glfw_xkb_should_repeat(&_glfw.wl.xkb, key))
|
||||
{
|
||||
_glfw.wl.keyRepeatInfo.key = key;
|
||||
repeatable = GLFW_TRUE;
|
||||
repeatable = true;
|
||||
_glfw.wl.keyRepeatInfo.keyboardFocus = window;
|
||||
}
|
||||
if (repeatable) {
|
||||
@@ -427,9 +434,9 @@ static void keyboardHandleKey(void* data,
|
||||
toggleTimer(&_glfw.wl.eventLoopData, _glfw.wl.keyRepeatInfo.keyRepeatTimer, repeatable ? 1 : 0);
|
||||
}
|
||||
|
||||
static void keyboardHandleModifiers(void* data,
|
||||
struct wl_keyboard* keyboard,
|
||||
uint32_t serial,
|
||||
static void keyboardHandleModifiers(void* data UNUSED,
|
||||
struct wl_keyboard* keyboard UNUSED,
|
||||
uint32_t serial UNUSED,
|
||||
uint32_t modsDepressed,
|
||||
uint32_t modsLatched,
|
||||
uint32_t modsLocked,
|
||||
@@ -438,7 +445,7 @@ static void keyboardHandleModifiers(void* data,
|
||||
glfw_xkb_update_modifiers(&_glfw.wl.xkb, modsDepressed, modsLatched, modsLocked, 0, 0, group);
|
||||
}
|
||||
|
||||
static void keyboardHandleRepeatInfo(void* data,
|
||||
static void keyboardHandleRepeatInfo(void* data UNUSED,
|
||||
struct wl_keyboard* keyboard,
|
||||
int32_t rate,
|
||||
int32_t delay)
|
||||
@@ -459,7 +466,7 @@ static const struct wl_keyboard_listener keyboardListener = {
|
||||
keyboardHandleRepeatInfo,
|
||||
};
|
||||
|
||||
static void seatHandleCapabilities(void* data,
|
||||
static void seatHandleCapabilities(void* data UNUSED,
|
||||
struct wl_seat* seat,
|
||||
enum wl_seat_capability caps)
|
||||
{
|
||||
@@ -486,9 +493,9 @@ static void seatHandleCapabilities(void* data,
|
||||
}
|
||||
}
|
||||
|
||||
static void seatHandleName(void* data,
|
||||
struct wl_seat* seat,
|
||||
const char* name)
|
||||
static void seatHandleName(void* data UNUSED,
|
||||
struct wl_seat* seat UNUSED,
|
||||
const char* name UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -497,7 +504,7 @@ static const struct wl_seat_listener seatListener = {
|
||||
seatHandleName,
|
||||
};
|
||||
|
||||
static void wmBaseHandlePing(void* data,
|
||||
static void wmBaseHandlePing(void* data UNUSED,
|
||||
struct xdg_wm_base* wmBase,
|
||||
uint32_t serial)
|
||||
{
|
||||
@@ -508,7 +515,7 @@ static const struct xdg_wm_base_listener wmBaseListener = {
|
||||
wmBaseHandlePing
|
||||
};
|
||||
|
||||
static void registryHandleGlobal(void* data,
|
||||
static void registryHandleGlobal(void* data UNUSED,
|
||||
struct wl_registry* registry,
|
||||
uint32_t name,
|
||||
const char* interface,
|
||||
@@ -614,18 +621,24 @@ static void registryHandleGlobal(void* data,
|
||||
|
||||
}
|
||||
|
||||
static void registryHandleGlobalRemove(void *data,
|
||||
struct wl_registry *registry,
|
||||
static void registryHandleGlobalRemove(void *data UNUSED,
|
||||
struct wl_registry *registry UNUSED,
|
||||
uint32_t name)
|
||||
{
|
||||
int i;
|
||||
_GLFWmonitor* monitor;
|
||||
|
||||
for (i = 0; i < _glfw.monitorCount; ++i)
|
||||
for (int i = 0; i < _glfw.monitorCount; ++i)
|
||||
{
|
||||
monitor = _glfw.monitors[i];
|
||||
if (monitor->wl.name == name)
|
||||
{
|
||||
for (_GLFWwindow *window = _glfw.windowListHead; window; window = window->next) {
|
||||
for (int m = window->wl.monitorsCount - 1; m >= 0; m--) {
|
||||
if (window->wl.monitors[m] == monitor) {
|
||||
remove_i_from_array(window->wl.monitors, m, window->wl.monitorsCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
_glfwInputMonitor(monitor, GLFW_DISCONNECTED, 0);
|
||||
return;
|
||||
}
|
||||
@@ -639,59 +652,81 @@ static const struct wl_registry_listener registryListener = {
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void registry_handle_global(void* data,
|
||||
struct wl_registry* registry UNUSED,
|
||||
uint32_t name UNUSED,
|
||||
const char* interface,
|
||||
uint32_t version UNUSED) {
|
||||
if (strcmp(interface, "zxdg_decoration_manager_v1") == 0) {
|
||||
bool *has_ssd = (bool*)data;
|
||||
if (has_ssd) *has_ssd = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void registry_handle_global_remove(void *data UNUSED,
|
||||
struct wl_registry *registry UNUSED,
|
||||
uint32_t name UNUSED) {}
|
||||
GLFWAPI const char*
|
||||
glfwWaylandCheckForServerSideDecorations(void) {
|
||||
struct wl_display *display = wl_display_connect(NULL);
|
||||
if (!display) return "ERR: Failed to connect to Wayland display";
|
||||
static const struct wl_registry_listener rl = {
|
||||
registry_handle_global, registry_handle_global_remove
|
||||
};
|
||||
struct wl_registry *registry = wl_display_get_registry(display);
|
||||
bool has_ssd = false;
|
||||
wl_registry_add_listener(registry, &rl, &has_ssd);
|
||||
wl_display_roundtrip(display);
|
||||
|
||||
wl_registry_destroy(registry);
|
||||
wl_display_flush(display);
|
||||
wl_display_flush(display);
|
||||
return has_ssd ? "YES" : "NO";
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int _glfwPlatformInit(void)
|
||||
{
|
||||
if (pipe2(_glfw.wl.eventLoopData.wakeupFds, O_CLOEXEC | O_NONBLOCK) != 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: failed to create self pipe");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_glfw.wl.cursor.handle = _glfw_dlopen("libwayland-cursor.so.0");
|
||||
if (!_glfw.wl.cursor.handle)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Failed to open libwayland-cursor");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfw.wl.cursor.theme_load = (PFN_wl_cursor_theme_load)
|
||||
_glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_theme_load");
|
||||
_glfw.wl.cursor.theme_destroy = (PFN_wl_cursor_theme_destroy)
|
||||
_glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_theme_destroy");
|
||||
_glfw.wl.cursor.theme_get_cursor = (PFN_wl_cursor_theme_get_cursor)
|
||||
_glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_theme_get_cursor");
|
||||
_glfw.wl.cursor.image_get_buffer = (PFN_wl_cursor_image_get_buffer)
|
||||
_glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_image_get_buffer");
|
||||
glfw_dlsym(_glfw.wl.cursor.theme_load, _glfw.wl.cursor.handle, "wl_cursor_theme_load");
|
||||
glfw_dlsym(_glfw.wl.cursor.theme_destroy, _glfw.wl.cursor.handle, "wl_cursor_theme_destroy");
|
||||
glfw_dlsym(_glfw.wl.cursor.theme_get_cursor, _glfw.wl.cursor.handle, "wl_cursor_theme_get_cursor");
|
||||
glfw_dlsym(_glfw.wl.cursor.image_get_buffer, _glfw.wl.cursor.handle, "wl_cursor_image_get_buffer");
|
||||
|
||||
_glfw.wl.egl.handle = _glfw_dlopen("libwayland-egl.so.1");
|
||||
if (!_glfw.wl.egl.handle)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Failed to open libwayland-egl");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfw.wl.egl.window_create = (PFN_wl_egl_window_create)
|
||||
_glfw_dlsym(_glfw.wl.egl.handle, "wl_egl_window_create");
|
||||
_glfw.wl.egl.window_destroy = (PFN_wl_egl_window_destroy)
|
||||
_glfw_dlsym(_glfw.wl.egl.handle, "wl_egl_window_destroy");
|
||||
_glfw.wl.egl.window_resize = (PFN_wl_egl_window_resize)
|
||||
_glfw_dlsym(_glfw.wl.egl.handle, "wl_egl_window_resize");
|
||||
glfw_dlsym(_glfw.wl.egl.window_create, _glfw.wl.egl.handle, "wl_egl_window_create");
|
||||
glfw_dlsym(_glfw.wl.egl.window_destroy, _glfw.wl.egl.handle, "wl_egl_window_destroy");
|
||||
glfw_dlsym(_glfw.wl.egl.window_resize, _glfw.wl.egl.handle, "wl_egl_window_resize");
|
||||
|
||||
_glfw.wl.display = wl_display_connect(NULL);
|
||||
if (!_glfw.wl.display)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Failed to connect to display");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
if (!initPollData(&_glfw.wl.eventLoopData, wl_display_get_fd(_glfw.wl.display))) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Failed to initialize event loop data");
|
||||
}
|
||||
initPollData(&_glfw.wl.eventLoopData, _glfw.wl.eventLoopData.wakeupFds[0], wl_display_get_fd(_glfw.wl.display));
|
||||
glfw_dbus_init(&_glfw.wl.dbus, &_glfw.wl.eventLoopData);
|
||||
_glfw.wl.keyRepeatInfo.keyRepeatTimer = addTimer(&_glfw.wl.eventLoopData, "wayland-key-repeat", 0.5, 0, true, dispatchPendingKeyRepeats, NULL, NULL);
|
||||
_glfw.wl.cursorAnimationTimer = addTimer(&_glfw.wl.eventLoopData, "wayland-cursor-animation", 0.5, 0, true, animateCursorImage, NULL, NULL);
|
||||
@@ -699,7 +734,7 @@ int _glfwPlatformInit(void)
|
||||
_glfw.wl.registry = wl_display_get_registry(_glfw.wl.display);
|
||||
wl_registry_add_listener(_glfw.wl.registry, ®istryListener, NULL);
|
||||
|
||||
if (!glfw_xkb_create_context(&_glfw.wl.xkb)) return GLFW_FALSE;
|
||||
if (!glfw_xkb_create_context(&_glfw.wl.xkb)) return false;
|
||||
|
||||
// Sync so we got all registry objects
|
||||
wl_display_roundtrip(_glfw.wl.display);
|
||||
@@ -710,7 +745,7 @@ int _glfwPlatformInit(void)
|
||||
#ifdef __linux__
|
||||
if (_glfw.hints.init.enableJoysticks) {
|
||||
if (!_glfwInitJoysticksLinux())
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -719,7 +754,7 @@ int _glfwPlatformInit(void)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Failed to find xdg-shell in your compositor");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_glfw.wl.shm)
|
||||
@@ -739,13 +774,13 @@ int _glfwPlatformInit(void)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Unable to load default cursor theme");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
_glfw.wl.cursorSurface =
|
||||
wl_compositor_create_surface(_glfw.wl.compositor);
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwPlatformTerminate(void)
|
||||
@@ -819,7 +854,7 @@ void _glfwPlatformTerminate(void)
|
||||
wl_display_flush(_glfw.wl.display);
|
||||
wl_display_disconnect(_glfw.wl.display);
|
||||
}
|
||||
closeFds(_glfw.wl.eventLoopData.wakeupFds, sizeof(_glfw.wl.eventLoopData.wakeupFds)/sizeof(_glfw.wl.eventLoopData.wakeupFds[0]));
|
||||
finalizePollData(&_glfw.wl.eventLoopData);
|
||||
free(_glfw.wl.clipboardString); _glfw.wl.clipboardString = NULL;
|
||||
free(_glfw.wl.primarySelectionString); _glfw.wl.primarySelectionString = NULL;
|
||||
free(_glfw.wl.pasteString); _glfw.wl.pasteString = NULL;
|
||||
|
||||
54
glfw/wl_monitor.c
vendored
54
glfw/wl_monitor.c
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Wayland - www.glfw.org
|
||||
// GLFW 3.4 Wayland - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
|
||||
//
|
||||
@@ -23,6 +23,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -34,15 +36,15 @@
|
||||
|
||||
|
||||
static void outputHandleGeometry(void* data,
|
||||
struct wl_output* output,
|
||||
int32_t x,
|
||||
int32_t y,
|
||||
int32_t physicalWidth,
|
||||
int32_t physicalHeight,
|
||||
int32_t subpixel,
|
||||
const char* make,
|
||||
const char* model,
|
||||
int32_t transform)
|
||||
struct wl_output* output UNUSED,
|
||||
int32_t x,
|
||||
int32_t y,
|
||||
int32_t physicalWidth,
|
||||
int32_t physicalHeight,
|
||||
int32_t subpixel UNUSED,
|
||||
const char* make,
|
||||
const char* model,
|
||||
int32_t transform UNUSED)
|
||||
{
|
||||
struct _GLFWmonitor *monitor = data;
|
||||
char name[1024];
|
||||
@@ -57,11 +59,11 @@ static void outputHandleGeometry(void* data,
|
||||
}
|
||||
|
||||
static void outputHandleMode(void* data,
|
||||
struct wl_output* output,
|
||||
uint32_t flags,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
int32_t refresh)
|
||||
struct wl_output* output UNUSED,
|
||||
uint32_t flags,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
int32_t refresh)
|
||||
{
|
||||
struct _GLFWmonitor *monitor = data;
|
||||
GLFWvidmode mode;
|
||||
@@ -71,7 +73,7 @@ static void outputHandleMode(void* data,
|
||||
mode.redBits = 8;
|
||||
mode.greenBits = 8;
|
||||
mode.blueBits = 8;
|
||||
mode.refreshRate = (int)round(refresh / 1000.0);
|
||||
mode.refreshRate = (int) round(refresh / 1000.0);
|
||||
|
||||
monitor->modeCount++;
|
||||
monitor->modes =
|
||||
@@ -82,16 +84,19 @@ static void outputHandleMode(void* data,
|
||||
monitor->wl.currentMode = monitor->modeCount - 1;
|
||||
}
|
||||
|
||||
static void outputHandleDone(void* data, struct wl_output* output)
|
||||
static void outputHandleDone(void* data, struct wl_output* output UNUSED)
|
||||
{
|
||||
struct _GLFWmonitor *monitor = data;
|
||||
for (int i = 0; i < _glfw.monitorCount; i++) {
|
||||
if (_glfw.monitors[i] == monitor) return;
|
||||
}
|
||||
|
||||
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
|
||||
}
|
||||
|
||||
static void outputHandleScale(void* data,
|
||||
struct wl_output* output,
|
||||
int32_t factor)
|
||||
struct wl_output* output UNUSED,
|
||||
int32_t factor)
|
||||
{
|
||||
struct _GLFWmonitor *monitor = data;
|
||||
if (factor > 0 && factor < 24)
|
||||
@@ -170,7 +175,9 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
||||
*yscale = (float) monitor->wl.scale;
|
||||
}
|
||||
|
||||
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height)
|
||||
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
|
||||
int* xpos, int* ypos,
|
||||
int* width, int* height)
|
||||
{
|
||||
if (xpos)
|
||||
*xpos = monitor->wl.x;
|
||||
@@ -193,14 +200,15 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
||||
*mode = monitor->modes[monitor->wl.currentMode];
|
||||
}
|
||||
|
||||
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor UNUSED, GLFWgammaramp* ramp UNUSED)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Gamma ramp access is not available");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor UNUSED,
|
||||
const GLFWgammaramp* ramp UNUSED)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Gamma ramp access is not available");
|
||||
|
||||
16
glfw/wl_platform.h
vendored
16
glfw/wl_platform.h
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Wayland - www.glfw.org
|
||||
// GLFW 3.4 Wayland - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
|
||||
//
|
||||
@@ -133,10 +133,10 @@ typedef struct _GLFWdecorationWayland
|
||||
typedef struct _GLFWwindowWayland
|
||||
{
|
||||
int width, height;
|
||||
GLFWbool visible;
|
||||
GLFWbool maximized;
|
||||
GLFWbool hovered;
|
||||
GLFWbool transparent;
|
||||
bool visible;
|
||||
bool maximized;
|
||||
bool hovered;
|
||||
bool transparent;
|
||||
struct wl_surface* surface;
|
||||
struct wl_egl_window* native;
|
||||
struct wl_callback* callback;
|
||||
@@ -167,10 +167,10 @@ typedef struct _GLFWwindowWayland
|
||||
|
||||
struct zwp_idle_inhibitor_v1* idleInhibitor;
|
||||
|
||||
GLFWbool fullscreened;
|
||||
bool fullscreened;
|
||||
|
||||
struct {
|
||||
GLFWbool serverSide;
|
||||
bool serverSide;
|
||||
struct wl_buffer* buffer;
|
||||
_GLFWdecorationWayland top, left, right, bottom;
|
||||
int focus;
|
||||
@@ -295,7 +295,7 @@ typedef struct _GLFWlibraryWayland
|
||||
typedef struct _GLFWmonitorWayland
|
||||
{
|
||||
struct wl_output* output;
|
||||
int name;
|
||||
uint32_t name;
|
||||
int currentMode;
|
||||
|
||||
int x;
|
||||
|
||||
307
glfw/wl_window.c
vendored
307
glfw/wl_window.c
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Wayland - www.glfw.org
|
||||
// GLFW 3.4 Wayland - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
|
||||
//
|
||||
@@ -23,6 +23,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
@@ -42,7 +44,7 @@
|
||||
#define URI_LIST_MIME "text/uri-list"
|
||||
|
||||
|
||||
static GLFWbool checkScaleChange(_GLFWwindow* window)
|
||||
static bool checkScaleChange(_GLFWwindow* window)
|
||||
{
|
||||
int scale = 1;
|
||||
int i;
|
||||
@@ -50,7 +52,7 @@ static GLFWbool checkScaleChange(_GLFWwindow* window)
|
||||
|
||||
// Check if we will be able to set the buffer scale or not.
|
||||
if (_glfw.wl.compositorVersion < 3)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
// Get the scale factor from the highest scale monitor.
|
||||
for (i = 0; i < window->wl.monitorsCount; ++i)
|
||||
@@ -65,9 +67,9 @@ static GLFWbool checkScaleChange(_GLFWwindow* window)
|
||||
{
|
||||
window->wl.scale = scale;
|
||||
wl_surface_set_buffer_scale(window->wl.surface, scale);
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Makes the surface considered as XRGB instead of ARGB.
|
||||
@@ -137,8 +139,8 @@ clipboard_mime(void) {
|
||||
static void dispatchChangesAfterConfigure(_GLFWwindow *window, int32_t width, int32_t height) {
|
||||
if (width <= 0) width = window->wl.width;
|
||||
if (height <= 0) height = window->wl.height;
|
||||
GLFWbool size_changed = width != window->wl.width || height != window->wl.height;
|
||||
GLFWbool scale_changed = checkScaleChange(window);
|
||||
bool size_changed = width != window->wl.width || height != window->wl.height;
|
||||
bool scale_changed = checkScaleChange(window);
|
||||
|
||||
if (size_changed) {
|
||||
_glfwInputWindowSize(window, width, height);
|
||||
@@ -171,7 +173,7 @@ static void dispatchChangesAfterConfigure(_GLFWwindow *window, int32_t width, in
|
||||
* SCM_RIGHTS methods.
|
||||
*
|
||||
* posix_fallocate() is used to guarantee that disk space is available
|
||||
* for the file at the given size. If disk space is insufficent, errno
|
||||
* for the file at the given size. If disk space is insufficient, errno
|
||||
* is set to ENOSPC. If posix_fallocate() is not supported, program may
|
||||
* receive SIGBUS on accessing mmap()'ed file contents instead.
|
||||
*/
|
||||
@@ -239,7 +241,7 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image)
|
||||
if (fd < 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Creating a buffer file for %d B failed: %m",
|
||||
"Wayland: Creating a buffer file for %d B failed: %%m",
|
||||
length);
|
||||
return NULL;
|
||||
}
|
||||
@@ -248,7 +250,7 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image)
|
||||
if (data == MAP_FAILED)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: mmap failed: %m");
|
||||
"Wayland: mmap failed: %%m");
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
@@ -281,7 +283,7 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image)
|
||||
|
||||
static void createDecoration(_GLFWdecorationWayland* decoration,
|
||||
struct wl_surface* parent,
|
||||
struct wl_buffer* buffer, GLFWbool opaque,
|
||||
struct wl_buffer* buffer, bool opaque,
|
||||
int x, int y,
|
||||
int width, int height)
|
||||
{
|
||||
@@ -313,7 +315,7 @@ static void createDecorations(_GLFWwindow* window)
|
||||
{
|
||||
unsigned char data[] = { 224, 224, 224, 255 };
|
||||
const GLFWimage image = { 1, 1, data };
|
||||
GLFWbool opaque = (data[3] == 255);
|
||||
bool opaque = (data[3] == 255);
|
||||
|
||||
if (!_glfw.wl.viewporter || !window->decorated || window->wl.decorations.serverSide)
|
||||
return;
|
||||
@@ -363,12 +365,12 @@ static void destroyDecorations(_GLFWwindow* window)
|
||||
}
|
||||
|
||||
static void xdgDecorationHandleConfigure(void* data,
|
||||
struct zxdg_toplevel_decoration_v1* decoration,
|
||||
struct zxdg_toplevel_decoration_v1* decoration UNUSED,
|
||||
uint32_t mode)
|
||||
{
|
||||
_GLFWwindow* window = data;
|
||||
window->wl.decorations.serverSide = (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
|
||||
if (!window->wl.decorations.serverSide)
|
||||
window->wl.decorations.serverSide = (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
|
||||
if (!window->wl.decorations.serverSide)
|
||||
createDecorations(window);
|
||||
}
|
||||
|
||||
@@ -377,7 +379,7 @@ static const struct zxdg_toplevel_decoration_v1_listener xdgDecorationListener =
|
||||
};
|
||||
|
||||
static void handleEnter(void *data,
|
||||
struct wl_surface *surface,
|
||||
struct wl_surface *surface UNUSED,
|
||||
struct wl_output *output)
|
||||
{
|
||||
_GLFWwindow* window = data;
|
||||
@@ -400,18 +402,18 @@ static void handleEnter(void *data,
|
||||
}
|
||||
|
||||
static void handleLeave(void *data,
|
||||
struct wl_surface *surface,
|
||||
struct wl_surface *surface UNUSED,
|
||||
struct wl_output *output)
|
||||
{
|
||||
_GLFWwindow* window = data;
|
||||
_GLFWmonitor* monitor = wl_output_get_user_data(output);
|
||||
GLFWbool found;
|
||||
bool found;
|
||||
int i;
|
||||
|
||||
for (i = 0, found = GLFW_FALSE; i < window->wl.monitorsCount - 1; ++i)
|
||||
for (i = 0, found = false; i < window->wl.monitorsCount - 1; ++i)
|
||||
{
|
||||
if (monitor == window->wl.monitors[i])
|
||||
found = GLFW_TRUE;
|
||||
found = true;
|
||||
if (found)
|
||||
window->wl.monitors[i] = window->wl.monitors[i + 1];
|
||||
}
|
||||
@@ -428,7 +430,7 @@ static const struct wl_surface_listener surfaceListener = {
|
||||
handleLeave
|
||||
};
|
||||
|
||||
static void setIdleInhibitor(_GLFWwindow* window, GLFWbool enable)
|
||||
static void setIdleInhibitor(_GLFWwindow* window, bool enable)
|
||||
{
|
||||
if (enable && !window->wl.idleInhibitor && _glfw.wl.idleInhibitManager)
|
||||
{
|
||||
@@ -446,12 +448,12 @@ static void setIdleInhibitor(_GLFWwindow* window, GLFWbool enable)
|
||||
}
|
||||
}
|
||||
|
||||
static GLFWbool createSurface(_GLFWwindow* window,
|
||||
static bool createSurface(_GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig)
|
||||
{
|
||||
window->wl.surface = wl_compositor_create_surface(_glfw.wl.compositor);
|
||||
if (!window->wl.surface)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
wl_surface_add_listener(window->wl.surface,
|
||||
&surfaceListener,
|
||||
@@ -463,7 +465,7 @@ static GLFWbool createSurface(_GLFWwindow* window,
|
||||
wndconfig->width,
|
||||
wndconfig->height);
|
||||
if (!window->wl.native)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
window->wl.width = wndconfig->width;
|
||||
window->wl.height = wndconfig->height;
|
||||
@@ -472,7 +474,7 @@ static GLFWbool createSurface(_GLFWwindow* window,
|
||||
if (!window->wl.transparent)
|
||||
setOpaqueRegion(window);
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -496,15 +498,14 @@ setFullscreen(_GLFWwindow* window, _GLFWmonitor* monitor, bool on)
|
||||
}
|
||||
|
||||
bool
|
||||
_glfwPlatformToggleFullscreen(_GLFWwindow *window, unsigned int flags) {
|
||||
(void) flags;
|
||||
_glfwPlatformToggleFullscreen(_GLFWwindow *window, unsigned int flags UNUSED) {
|
||||
bool already_fullscreen = window->wl.fullscreened;
|
||||
setFullscreen(window, NULL, !already_fullscreen);
|
||||
return !already_fullscreen;
|
||||
}
|
||||
|
||||
static void xdgToplevelHandleConfigure(void* data,
|
||||
struct xdg_toplevel* toplevel,
|
||||
struct xdg_toplevel* toplevel UNUSED,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
struct wl_array* states)
|
||||
@@ -513,24 +514,24 @@ static void xdgToplevelHandleConfigure(void* data,
|
||||
float aspectRatio;
|
||||
float targetRatio;
|
||||
uint32_t* state;
|
||||
GLFWbool maximized = GLFW_FALSE;
|
||||
GLFWbool fullscreen = GLFW_FALSE;
|
||||
GLFWbool activated = GLFW_FALSE;
|
||||
bool maximized = false;
|
||||
bool fullscreen = false;
|
||||
bool activated = false;
|
||||
|
||||
wl_array_for_each(state, states)
|
||||
{
|
||||
switch (*state)
|
||||
{
|
||||
case XDG_TOPLEVEL_STATE_MAXIMIZED:
|
||||
maximized = GLFW_TRUE;
|
||||
maximized = true;
|
||||
break;
|
||||
case XDG_TOPLEVEL_STATE_FULLSCREEN:
|
||||
fullscreen = GLFW_TRUE;
|
||||
fullscreen = true;
|
||||
break;
|
||||
case XDG_TOPLEVEL_STATE_RESIZING:
|
||||
break;
|
||||
case XDG_TOPLEVEL_STATE_ACTIVATED:
|
||||
activated = GLFW_TRUE;
|
||||
activated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -551,12 +552,18 @@ static void xdgToplevelHandleConfigure(void* data,
|
||||
}
|
||||
}
|
||||
window->wl.fullscreened = fullscreen;
|
||||
if (!fullscreen) {
|
||||
if (window->decorated && !window->wl.decorations.serverSide && window->wl.decorations.buffer) {
|
||||
width -= _GLFW_DECORATION_HORIZONTAL;
|
||||
height -= _GLFW_DECORATION_VERTICAL;
|
||||
}
|
||||
}
|
||||
dispatchChangesAfterConfigure(window, width, height);
|
||||
_glfwInputWindowFocus(window, activated);
|
||||
}
|
||||
|
||||
static void xdgToplevelHandleClose(void* data,
|
||||
struct xdg_toplevel* toplevel)
|
||||
struct xdg_toplevel* toplevel UNUSED)
|
||||
{
|
||||
_GLFWwindow* window = data;
|
||||
_glfwInputWindowCloseRequest(window);
|
||||
@@ -567,7 +574,7 @@ static const struct xdg_toplevel_listener xdgToplevelListener = {
|
||||
xdgToplevelHandleClose
|
||||
};
|
||||
|
||||
static void xdgSurfaceHandleConfigure(void* data,
|
||||
static void xdgSurfaceHandleConfigure(void* data UNUSED,
|
||||
struct xdg_surface* surface,
|
||||
uint32_t serial)
|
||||
{
|
||||
@@ -594,12 +601,12 @@ static void setXdgDecorations(_GLFWwindow* window)
|
||||
}
|
||||
else
|
||||
{
|
||||
window->wl.decorations.serverSide = GLFW_FALSE;
|
||||
window->wl.decorations.serverSide = false;
|
||||
createDecorations(window);
|
||||
}
|
||||
}
|
||||
|
||||
static GLFWbool createXdgSurface(_GLFWwindow* window)
|
||||
static bool createXdgSurface(_GLFWwindow* window)
|
||||
{
|
||||
window->wl.xdg.surface = xdg_wm_base_get_xdg_surface(_glfw.wl.wmBase,
|
||||
window->wl.surface);
|
||||
@@ -607,7 +614,7 @@ static GLFWbool createXdgSurface(_GLFWwindow* window)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: xdg-surface creation failed");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
xdg_surface_add_listener(window->wl.xdg.surface,
|
||||
@@ -619,7 +626,7 @@ static GLFWbool createXdgSurface(_GLFWwindow* window)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: xdg-toplevel creation failed");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
xdg_toplevel_add_listener(window->wl.xdg.toplevel,
|
||||
@@ -640,17 +647,17 @@ static GLFWbool createXdgSurface(_GLFWwindow* window)
|
||||
{
|
||||
xdg_toplevel_set_fullscreen(window->wl.xdg.toplevel,
|
||||
window->monitor->wl.output);
|
||||
setIdleInhibitor(window, GLFW_TRUE);
|
||||
setIdleInhibitor(window, true);
|
||||
}
|
||||
else if (window->wl.maximized)
|
||||
{
|
||||
xdg_toplevel_set_maximized(window->wl.xdg.toplevel);
|
||||
setIdleInhibitor(window, GLFW_FALSE);
|
||||
setIdleInhibitor(window, false);
|
||||
setXdgDecorations(window);
|
||||
}
|
||||
else
|
||||
{
|
||||
setIdleInhibitor(window, GLFW_FALSE);
|
||||
setIdleInhibitor(window, false);
|
||||
setXdgDecorations(window);
|
||||
}
|
||||
if (strlen(window->wl.appId))
|
||||
@@ -659,7 +666,7 @@ static GLFWbool createXdgSurface(_GLFWwindow* window)
|
||||
wl_surface_commit(window->wl.surface);
|
||||
wl_display_roundtrip(_glfw.wl.display);
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -720,7 +727,7 @@ incrementCursorImage(_GLFWwindow* window)
|
||||
}
|
||||
|
||||
void
|
||||
animateCursorImage(id_type timer_id, void *data) {
|
||||
animateCursorImage(id_type timer_id UNUSED, void *data UNUSED) {
|
||||
incrementCursorImage(_glfw.wl.pointerFocus);
|
||||
}
|
||||
|
||||
@@ -733,6 +740,8 @@ abortOnFatalError(int last_error) {
|
||||
_glfwInputWindowCloseRequest(window);
|
||||
window = window->next;
|
||||
}
|
||||
// ensure the tick callback is called
|
||||
_glfw.wl.eventLoopData.wakeup_data_read = true;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -740,16 +749,17 @@ handleEvents(double timeout)
|
||||
{
|
||||
struct wl_display* display = _glfw.wl.display;
|
||||
errno = 0;
|
||||
EVDBG("starting handleEvents(%.2f)", timeout);
|
||||
|
||||
while (wl_display_prepare_read(display) != 0) {
|
||||
while(1) {
|
||||
errno = 0;
|
||||
int num_dispatched = wl_display_dispatch_pending(display);
|
||||
if (num_dispatched == 0) return;
|
||||
if (num_dispatched < 0) {
|
||||
if (errno == EAGAIN) continue;
|
||||
int last_error = wl_display_get_error(display);
|
||||
if (last_error) abortOnFatalError(last_error);
|
||||
wl_display_cancel_read(display);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@@ -767,10 +777,13 @@ handleEvents(double timeout)
|
||||
return;
|
||||
}
|
||||
|
||||
GLFWbool display_read_ok = pollForEvents(&_glfw.wl.eventLoopData, timeout);
|
||||
bool display_read_ok = pollForEvents(&_glfw.wl.eventLoopData, timeout);
|
||||
EVDBG("display_read_ok: %d", display_read_ok);
|
||||
if (display_read_ok) {
|
||||
wl_display_read_events(display);
|
||||
wl_display_dispatch_pending(display);
|
||||
int num = wl_display_dispatch_pending(display);
|
||||
(void)num;
|
||||
EVDBG("dispatched %d Wayland events", num);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -778,6 +791,8 @@ handleEvents(double timeout)
|
||||
}
|
||||
glfw_ibus_dispatch(&_glfw.wl.xkb.ibus);
|
||||
glfw_dbus_session_bus_dispatch();
|
||||
EVDBG("other dispatch done");
|
||||
if (_glfw.wl.eventLoopData.wakeup_fd_ready) check_for_wakeup_events(&_glfw.wl.eventLoopData);
|
||||
}
|
||||
|
||||
static struct wl_cursor*
|
||||
@@ -795,13 +810,13 @@ try_cursor_names(int arg_count, ...) {
|
||||
|
||||
struct wl_cursor* _glfwLoadCursor(GLFWCursorShape shape)
|
||||
{
|
||||
static GLFWbool warnings[GLFW_INVALID_CURSOR] = {0};
|
||||
static bool warnings[GLFW_INVALID_CURSOR] = {0};
|
||||
#define NUMARGS(...) (sizeof((const char*[]){__VA_ARGS__})/sizeof(const char*))
|
||||
#define C(name, ...) case name: { \
|
||||
ans = try_cursor_names(NUMARGS(__VA_ARGS__), __VA_ARGS__); \
|
||||
if (!ans && !warnings[name]) {\
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Could not find standard cursor: %s", #name); \
|
||||
warnings[name] = GLFW_TRUE; \
|
||||
warnings[name] = true; \
|
||||
} \
|
||||
break; }
|
||||
|
||||
@@ -839,7 +854,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
strncpy(window->wl.appId, wndconfig->wl.appId, sizeof(window->wl.appId));
|
||||
|
||||
if (!createSurface(window, wndconfig))
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
if (ctxconfig->client != GLFW_NO_API)
|
||||
{
|
||||
@@ -847,16 +862,16 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
|
||||
{
|
||||
if (!_glfwInitEGL())
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
|
||||
{
|
||||
if (!_glfwInitOSMesa())
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -866,15 +881,15 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
if (wndconfig->visible)
|
||||
{
|
||||
if (!createXdgSurface(window))
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
window->wl.visible = GLFW_TRUE;
|
||||
window->wl.visible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
window->wl.xdg.surface = NULL;
|
||||
window->wl.xdg.toplevel = NULL;
|
||||
window->wl.visible = GLFW_FALSE;
|
||||
window->wl.visible = false;
|
||||
}
|
||||
|
||||
window->wl.currentCursor = NULL;
|
||||
@@ -883,7 +898,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
window->wl.monitorsCount = 0;
|
||||
window->wl.monitorsSize = 1;
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
@@ -891,12 +906,12 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
if (window == _glfw.wl.pointerFocus)
|
||||
{
|
||||
_glfw.wl.pointerFocus = NULL;
|
||||
_glfwInputCursorEnter(window, GLFW_FALSE);
|
||||
_glfwInputCursorEnter(window, false);
|
||||
}
|
||||
if (window == _glfw.wl.keyboardFocus)
|
||||
{
|
||||
_glfw.wl.keyboardFocus = NULL;
|
||||
_glfwInputWindowFocus(window, GLFW_FALSE);
|
||||
_glfwInputWindowFocus(window, false);
|
||||
}
|
||||
|
||||
if (window->wl.idleInhibitor)
|
||||
@@ -908,6 +923,7 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
destroyDecorations(window);
|
||||
if (window->wl.xdg.decoration)
|
||||
zxdg_toplevel_decoration_v1_destroy(window->wl.xdg.decoration);
|
||||
|
||||
if (window->wl.decorations.buffer)
|
||||
wl_buffer_destroy(window->wl.decorations.buffer);
|
||||
|
||||
@@ -938,14 +954,14 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
||||
xdg_toplevel_set_title(window->wl.xdg.toplevel, title);
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
||||
int count, const GLFWimage* images)
|
||||
void _glfwPlatformSetWindowIcon(_GLFWwindow* window UNUSED,
|
||||
int count UNUSED, const GLFWimage* images UNUSED)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Setting window icon not supported");
|
||||
}
|
||||
|
||||
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
|
||||
void _glfwPlatformGetWindowPos(_GLFWwindow* window UNUSED, int* xpos UNUSED, int* ypos UNUSED)
|
||||
{
|
||||
// A Wayland client is not aware of its position, so just warn and leave it
|
||||
// as (0, 0)
|
||||
@@ -954,7 +970,7 @@ void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
|
||||
"Wayland: Window position retrieval not supported");
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
|
||||
void _glfwPlatformSetWindowPos(_GLFWwindow* window UNUSED, int xpos UNUSED, int ypos UNUSED)
|
||||
{
|
||||
// A Wayland client can not set its position, so just warn
|
||||
|
||||
@@ -995,13 +1011,15 @@ void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)
|
||||
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window UNUSED,
|
||||
int numer UNUSED, int denom UNUSED)
|
||||
{
|
||||
// TODO: find out how to trigger a resize.
|
||||
// The actual limits are checked in the xdg_toplevel::configure handler.
|
||||
}
|
||||
|
||||
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
|
||||
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window,
|
||||
int* width, int* height)
|
||||
{
|
||||
_glfwPlatformGetWindowSize(window, width, height);
|
||||
*width *= window->wl.scale;
|
||||
@@ -1034,7 +1052,7 @@ void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
|
||||
*yscale = (float) window->wl.scale;
|
||||
}
|
||||
|
||||
double _glfwPlatformGetDoubleClickInterval(_GLFWwindow* window)
|
||||
double _glfwPlatformGetDoubleClickInterval(_GLFWwindow* window UNUSED)
|
||||
{
|
||||
return 0.5;
|
||||
}
|
||||
@@ -1057,7 +1075,7 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
|
||||
// minimized, so there is nothing to do in this case.
|
||||
}
|
||||
_glfwInputWindowMonitor(window, NULL);
|
||||
window->wl.maximized = GLFW_FALSE;
|
||||
window->wl.maximized = false;
|
||||
}
|
||||
|
||||
void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
|
||||
@@ -1066,7 +1084,7 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
|
||||
{
|
||||
xdg_toplevel_set_maximized(window->wl.xdg.toplevel);
|
||||
}
|
||||
window->wl.maximized = GLFW_TRUE;
|
||||
window->wl.maximized = true;
|
||||
}
|
||||
|
||||
void _glfwPlatformShowWindow(_GLFWwindow* window)
|
||||
@@ -1074,7 +1092,7 @@ void _glfwPlatformShowWindow(_GLFWwindow* window)
|
||||
if (!window->wl.visible)
|
||||
{
|
||||
createXdgSurface(window);
|
||||
window->wl.visible = GLFW_TRUE;
|
||||
window->wl.visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1087,34 +1105,34 @@ void _glfwPlatformHideWindow(_GLFWwindow* window)
|
||||
window->wl.xdg.toplevel = NULL;
|
||||
window->wl.xdg.surface = NULL;
|
||||
}
|
||||
window->wl.visible = GLFW_FALSE;
|
||||
window->wl.visible = false;
|
||||
}
|
||||
|
||||
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
|
||||
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window UNUSED)
|
||||
{
|
||||
// TODO
|
||||
static GLFWbool notified = GLFW_FALSE;
|
||||
static bool notified = false;
|
||||
if (!notified) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Window attention request not implemented yet");
|
||||
notified = GLFW_TRUE;
|
||||
notified = true;
|
||||
}
|
||||
}
|
||||
|
||||
int _glfwPlatformWindowBell(_GLFWwindow* window)
|
||||
int _glfwPlatformWindowBell(_GLFWwindow* window UNUSED)
|
||||
{
|
||||
// TODO: Use an actual Wayland API to implement this when one becomes available
|
||||
static char tty[L_ctermid + 1];
|
||||
int fd = open(ctermid(tty), O_WRONLY | O_CLOEXEC);
|
||||
if (fd > -1) {
|
||||
int ret = write(fd, "\x07", 1) == 1 ? GLFW_TRUE : GLFW_FALSE;
|
||||
int ret = write(fd, "\x07", 1) == 1 ? true : false;
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
void _glfwPlatformFocusWindow(_GLFWwindow* window)
|
||||
void _glfwPlatformFocusWindow(_GLFWwindow* window UNUSED)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Focusing a window requires user interaction");
|
||||
@@ -1122,9 +1140,9 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window)
|
||||
|
||||
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
||||
_GLFWmonitor* monitor,
|
||||
int xpos, int ypos,
|
||||
int width, int height,
|
||||
int refreshRate)
|
||||
int xpos UNUSED, int ypos UNUSED,
|
||||
int width UNUSED, int height UNUSED,
|
||||
int refreshRate UNUSED)
|
||||
{
|
||||
setFullscreen(window, monitor, monitor != NULL);
|
||||
_glfwInputWindowMonitor(window, monitor);
|
||||
@@ -1135,16 +1153,16 @@ int _glfwPlatformWindowFocused(_GLFWwindow* window)
|
||||
return _glfw.wl.keyboardFocus == window;
|
||||
}
|
||||
|
||||
int _glfwPlatformWindowOccluded(_GLFWwindow* window)
|
||||
int _glfwPlatformWindowOccluded(_GLFWwindow* window UNUSED)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
int _glfwPlatformWindowIconified(_GLFWwindow* window)
|
||||
int _glfwPlatformWindowIconified(_GLFWwindow* window UNUSED)
|
||||
{
|
||||
// xdg-shell doesn’t give any way to request whether a surface is
|
||||
// iconified.
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
int _glfwPlatformWindowVisible(_GLFWwindow* window)
|
||||
@@ -1167,14 +1185,14 @@ int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
|
||||
return window->wl.transparent;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window UNUSED, bool enabled UNUSED)
|
||||
{
|
||||
// TODO
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Window attribute setting not implemented yet");
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
|
||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, bool enabled)
|
||||
{
|
||||
if (!window->monitor)
|
||||
{
|
||||
@@ -1185,19 +1203,19 @@ void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window UNUSED, bool enabled UNUSED)
|
||||
{
|
||||
// TODO
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Window attribute setting not implemented yet");
|
||||
}
|
||||
|
||||
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
|
||||
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window UNUSED)
|
||||
{
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
|
||||
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window UNUSED, float opacity UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1221,7 +1239,7 @@ void _glfwPlatformWaitEventsTimeout(double timeout)
|
||||
|
||||
void _glfwPlatformPostEmptyEvent(void)
|
||||
{
|
||||
while (write(_glfw.wl.eventLoopData.wakeupFds[1], "w", 1) < 0 && errno == EINTR);
|
||||
wakeupEventLoop(&_glfw.wl.eventLoopData);
|
||||
}
|
||||
|
||||
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
|
||||
@@ -1232,7 +1250,7 @@ void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
|
||||
*ypos = window->wl.cursorPosY;
|
||||
}
|
||||
|
||||
static GLFWbool isPointerLocked(_GLFWwindow* window);
|
||||
static bool isPointerLocked(_GLFWwindow* window);
|
||||
|
||||
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
|
||||
{
|
||||
@@ -1245,7 +1263,7 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
||||
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode UNUSED)
|
||||
{
|
||||
_glfwPlatformSetCursor(window, window->wl.currentCursor);
|
||||
}
|
||||
@@ -1262,16 +1280,16 @@ int _glfwPlatformGetKeyScancode(int key)
|
||||
|
||||
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
||||
const GLFWimage* image,
|
||||
int xhot, int yhot, int count)
|
||||
int xhot, int yhot, int count UNUSED)
|
||||
{
|
||||
cursor->wl.buffer = createShmBuffer(image);
|
||||
if (!cursor->wl.buffer)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
cursor->wl.width = image->width;
|
||||
cursor->wl.height = image->height;
|
||||
cursor->wl.xhot = xhot;
|
||||
cursor->wl.yhot = yhot;
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, GLFWCursorShape shape)
|
||||
@@ -1279,10 +1297,10 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, GLFWCursorShape shape
|
||||
struct wl_cursor* standardCursor;
|
||||
|
||||
standardCursor = _glfwLoadCursor(shape);
|
||||
if (!standardCursor) return GLFW_FALSE;
|
||||
if (!standardCursor) return false;
|
||||
cursor->wl.cursor = standardCursor;
|
||||
cursor->wl.currentImage = 0;
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
||||
@@ -1296,11 +1314,11 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
||||
}
|
||||
|
||||
static void handleRelativeMotion(void* data,
|
||||
struct zwp_relative_pointer_v1* pointer,
|
||||
uint32_t timeHi,
|
||||
uint32_t timeLo,
|
||||
wl_fixed_t dx,
|
||||
wl_fixed_t dy,
|
||||
struct zwp_relative_pointer_v1* pointer UNUSED,
|
||||
uint32_t timeHi UNUSED,
|
||||
uint32_t timeLo UNUSED,
|
||||
wl_fixed_t dx UNUSED,
|
||||
wl_fixed_t dy UNUSED,
|
||||
wl_fixed_t dxUnaccel,
|
||||
wl_fixed_t dyUnaccel)
|
||||
{
|
||||
@@ -1318,8 +1336,8 @@ static const struct zwp_relative_pointer_v1_listener relativePointerListener = {
|
||||
handleRelativeMotion
|
||||
};
|
||||
|
||||
static void handleLocked(void* data,
|
||||
struct zwp_locked_pointer_v1* lockedPointer)
|
||||
static void handleLocked(void* data UNUSED,
|
||||
struct zwp_locked_pointer_v1* lockedPointer UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1337,10 +1355,10 @@ static void unlockPointer(_GLFWwindow* window)
|
||||
window->wl.pointerLock.lockedPointer = NULL;
|
||||
}
|
||||
|
||||
static void lockPointer(_GLFWwindow* window);
|
||||
static void lockPointer(_GLFWwindow* window UNUSED);
|
||||
|
||||
static void handleUnlocked(void* data,
|
||||
struct zwp_locked_pointer_v1* lockedPointer)
|
||||
static void handleUnlocked(void* data UNUSED,
|
||||
struct zwp_locked_pointer_v1* lockedPointer UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1387,7 +1405,7 @@ static void lockPointer(_GLFWwindow* window)
|
||||
NULL, 0, 0);
|
||||
}
|
||||
|
||||
static GLFWbool isPointerLocked(_GLFWwindow* window)
|
||||
static bool isPointerLocked(_GLFWwindow* window)
|
||||
{
|
||||
return window->wl.pointerLock.lockedPointer != NULL;
|
||||
}
|
||||
@@ -1462,12 +1480,12 @@ static void send_text(char *text, int fd)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static void _glfwSendClipboardText(void *data, struct wl_data_source *data_source, const char *mime_type, int fd) {
|
||||
static void _glfwSendClipboardText(void *data UNUSED, struct wl_data_source *data_source UNUSED, const char *mime_type UNUSED, int fd) {
|
||||
send_text(_glfw.wl.clipboardString, fd);
|
||||
}
|
||||
|
||||
static void _glfwSendPrimarySelectionText(void *data, struct zwp_primary_selection_source_v1 *primary_selection_source,
|
||||
const char *mime_type, int fd) {
|
||||
static void _glfwSendPrimarySelectionText(void *data UNUSED, struct zwp_primary_selection_source_v1 *primary_selection_source UNUSED,
|
||||
const char *mime_type UNUSED, int fd) {
|
||||
send_text(_glfw.wl.primarySelectionString, fd);
|
||||
}
|
||||
|
||||
@@ -1532,28 +1550,28 @@ static char* read_data_offer(struct wl_data_offer *data_offer, const char *mime)
|
||||
return read_offer_string(pipefd[0]);
|
||||
}
|
||||
|
||||
static void data_source_canceled(void *data, struct wl_data_source *wl_data_source) {
|
||||
static void data_source_canceled(void *data UNUSED, struct wl_data_source *wl_data_source) {
|
||||
if (_glfw.wl.dataSourceForClipboard == wl_data_source)
|
||||
_glfw.wl.dataSourceForClipboard = NULL;
|
||||
wl_data_source_destroy(wl_data_source);
|
||||
}
|
||||
|
||||
static void primary_selection_source_canceled(void *data, struct zwp_primary_selection_source_v1 *primary_selection_source) {
|
||||
static void primary_selection_source_canceled(void *data UNUSED, struct zwp_primary_selection_source_v1 *primary_selection_source) {
|
||||
if (_glfw.wl.dataSourceForPrimarySelection == primary_selection_source)
|
||||
_glfw.wl.dataSourceForPrimarySelection = NULL;
|
||||
zwp_primary_selection_source_v1_destroy(primary_selection_source);
|
||||
}
|
||||
|
||||
static void data_source_target(void *data, struct wl_data_source *wl_data_source, const char* mime) {
|
||||
static void data_source_target(void *data UNUSED, struct wl_data_source *wl_data_source UNUSED, const char* mime UNUSED) {
|
||||
}
|
||||
|
||||
const static struct wl_data_source_listener data_source_listener = {
|
||||
static const struct wl_data_source_listener data_source_listener = {
|
||||
.send = _glfwSendClipboardText,
|
||||
.cancelled = data_source_canceled,
|
||||
.target = data_source_target,
|
||||
};
|
||||
|
||||
const static struct zwp_primary_selection_source_v1_listener primary_selection_source_listener = {
|
||||
static const struct zwp_primary_selection_source_v1_listener primary_selection_source_listener = {
|
||||
.send = _glfwSendPrimarySelectionText,
|
||||
.cancelled = primary_selection_source_canceled,
|
||||
};
|
||||
@@ -1576,7 +1594,7 @@ static void prune_unclaimed_primary_selection_offers(void) {
|
||||
}
|
||||
}
|
||||
|
||||
static void mark_selection_offer(void *data, struct wl_data_device *data_device, struct wl_data_offer *data_offer)
|
||||
static void mark_selection_offer(void *data UNUSED, struct wl_data_device *data_device UNUSED, struct wl_data_offer *data_offer)
|
||||
{
|
||||
for (size_t i = 0; i < arraysz(_glfw.wl.dataOffers); i++) {
|
||||
if (_glfw.wl.dataOffers[i].id == data_offer) {
|
||||
@@ -1588,7 +1606,7 @@ static void mark_selection_offer(void *data, struct wl_data_device *data_device,
|
||||
prune_unclaimed_data_offers();
|
||||
}
|
||||
|
||||
static void mark_primary_selection_offer(void *data, struct zwp_primary_selection_device_v1* primary_selection_device,
|
||||
static void mark_primary_selection_offer(void *data UNUSED, struct zwp_primary_selection_device_v1* primary_selection_device UNUSED,
|
||||
struct zwp_primary_selection_offer_v1 *primary_selection_offer) {
|
||||
for (size_t i = 0; i < arraysz(_glfw.wl.primarySelectionOffers); i++) {
|
||||
if (_glfw.wl.primarySelectionOffers[i].id == primary_selection_offer) {
|
||||
@@ -1611,7 +1629,7 @@ static void set_offer_mimetype(struct _GLFWWaylandDataOffer* offer, const char*
|
||||
offer->has_uri_list = 1;
|
||||
}
|
||||
|
||||
static void handle_offer_mimetype(void *data, struct wl_data_offer* id, const char *mime) {
|
||||
static void handle_offer_mimetype(void *data UNUSED, struct wl_data_offer* id, const char *mime) {
|
||||
for (size_t i = 0; i < arraysz(_glfw.wl.dataOffers); i++) {
|
||||
if (_glfw.wl.dataOffers[i].id == id) {
|
||||
set_offer_mimetype(&_glfw.wl.dataOffers[i], mime);
|
||||
@@ -1620,7 +1638,7 @@ static void handle_offer_mimetype(void *data, struct wl_data_offer* id, const ch
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_primary_selection_offer_mimetype(void *data, struct zwp_primary_selection_offer_v1* id, const char *mime) {
|
||||
static void handle_primary_selection_offer_mimetype(void *data UNUSED, struct zwp_primary_selection_offer_v1* id, const char *mime) {
|
||||
for (size_t i = 0; i < arraysz(_glfw.wl.primarySelectionOffers); i++) {
|
||||
if (_glfw.wl.primarySelectionOffers[i].id == id) {
|
||||
set_offer_mimetype((struct _GLFWWaylandDataOffer*)&_glfw.wl.primarySelectionOffers[i], mime);
|
||||
@@ -1629,7 +1647,7 @@ static void handle_primary_selection_offer_mimetype(void *data, struct zwp_prima
|
||||
}
|
||||
}
|
||||
|
||||
static void data_offer_source_actions(void *data, struct wl_data_offer* id, uint32_t actions) {
|
||||
static void data_offer_source_actions(void *data UNUSED, struct wl_data_offer* id, uint32_t actions) {
|
||||
for (size_t i = 0; i < arraysz(_glfw.wl.dataOffers); i++) {
|
||||
if (_glfw.wl.dataOffers[i].id == id) {
|
||||
_glfw.wl.dataOffers[i].source_actions = actions;
|
||||
@@ -1638,7 +1656,7 @@ static void data_offer_source_actions(void *data, struct wl_data_offer* id, uint
|
||||
}
|
||||
}
|
||||
|
||||
static void data_offer_action(void *data, struct wl_data_offer* id, uint32_t action) {
|
||||
static void data_offer_action(void *data UNUSED, struct wl_data_offer* id, uint32_t action) {
|
||||
for (size_t i = 0; i < arraysz(_glfw.wl.dataOffers); i++) {
|
||||
if (_glfw.wl.dataOffers[i].id == id) {
|
||||
_glfw.wl.dataOffers[i].dnd_action = action;
|
||||
@@ -1658,7 +1676,7 @@ static const struct zwp_primary_selection_offer_v1_listener primary_selection_of
|
||||
.offer = handle_primary_selection_offer_mimetype,
|
||||
};
|
||||
|
||||
static void handle_data_offer(void *data, struct wl_data_device *wl_data_device, struct wl_data_offer *id) {
|
||||
static void handle_data_offer(void *data UNUSED, struct wl_data_device *wl_data_device UNUSED, struct wl_data_offer *id) {
|
||||
size_t smallest_idx = SIZE_MAX, pos = 0;
|
||||
for (size_t i = 0; i < arraysz(_glfw.wl.dataOffers); i++) {
|
||||
if (_glfw.wl.dataOffers[i].idx && _glfw.wl.dataOffers[i].idx < smallest_idx) {
|
||||
@@ -1679,7 +1697,7 @@ end:
|
||||
wl_data_offer_add_listener(id, &data_offer_listener, NULL);
|
||||
}
|
||||
|
||||
static void handle_primary_selection_offer(void *data, struct zwp_primary_selection_device_v1 *zwp_primary_selection_device_v1, struct zwp_primary_selection_offer_v1 *id) {
|
||||
static void handle_primary_selection_offer(void *data UNUSED, struct zwp_primary_selection_device_v1 *zwp_primary_selection_device_v1 UNUSED, struct zwp_primary_selection_offer_v1 *id) {
|
||||
size_t smallest_idx = SIZE_MAX, pos = 0;
|
||||
for (size_t i = 0; i < arraysz(_glfw.wl.primarySelectionOffers); i++) {
|
||||
if (_glfw.wl.primarySelectionOffers[i].idx && _glfw.wl.primarySelectionOffers[i].idx < smallest_idx) {
|
||||
@@ -1700,7 +1718,7 @@ end:
|
||||
zwp_primary_selection_offer_v1_add_listener(id, &primary_selection_offer_listener, NULL);
|
||||
}
|
||||
|
||||
static void drag_enter(void *data, struct wl_data_device *wl_data_device, uint32_t serial, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *id) {
|
||||
static void drag_enter(void *data UNUSED, struct wl_data_device *wl_data_device UNUSED, uint32_t serial, struct wl_surface *surface, wl_fixed_t x UNUSED, wl_fixed_t y UNUSED, struct wl_data_offer *id) {
|
||||
for (size_t i = 0; i < arraysz(_glfw.wl.dataOffers); i++) {
|
||||
if (_glfw.wl.dataOffers[i].id == id) {
|
||||
_glfw.wl.dataOffers[i].offer_type = DRAG_AND_DROP;
|
||||
@@ -1714,7 +1732,7 @@ static void drag_enter(void *data, struct wl_data_device *wl_data_device, uint32
|
||||
prune_unclaimed_data_offers();
|
||||
}
|
||||
|
||||
static void drag_leave(void *data, struct wl_data_device *wl_data_device) {
|
||||
static void drag_leave(void *data UNUSED, struct wl_data_device *wl_data_device UNUSED) {
|
||||
for (size_t i = 0; i < arraysz(_glfw.wl.dataOffers); i++) {
|
||||
if (_glfw.wl.dataOffers[i].offer_type == DRAG_AND_DROP) {
|
||||
wl_data_offer_destroy(_glfw.wl.dataOffers[i].id);
|
||||
@@ -1723,7 +1741,7 @@ static void drag_leave(void *data, struct wl_data_device *wl_data_device) {
|
||||
}
|
||||
}
|
||||
|
||||
static void drop(void *data, struct wl_data_device *wl_data_device) {
|
||||
static void drop(void *data, struct wl_data_device *wl_data_device UNUSED) {
|
||||
for (size_t i = 0; i < arraysz(_glfw.wl.dataOffers); i++) {
|
||||
if (_glfw.wl.dataOffers[i].offer_type == DRAG_AND_DROP) {
|
||||
char *uri_list = read_data_offer(_glfw.wl.dataOffers[i].id, URI_LIST_MIME);
|
||||
@@ -1755,10 +1773,10 @@ static void drop(void *data, struct wl_data_device *wl_data_device) {
|
||||
}
|
||||
}
|
||||
|
||||
static void motion(void *data, struct wl_data_device *wl_data_device, uint32_t time, wl_fixed_t x, wl_fixed_t y) {
|
||||
static void motion(void *data UNUSED, struct wl_data_device *wl_data_device UNUSED, uint32_t time UNUSED, wl_fixed_t x UNUSED, wl_fixed_t y UNUSED) {
|
||||
}
|
||||
|
||||
const static struct wl_data_device_listener data_device_listener = {
|
||||
static const struct wl_data_device_listener data_device_listener = {
|
||||
.data_offer = handle_data_offer,
|
||||
.selection = mark_selection_offer,
|
||||
.enter = drag_enter,
|
||||
@@ -1767,7 +1785,7 @@ const static struct wl_data_device_listener data_device_listener = {
|
||||
.leave = drag_leave,
|
||||
};
|
||||
|
||||
const static struct zwp_primary_selection_device_v1_listener primary_selection_device_listener = {
|
||||
static const struct zwp_primary_selection_device_v1_listener primary_selection_device_listener = {
|
||||
.data_offer = handle_primary_selection_offer,
|
||||
.selection = mark_primary_selection_offer,
|
||||
};
|
||||
@@ -1799,12 +1817,12 @@ void _glfwSetupWaylandPrimarySelectionDevice() {
|
||||
if (_glfw.wl.primarySelectionDevice) zwp_primary_selection_device_v1_add_listener(_glfw.wl.primarySelectionDevice, &primary_selection_device_listener, NULL);
|
||||
}
|
||||
|
||||
static inline GLFWbool _glfwEnsureDataDevice(void) {
|
||||
static inline bool _glfwEnsureDataDevice(void) {
|
||||
if (!_glfw.wl.dataDeviceManager)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Cannot use clipboard, data device manager is not ready");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_glfw.wl.dataDevice)
|
||||
@@ -1813,16 +1831,16 @@ static inline GLFWbool _glfwEnsureDataDevice(void) {
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Cannot use clipboard, seat is not ready");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
if (!_glfw.wl.dataDevice)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Cannot use clipboard, failed to create data device");
|
||||
return GLFW_FALSE;
|
||||
"Wayland: Cannot use clipboard, failed to create data device");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetClipboardString(const char* string)
|
||||
@@ -1847,7 +1865,7 @@ void _glfwPlatformSetClipboardString(const char* string)
|
||||
wl_data_source_offer(_glfw.wl.dataSourceForClipboard, "STRING");
|
||||
wl_data_source_offer(_glfw.wl.dataSourceForClipboard, "UTF8_STRING");
|
||||
struct wl_callback *callback = wl_display_sync(_glfw.wl.display);
|
||||
const static struct wl_callback_listener clipboard_copy_callback_listener = {.done = clipboard_copy_callback_done};
|
||||
static const struct wl_callback_listener clipboard_copy_callback_listener = {.done = clipboard_copy_callback_done};
|
||||
wl_callback_add_listener(callback, &clipboard_copy_callback_listener, _glfw.wl.dataSourceForClipboard);
|
||||
}
|
||||
|
||||
@@ -1867,11 +1885,11 @@ const char* _glfwPlatformGetClipboardString(void)
|
||||
void _glfwPlatformSetPrimarySelectionString(const char* string)
|
||||
{
|
||||
if (!_glfw.wl.primarySelectionDevice) {
|
||||
static GLFWbool warned_about_primary_selection_device = GLFW_FALSE;
|
||||
static bool warned_about_primary_selection_device = false;
|
||||
if (!warned_about_primary_selection_device) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Cannot copy no primary selection device available");
|
||||
warned_about_primary_selection_device = GLFW_TRUE;
|
||||
warned_about_primary_selection_device = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1896,7 +1914,7 @@ void _glfwPlatformSetPrimarySelectionString(const char* string)
|
||||
zwp_primary_selection_source_v1_offer(_glfw.wl.dataSourceForPrimarySelection, "STRING");
|
||||
zwp_primary_selection_source_v1_offer(_glfw.wl.dataSourceForPrimarySelection, "UTF8_STRING");
|
||||
struct wl_callback *callback = wl_display_sync(_glfw.wl.display);
|
||||
const static struct wl_callback_listener primary_selection_copy_callback_listener = {.done = primary_selection_copy_callback_done};
|
||||
static const struct wl_callback_listener primary_selection_copy_callback_listener = {.done = primary_selection_copy_callback_done};
|
||||
wl_callback_add_listener(callback, &primary_selection_copy_callback_listener, _glfw.wl.dataSourceForPrimarySelection);
|
||||
}
|
||||
|
||||
@@ -1986,7 +2004,7 @@ _glfwPlatformUpdateIMEState(_GLFWwindow *w, int which, int a, int b, int c, int
|
||||
}
|
||||
|
||||
static void
|
||||
frame_handle_redraw(void *data, struct wl_callback *callback, uint32_t time) {
|
||||
frame_handle_redraw(void *data, struct wl_callback *callback, uint32_t time UNUSED) {
|
||||
_GLFWwindow* window = (_GLFWwindow*) data;
|
||||
if (callback == window->wl.frameCallbackData.current_wl_callback) {
|
||||
window->wl.frameCallbackData.callback(window->wl.frameCallbackData.id);
|
||||
@@ -1995,6 +2013,7 @@ frame_handle_redraw(void *data, struct wl_callback *callback, uint32_t time) {
|
||||
wl_callback_destroy(callback);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW native API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -2012,7 +2031,7 @@ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* handle)
|
||||
return window->wl.surface;
|
||||
}
|
||||
|
||||
GLFWAPI int glfwGetXKBScancode(const char* keyName, GLFWbool caseSensitive) {
|
||||
GLFWAPI int glfwGetXKBScancode(const char* keyName, bool caseSensitive) {
|
||||
return glfw_xkb_keysym_from_name(keyName, caseSensitive);
|
||||
}
|
||||
|
||||
|
||||
214
glfw/x11_init.c
vendored
214
glfw/x11_init.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 X11 - www.glfw.org
|
||||
// GLFW 3.4 X11 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include "internal.h"
|
||||
@@ -46,10 +48,9 @@ static Atom getSupportedAtom(Atom* supportedAtoms,
|
||||
unsigned long atomCount,
|
||||
const char* atomName)
|
||||
{
|
||||
unsigned long i;
|
||||
const Atom atom = XInternAtom(_glfw.x11.display, atomName, False);
|
||||
|
||||
for (i = 0; i < atomCount; i++)
|
||||
for (unsigned long i = 0; i < atomCount; i++)
|
||||
{
|
||||
if (supportedAtoms[i] == atom)
|
||||
return atom;
|
||||
@@ -62,18 +63,12 @@ static Atom getSupportedAtom(Atom* supportedAtoms,
|
||||
//
|
||||
static void detectEWMH(void)
|
||||
{
|
||||
// First we read the _NET_SUPPORTING_WM_CHECK property on the root window
|
||||
Window* windowFromRoot = NULL;
|
||||
Window* windowFromChild = NULL;
|
||||
|
||||
// First we need a couple of atoms
|
||||
const Atom supportingWmCheck =
|
||||
XInternAtom(_glfw.x11.display, "_NET_SUPPORTING_WM_CHECK", False);
|
||||
const Atom wmSupported =
|
||||
XInternAtom(_glfw.x11.display, "_NET_SUPPORTED", False);
|
||||
|
||||
// Then we look for the _NET_SUPPORTING_WM_CHECK property of the root window
|
||||
if (!_glfwGetWindowPropertyX11(_glfw.x11.root,
|
||||
supportingWmCheck,
|
||||
_glfw.x11.NET_SUPPORTING_WM_CHECK,
|
||||
XA_WINDOW,
|
||||
(unsigned char**) &windowFromRoot))
|
||||
{
|
||||
@@ -82,10 +77,12 @@ static void detectEWMH(void)
|
||||
|
||||
_glfwGrabErrorHandlerX11();
|
||||
|
||||
// It should be the ID of a child window (of the root)
|
||||
// Then we look for the same property on the child window
|
||||
// If it exists, it should be the XID of a top-level window
|
||||
// Then we look for the same property on that window
|
||||
|
||||
Window* windowFromChild = NULL;
|
||||
if (!_glfwGetWindowPropertyX11(*windowFromRoot,
|
||||
supportingWmCheck,
|
||||
_glfw.x11.NET_SUPPORTING_WM_CHECK,
|
||||
XA_WINDOW,
|
||||
(unsigned char**) &windowFromChild))
|
||||
{
|
||||
@@ -95,7 +92,7 @@ static void detectEWMH(void)
|
||||
|
||||
_glfwReleaseErrorHandlerX11();
|
||||
|
||||
// It should be the ID of that same child window
|
||||
// If the property exists, it should contain the XID of the window
|
||||
if (*windowFromRoot != *windowFromChild)
|
||||
{
|
||||
XFree(windowFromRoot);
|
||||
@@ -107,18 +104,20 @@ static void detectEWMH(void)
|
||||
XFree(windowFromChild);
|
||||
|
||||
// We are now fairly sure that an EWMH-compliant window manager is running
|
||||
// We can now start querying the WM about what features it supports by
|
||||
// looking in the _NET_SUPPORTED property on the root window
|
||||
// It should contain a list of supported EWMH protocol and state atoms
|
||||
|
||||
Atom* supportedAtoms;
|
||||
unsigned long atomCount;
|
||||
|
||||
// Now we need to check the _NET_SUPPORTED property of the root window
|
||||
// It should be a list of supported WM protocol and state atoms
|
||||
atomCount = _glfwGetWindowPropertyX11(_glfw.x11.root,
|
||||
wmSupported,
|
||||
Atom* supportedAtoms = NULL;
|
||||
const unsigned long atomCount = _glfwGetWindowPropertyX11(_glfw.x11.root,
|
||||
_glfw.x11.NET_SUPPORTED,
|
||||
XA_ATOM,
|
||||
(unsigned char**) &supportedAtoms);
|
||||
if (!supportedAtoms)
|
||||
return;
|
||||
|
||||
// See which of the atoms we support that are supported by the WM
|
||||
|
||||
_glfw.x11.NET_WM_STATE =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE");
|
||||
_glfw.x11.NET_WM_STATE_ABOVE =
|
||||
@@ -148,25 +147,20 @@ static void detectEWMH(void)
|
||||
_glfw.x11.NET_REQUEST_FRAME_EXTENTS =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_REQUEST_FRAME_EXTENTS");
|
||||
|
||||
if (supportedAtoms)
|
||||
XFree(supportedAtoms);
|
||||
XFree(supportedAtoms);
|
||||
}
|
||||
|
||||
// Look for and initialize supported X11 extensions
|
||||
//
|
||||
static GLFWbool initExtensions(void)
|
||||
static bool initExtensions(void)
|
||||
{
|
||||
_glfw.x11.vidmode.handle = _glfw_dlopen("libXxf86vm.so.1");
|
||||
if (_glfw.x11.vidmode.handle)
|
||||
{
|
||||
_glfw.x11.vidmode.QueryExtension = (PFN_XF86VidModeQueryExtension)
|
||||
_glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeQueryExtension");
|
||||
_glfw.x11.vidmode.GetGammaRamp = (PFN_XF86VidModeGetGammaRamp)
|
||||
_glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRamp");
|
||||
_glfw.x11.vidmode.SetGammaRamp = (PFN_XF86VidModeSetGammaRamp)
|
||||
_glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeSetGammaRamp");
|
||||
_glfw.x11.vidmode.GetGammaRampSize = (PFN_XF86VidModeGetGammaRampSize)
|
||||
_glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRampSize");
|
||||
glfw_dlsym(_glfw.x11.vidmode.QueryExtension, _glfw.x11.vidmode.handle, "XF86VidModeQueryExtension");
|
||||
glfw_dlsym(_glfw.x11.vidmode.GetGammaRamp, _glfw.x11.vidmode.handle, "XF86VidModeGetGammaRamp");
|
||||
glfw_dlsym(_glfw.x11.vidmode.SetGammaRamp, _glfw.x11.vidmode.handle, "XF86VidModeSetGammaRamp");
|
||||
glfw_dlsym(_glfw.x11.vidmode.GetGammaRampSize, _glfw.x11.vidmode.handle, "XF86VidModeGetGammaRampSize");
|
||||
|
||||
_glfw.x11.vidmode.available =
|
||||
XF86VidModeQueryExtension(_glfw.x11.display,
|
||||
@@ -181,10 +175,8 @@ static GLFWbool initExtensions(void)
|
||||
#endif
|
||||
if (_glfw.x11.xi.handle)
|
||||
{
|
||||
_glfw.x11.xi.QueryVersion = (PFN_XIQueryVersion)
|
||||
_glfw_dlsym(_glfw.x11.xi.handle, "XIQueryVersion");
|
||||
_glfw.x11.xi.SelectEvents = (PFN_XISelectEvents)
|
||||
_glfw_dlsym(_glfw.x11.xi.handle, "XISelectEvents");
|
||||
glfw_dlsym(_glfw.x11.xi.QueryVersion, _glfw.x11.xi.handle, "XIQueryVersion");
|
||||
glfw_dlsym(_glfw.x11.xi.SelectEvents, _glfw.x11.xi.handle, "XISelectEvents");
|
||||
|
||||
if (XQueryExtension(_glfw.x11.display,
|
||||
"XInputExtension",
|
||||
@@ -199,7 +191,7 @@ static GLFWbool initExtensions(void)
|
||||
&_glfw.x11.xi.major,
|
||||
&_glfw.x11.xi.minor) == Success)
|
||||
{
|
||||
_glfw.x11.xi.available = GLFW_TRUE;
|
||||
_glfw.x11.xi.available = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -211,42 +203,24 @@ static GLFWbool initExtensions(void)
|
||||
#endif
|
||||
if (_glfw.x11.randr.handle)
|
||||
{
|
||||
_glfw.x11.randr.AllocGamma = (PFN_XRRAllocGamma)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRAllocGamma");
|
||||
_glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeGamma");
|
||||
_glfw.x11.randr.FreeCrtcInfo = (PFN_XRRFreeCrtcInfo)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeCrtcInfo");
|
||||
_glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeGamma");
|
||||
_glfw.x11.randr.FreeOutputInfo = (PFN_XRRFreeOutputInfo)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeOutputInfo");
|
||||
_glfw.x11.randr.FreeScreenResources = (PFN_XRRFreeScreenResources)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeScreenResources");
|
||||
_glfw.x11.randr.GetCrtcGamma = (PFN_XRRGetCrtcGamma)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGamma");
|
||||
_glfw.x11.randr.GetCrtcGammaSize = (PFN_XRRGetCrtcGammaSize)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGammaSize");
|
||||
_glfw.x11.randr.GetCrtcInfo = (PFN_XRRGetCrtcInfo)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcInfo");
|
||||
_glfw.x11.randr.GetOutputInfo = (PFN_XRRGetOutputInfo)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRGetOutputInfo");
|
||||
_glfw.x11.randr.GetOutputPrimary = (PFN_XRRGetOutputPrimary)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRGetOutputPrimary");
|
||||
_glfw.x11.randr.GetScreenResourcesCurrent = (PFN_XRRGetScreenResourcesCurrent)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRGetScreenResourcesCurrent");
|
||||
_glfw.x11.randr.QueryExtension = (PFN_XRRQueryExtension)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRQueryExtension");
|
||||
_glfw.x11.randr.QueryVersion = (PFN_XRRQueryVersion)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRQueryVersion");
|
||||
_glfw.x11.randr.SelectInput = (PFN_XRRSelectInput)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRSelectInput");
|
||||
_glfw.x11.randr.SetCrtcConfig = (PFN_XRRSetCrtcConfig)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRSetCrtcConfig");
|
||||
_glfw.x11.randr.SetCrtcGamma = (PFN_XRRSetCrtcGamma)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRSetCrtcGamma");
|
||||
_glfw.x11.randr.UpdateConfiguration = (PFN_XRRUpdateConfiguration)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRUpdateConfiguration");
|
||||
glfw_dlsym(_glfw.x11.randr.AllocGamma, _glfw.x11.randr.handle, "XRRAllocGamma");
|
||||
glfw_dlsym(_glfw.x11.randr.FreeGamma, _glfw.x11.randr.handle, "XRRFreeGamma");
|
||||
glfw_dlsym(_glfw.x11.randr.FreeCrtcInfo, _glfw.x11.randr.handle, "XRRFreeCrtcInfo");
|
||||
glfw_dlsym(_glfw.x11.randr.FreeGamma, _glfw.x11.randr.handle, "XRRFreeGamma");
|
||||
glfw_dlsym(_glfw.x11.randr.FreeOutputInfo, _glfw.x11.randr.handle, "XRRFreeOutputInfo");
|
||||
glfw_dlsym(_glfw.x11.randr.FreeScreenResources, _glfw.x11.randr.handle, "XRRFreeScreenResources");
|
||||
glfw_dlsym(_glfw.x11.randr.GetCrtcGamma, _glfw.x11.randr.handle, "XRRGetCrtcGamma");
|
||||
glfw_dlsym(_glfw.x11.randr.GetCrtcGammaSize, _glfw.x11.randr.handle, "XRRGetCrtcGammaSize");
|
||||
glfw_dlsym(_glfw.x11.randr.GetCrtcInfo, _glfw.x11.randr.handle, "XRRGetCrtcInfo");
|
||||
glfw_dlsym(_glfw.x11.randr.GetOutputInfo, _glfw.x11.randr.handle, "XRRGetOutputInfo");
|
||||
glfw_dlsym(_glfw.x11.randr.GetOutputPrimary, _glfw.x11.randr.handle, "XRRGetOutputPrimary");
|
||||
glfw_dlsym(_glfw.x11.randr.GetScreenResourcesCurrent, _glfw.x11.randr.handle, "XRRGetScreenResourcesCurrent");
|
||||
glfw_dlsym(_glfw.x11.randr.QueryExtension, _glfw.x11.randr.handle, "XRRQueryExtension");
|
||||
glfw_dlsym(_glfw.x11.randr.QueryVersion, _glfw.x11.randr.handle, "XRRQueryVersion");
|
||||
glfw_dlsym(_glfw.x11.randr.SelectInput, _glfw.x11.randr.handle, "XRRSelectInput");
|
||||
glfw_dlsym(_glfw.x11.randr.SetCrtcConfig, _glfw.x11.randr.handle, "XRRSetCrtcConfig");
|
||||
glfw_dlsym(_glfw.x11.randr.SetCrtcGamma, _glfw.x11.randr.handle, "XRRSetCrtcGamma");
|
||||
glfw_dlsym(_glfw.x11.randr.UpdateConfiguration, _glfw.x11.randr.handle, "XRRUpdateConfiguration");
|
||||
|
||||
if (XRRQueryExtension(_glfw.x11.display,
|
||||
&_glfw.x11.randr.eventBase,
|
||||
@@ -258,7 +232,7 @@ static GLFWbool initExtensions(void)
|
||||
{
|
||||
// The GLFW RandR path requires at least version 1.3
|
||||
if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3)
|
||||
_glfw.x11.randr.available = GLFW_TRUE;
|
||||
_glfw.x11.randr.available = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -277,14 +251,14 @@ static GLFWbool initExtensions(void)
|
||||
{
|
||||
// This is likely an older Nvidia driver with broken gamma support
|
||||
// Flag it as useless and fall back to xf86vm gamma, if available
|
||||
_glfw.x11.randr.gammaBroken = GLFW_TRUE;
|
||||
_glfw.x11.randr.gammaBroken = true;
|
||||
}
|
||||
|
||||
if (!sr->ncrtc)
|
||||
{
|
||||
// A system without CRTCs is likely a system with broken RandR
|
||||
// Disable the RandR monitor path and fall back to core functions
|
||||
_glfw.x11.randr.monitorBroken = GLFW_TRUE;
|
||||
_glfw.x11.randr.monitorBroken = true;
|
||||
}
|
||||
|
||||
XRRFreeScreenResources(sr);
|
||||
@@ -303,12 +277,9 @@ static GLFWbool initExtensions(void)
|
||||
#endif
|
||||
if (_glfw.x11.xcursor.handle)
|
||||
{
|
||||
_glfw.x11.xcursor.ImageCreate = (PFN_XcursorImageCreate)
|
||||
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageCreate");
|
||||
_glfw.x11.xcursor.ImageDestroy = (PFN_XcursorImageDestroy)
|
||||
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageDestroy");
|
||||
_glfw.x11.xcursor.ImageLoadCursor = (PFN_XcursorImageLoadCursor)
|
||||
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageLoadCursor");
|
||||
glfw_dlsym(_glfw.x11.xcursor.ImageCreate, _glfw.x11.xcursor.handle, "XcursorImageCreate");
|
||||
glfw_dlsym(_glfw.x11.xcursor.ImageDestroy, _glfw.x11.xcursor.handle, "XcursorImageDestroy");
|
||||
glfw_dlsym(_glfw.x11.xcursor.ImageLoadCursor, _glfw.x11.xcursor.handle, "XcursorImageLoadCursor");
|
||||
}
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
@@ -318,19 +289,16 @@ static GLFWbool initExtensions(void)
|
||||
#endif
|
||||
if (_glfw.x11.xinerama.handle)
|
||||
{
|
||||
_glfw.x11.xinerama.IsActive = (PFN_XineramaIsActive)
|
||||
_glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaIsActive");
|
||||
_glfw.x11.xinerama.QueryExtension = (PFN_XineramaQueryExtension)
|
||||
_glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaQueryExtension");
|
||||
_glfw.x11.xinerama.QueryScreens = (PFN_XineramaQueryScreens)
|
||||
_glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaQueryScreens");
|
||||
glfw_dlsym(_glfw.x11.xinerama.IsActive, _glfw.x11.xinerama.handle, "XineramaIsActive");
|
||||
glfw_dlsym(_glfw.x11.xinerama.QueryExtension, _glfw.x11.xinerama.handle, "XineramaQueryExtension");
|
||||
glfw_dlsym(_glfw.x11.xinerama.QueryScreens, _glfw.x11.xinerama.handle, "XineramaQueryScreens");
|
||||
|
||||
if (XineramaQueryExtension(_glfw.x11.display,
|
||||
&_glfw.x11.xinerama.major,
|
||||
&_glfw.x11.xinerama.minor))
|
||||
{
|
||||
if (XineramaIsActive(_glfw.x11.display))
|
||||
_glfw.x11.xinerama.available = GLFW_TRUE;
|
||||
_glfw.x11.xinerama.available = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,12 +309,9 @@ static GLFWbool initExtensions(void)
|
||||
#endif
|
||||
if (_glfw.x11.xrender.handle)
|
||||
{
|
||||
_glfw.x11.xrender.QueryExtension = (PFN_XRenderQueryExtension)
|
||||
_glfw_dlsym(_glfw.x11.xrender.handle, "XRenderQueryExtension");
|
||||
_glfw.x11.xrender.QueryVersion = (PFN_XRenderQueryVersion)
|
||||
_glfw_dlsym(_glfw.x11.xrender.handle, "XRenderQueryVersion");
|
||||
_glfw.x11.xrender.FindVisualFormat = (PFN_XRenderFindVisualFormat)
|
||||
_glfw_dlsym(_glfw.x11.xrender.handle, "XRenderFindVisualFormat");
|
||||
glfw_dlsym(_glfw.x11.xrender.QueryExtension, _glfw.x11.xrender.handle, "XRenderQueryExtension");
|
||||
glfw_dlsym(_glfw.x11.xrender.QueryVersion, _glfw.x11.xrender.handle, "XRenderQueryVersion");
|
||||
glfw_dlsym(_glfw.x11.xrender.FindVisualFormat, _glfw.x11.xrender.handle, "XRenderFindVisualFormat");
|
||||
|
||||
if (XRenderQueryExtension(_glfw.x11.display,
|
||||
&_glfw.x11.xrender.errorBase,
|
||||
@@ -356,7 +321,7 @@ static GLFWbool initExtensions(void)
|
||||
&_glfw.x11.xrender.major,
|
||||
&_glfw.x11.xrender.minor))
|
||||
{
|
||||
_glfw.x11.xrender.available = GLFW_TRUE;
|
||||
_glfw.x11.xrender.available = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -373,22 +338,19 @@ static GLFWbool initExtensions(void)
|
||||
if (!_glfw.x11.xkb.available)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to load Xkb extension");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
Bool supported;
|
||||
if (XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported))
|
||||
{
|
||||
if (supported)
|
||||
_glfw.x11.xkb.detectable = GLFW_TRUE;
|
||||
_glfw.x11.xkb.detectable = true;
|
||||
}
|
||||
|
||||
if (!glfw_xkb_set_x11_events_mask()) return GLFW_FALSE;
|
||||
if (!glfw_xkb_create_context(&_glfw.x11.xkb)) return GLFW_FALSE;
|
||||
if (!glfw_xkb_update_x11_keyboard_id(&_glfw.x11.xkb)) return GLFW_FALSE;
|
||||
if (!glfw_xkb_compile_keymap(&_glfw.x11.xkb, NULL)) return GLFW_FALSE;
|
||||
|
||||
// Detect whether an EWMH-conformant window manager is running
|
||||
detectEWMH();
|
||||
if (!glfw_xkb_set_x11_events_mask()) return false;
|
||||
if (!glfw_xkb_create_context(&_glfw.x11.xkb)) return false;
|
||||
if (!glfw_xkb_update_x11_keyboard_id(&_glfw.x11.xkb)) return false;
|
||||
if (!glfw_xkb_compile_keymap(&_glfw.x11.xkb, NULL)) return false;
|
||||
|
||||
// String format atoms
|
||||
_glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False);
|
||||
@@ -433,6 +395,10 @@ static GLFWbool initExtensions(void)
|
||||
XInternAtom(_glfw.x11.display, "WM_STATE", False);
|
||||
_glfw.x11.WM_DELETE_WINDOW =
|
||||
XInternAtom(_glfw.x11.display, "WM_DELETE_WINDOW", False);
|
||||
_glfw.x11.NET_SUPPORTED =
|
||||
XInternAtom(_glfw.x11.display, "_NET_SUPPORTED", False);
|
||||
_glfw.x11.NET_SUPPORTING_WM_CHECK =
|
||||
XInternAtom(_glfw.x11.display, "_NET_SUPPORTING_WM_CHECK", False);
|
||||
_glfw.x11.NET_WM_ICON =
|
||||
XInternAtom(_glfw.x11.display, "_NET_WM_ICON", False);
|
||||
_glfw.x11.NET_WM_PING =
|
||||
@@ -457,12 +423,15 @@ static GLFWbool initExtensions(void)
|
||||
_glfw.x11.NET_WM_CM_Sx = XInternAtom(_glfw.x11.display, name, False);
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
// Detect whether an EWMH-conformant window manager is running
|
||||
detectEWMH();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Retrieve system content scale via folklore heuristics
|
||||
//
|
||||
void _glfwGetSystemContentScaleX11(float* xscale, float* yscale, GLFWbool bypass_cache)
|
||||
void _glfwGetSystemContentScaleX11(float* xscale, float* yscale, bool bypass_cache)
|
||||
{
|
||||
// NOTE: Default to the display-wide DPI as we don't currently have a policy
|
||||
// for which monitor a window is considered to be on
|
||||
@@ -536,7 +505,7 @@ static Window createHelperWindow(void)
|
||||
|
||||
// X error handler
|
||||
//
|
||||
static int errorHandler(Display *display, XErrorEvent* event)
|
||||
static int errorHandler(Display *display UNUSED, XErrorEvent* event)
|
||||
{
|
||||
_glfw.x11.errorCode = event->error_code;
|
||||
return 0;
|
||||
@@ -611,6 +580,7 @@ Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot)
|
||||
return cursor;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -620,13 +590,6 @@ int _glfwPlatformInit(void)
|
||||
XInitThreads();
|
||||
XrmInitialize();
|
||||
|
||||
if (pipe2(_glfw.x11.eventLoopData.wakeupFds, O_CLOEXEC | O_NONBLOCK) != 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: failed to create self pipe");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_glfw.x11.display = XOpenDisplay(NULL);
|
||||
if (!_glfw.x11.display)
|
||||
{
|
||||
@@ -642,10 +605,13 @@ int _glfwPlatformInit(void)
|
||||
"X11: The DISPLAY environment variable is missing");
|
||||
}
|
||||
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
initPollData(&_glfw.x11.eventLoopData, _glfw.x11.eventLoopData.wakeupFds[0], ConnectionNumber(_glfw.x11.display));
|
||||
if (!initPollData(&_glfw.x11.eventLoopData, ConnectionNumber(_glfw.x11.display))) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: Failed to initialize event loop data");
|
||||
}
|
||||
glfw_dbus_init(&_glfw.x11.dbus, &_glfw.x11.eventLoopData);
|
||||
|
||||
_glfw.x11.screen = DefaultScreen(_glfw.x11.display);
|
||||
@@ -654,10 +620,10 @@ int _glfwPlatformInit(void)
|
||||
_glfw.x11.RESOURCE_MANAGER = XInternAtom(_glfw.x11.display, "RESOURCE_MANAGER", True);
|
||||
XSelectInput(_glfw.x11.display, _glfw.x11.root, PropertyChangeMask);
|
||||
|
||||
_glfwGetSystemContentScaleX11(&_glfw.x11.contentScaleX, &_glfw.x11.contentScaleY, GLFW_FALSE);
|
||||
_glfwGetSystemContentScaleX11(&_glfw.x11.contentScaleX, &_glfw.x11.contentScaleY, false);
|
||||
|
||||
if (!initExtensions())
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
_glfw.x11.helperWindowHandle = createHelperWindow();
|
||||
_glfw.x11.hiddenCursorHandle = createHiddenCursor();
|
||||
@@ -665,7 +631,7 @@ int _glfwPlatformInit(void)
|
||||
#if defined(__linux__)
|
||||
if (_glfw.hints.init.enableJoysticks) {
|
||||
if (!_glfwInitJoysticksLinux())
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
if (_glfw.linjs.inotify > 0)
|
||||
addWatch(&_glfw.x11.eventLoopData, "joystick", _glfw.linjs.inotify, POLLIN, 1, NULL, NULL);
|
||||
}
|
||||
@@ -674,7 +640,7 @@ int _glfwPlatformInit(void)
|
||||
_glfwInitTimerPOSIX();
|
||||
|
||||
_glfwPollMonitorsX11();
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwPlatformTerminate(void)
|
||||
@@ -754,7 +720,7 @@ void _glfwPlatformTerminate(void)
|
||||
#if defined(__linux__)
|
||||
_glfwTerminateJoysticksLinux();
|
||||
#endif
|
||||
closeFds(_glfw.x11.eventLoopData.wakeupFds, sizeof(_glfw.x11.eventLoopData.wakeupFds)/sizeof(_glfw.x11.eventLoopData.wakeupFds[0]));
|
||||
finalizePollData(&_glfw.x11.eventLoopData);
|
||||
}
|
||||
|
||||
const char* _glfwPlatformGetVersionString(void)
|
||||
|
||||
106
glfw/x11_monitor.c
vendored
106
glfw/x11_monitor.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 X11 - www.glfw.org
|
||||
// GLFW 3.4 X11 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -35,7 +37,7 @@
|
||||
|
||||
// Check whether the display mode should be included in enumeration
|
||||
//
|
||||
static GLFWbool modeIsGood(const XRRModeInfo* mi)
|
||||
static bool modeIsGood(const XRRModeInfo* mi)
|
||||
{
|
||||
return (mi->modeFlags & RR_Interlace) == 0;
|
||||
}
|
||||
@@ -54,9 +56,7 @@ static int calculateRefreshRate(const XRRModeInfo* mi)
|
||||
//
|
||||
static const XRRModeInfo* getModeInfo(const XRRScreenResources* sr, RRMode id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sr->nmode; i++)
|
||||
for (int i = 0; i < sr->nmode; i++)
|
||||
{
|
||||
if (sr->modes[i].id == id)
|
||||
return sr->modes + i;
|
||||
@@ -102,7 +102,7 @@ void _glfwPollMonitorsX11(void)
|
||||
{
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||
{
|
||||
int i, j, disconnectedCount, screenCount = 0;
|
||||
int disconnectedCount, screenCount = 0;
|
||||
_GLFWmonitor** disconnected = NULL;
|
||||
XineramaScreenInfo* screens = NULL;
|
||||
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display,
|
||||
@@ -122,14 +122,11 @@ void _glfwPollMonitorsX11(void)
|
||||
_glfw.monitorCount * sizeof(_GLFWmonitor*));
|
||||
}
|
||||
|
||||
for (i = 0; i < sr->noutput; i++)
|
||||
for (int i = 0; i < sr->noutput; i++)
|
||||
{
|
||||
int type, widthMM, heightMM;
|
||||
XRROutputInfo* oi;
|
||||
XRRCrtcInfo* ci;
|
||||
_GLFWmonitor* monitor;
|
||||
int j, type, widthMM, heightMM;
|
||||
|
||||
oi = XRRGetOutputInfo(_glfw.x11.display, sr, sr->outputs[i]);
|
||||
XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, sr->outputs[i]);
|
||||
if (oi->connection != RR_Connected || oi->crtc == None)
|
||||
{
|
||||
XRRFreeOutputInfo(oi);
|
||||
@@ -152,7 +149,7 @@ void _glfwPollMonitorsX11(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, oi->crtc);
|
||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, oi->crtc);
|
||||
if (!ci)
|
||||
{
|
||||
XRRFreeOutputInfo(oi);
|
||||
@@ -169,7 +166,7 @@ void _glfwPollMonitorsX11(void)
|
||||
heightMM = oi->mm_height;
|
||||
}
|
||||
|
||||
monitor = _glfwAllocMonitor(oi->name, widthMM, heightMM);
|
||||
_GLFWmonitor* monitor = _glfwAllocMonitor(oi->name, widthMM, heightMM);
|
||||
monitor->x11.output = sr->outputs[i];
|
||||
monitor->x11.crtc = oi->crtc;
|
||||
|
||||
@@ -177,8 +174,8 @@ void _glfwPollMonitorsX11(void)
|
||||
{
|
||||
if (screens[j].x_org == ci->x &&
|
||||
screens[j].y_org == ci->y &&
|
||||
screens[j].width == ci->width &&
|
||||
screens[j].height == ci->height)
|
||||
screens[j].width == (short int)ci->width &&
|
||||
screens[j].height == (short int)ci->height)
|
||||
{
|
||||
monitor->x11.index = j;
|
||||
break;
|
||||
@@ -201,7 +198,7 @@ void _glfwPollMonitorsX11(void)
|
||||
if (screens)
|
||||
XFree(screens);
|
||||
|
||||
for (i = 0; i < disconnectedCount; i++)
|
||||
for (int i = 0; i < disconnectedCount; i++)
|
||||
{
|
||||
if (disconnected[i])
|
||||
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
||||
@@ -226,24 +223,19 @@ void _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
||||
{
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||
{
|
||||
XRRScreenResources* sr;
|
||||
XRRCrtcInfo* ci;
|
||||
XRROutputInfo* oi;
|
||||
GLFWvidmode current;
|
||||
const GLFWvidmode* best;
|
||||
RRMode native = None;
|
||||
int i;
|
||||
|
||||
best = _glfwChooseVideoMode(monitor, desired);
|
||||
const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired);
|
||||
_glfwPlatformGetVideoMode(monitor, ¤t);
|
||||
if (_glfwCompareVideoModes(¤t, best) == 0)
|
||||
return;
|
||||
|
||||
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
|
||||
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
|
||||
|
||||
for (i = 0; i < oi->nmode; i++)
|
||||
for (int i = 0; i < oi->nmode; i++)
|
||||
{
|
||||
const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]);
|
||||
if (!modeIsGood(mi))
|
||||
@@ -284,14 +276,11 @@ void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor)
|
||||
{
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||
{
|
||||
XRRScreenResources* sr;
|
||||
XRRCrtcInfo* ci;
|
||||
|
||||
if (monitor->x11.oldMode == None)
|
||||
return;
|
||||
|
||||
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
|
||||
XRRSetCrtcConfig(_glfw.x11.display,
|
||||
sr, monitor->x11.crtc,
|
||||
@@ -314,7 +303,7 @@ void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor)
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
|
||||
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -322,11 +311,9 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||
{
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||
{
|
||||
XRRScreenResources* sr;
|
||||
XRRCrtcInfo* ci;
|
||||
|
||||
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
if (ci)
|
||||
{
|
||||
if (xpos)
|
||||
@@ -340,7 +327,7 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
||||
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor UNUSED,
|
||||
float* xscale, float* yscale)
|
||||
{
|
||||
if (xscale)
|
||||
@@ -349,17 +336,15 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
||||
*yscale = _glfw.x11.contentScaleY;
|
||||
}
|
||||
|
||||
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height)
|
||||
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height)
|
||||
{
|
||||
int areaX = 0, areaY = 0, areaWidth = 0, areaHeight = 0;
|
||||
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||
{
|
||||
XRRScreenResources* sr;
|
||||
XRRCrtcInfo* ci;
|
||||
|
||||
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
|
||||
areaX = ci->x;
|
||||
areaY = ci->y;
|
||||
@@ -451,24 +436,20 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
||||
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||
{
|
||||
int i, j;
|
||||
XRRScreenResources* sr;
|
||||
XRRCrtcInfo* ci;
|
||||
XRROutputInfo* oi;
|
||||
|
||||
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
|
||||
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
|
||||
|
||||
result = calloc(oi->nmode, sizeof(GLFWvidmode));
|
||||
|
||||
for (i = 0; i < oi->nmode; i++)
|
||||
for (int i = 0; i < oi->nmode; i++)
|
||||
{
|
||||
const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]);
|
||||
if (!modeIsGood(mi))
|
||||
continue;
|
||||
|
||||
const GLFWvidmode mode = vidmodeFromModeInfo(mi, ci);
|
||||
int j;
|
||||
|
||||
for (j = 0; j < *count; j++)
|
||||
{
|
||||
@@ -502,11 +483,9 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
||||
{
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||
{
|
||||
XRRScreenResources* sr;
|
||||
XRRCrtcInfo* ci;
|
||||
|
||||
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
|
||||
if (ci) {
|
||||
const XRRModeInfo* mi = getModeInfo(sr, ci->mode);
|
||||
@@ -528,7 +507,7 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
||||
}
|
||||
}
|
||||
|
||||
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
{
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken)
|
||||
{
|
||||
@@ -544,7 +523,7 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
memcpy(ramp->blue, gamma->blue, size * sizeof(unsigned short));
|
||||
|
||||
XRRFreeGamma(gamma);
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
else if (_glfw.x11.vidmode.available)
|
||||
{
|
||||
@@ -556,13 +535,13 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
XF86VidModeGetGammaRamp(_glfw.x11.display,
|
||||
_glfw.x11.screen,
|
||||
ramp->size, ramp->red, ramp->green, ramp->blue);
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: Gamma ramp access not supported by server");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -570,7 +549,7 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||
{
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken)
|
||||
{
|
||||
if (XRRGetCrtcGammaSize(_glfw.x11.display, monitor->x11.crtc) != ramp->size)
|
||||
if (XRRGetCrtcGammaSize(_glfw.x11.display, monitor->x11.crtc) != (int)ramp->size)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: Gamma ramp size must match current ramp size");
|
||||
@@ -595,7 +574,8 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||
(unsigned short*) ramp->green,
|
||||
(unsigned short*) ramp->blue);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: Gamma ramp access not supported by server");
|
||||
}
|
||||
|
||||
31
glfw/x11_platform.h
vendored
31
glfw/x11_platform.h
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 X11 - www.glfw.org
|
||||
// GLFW 3.4 X11 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -182,11 +182,11 @@ typedef struct _GLFWwindowX11
|
||||
Colormap colormap;
|
||||
Window handle;
|
||||
|
||||
GLFWbool iconified;
|
||||
GLFWbool maximized;
|
||||
bool iconified;
|
||||
bool maximized;
|
||||
|
||||
// Whether the visual supports framebuffer transparency
|
||||
GLFWbool transparent;
|
||||
bool transparent;
|
||||
|
||||
// Cached position and size used to filter out duplicate events
|
||||
int width, height;
|
||||
@@ -227,6 +227,8 @@ typedef struct _GLFWlibraryX11
|
||||
_GLFWwindow* disabledCursorWindow;
|
||||
|
||||
// Window manager atoms
|
||||
Atom NET_SUPPORTED;
|
||||
Atom NET_SUPPORTING_WM_CHECK;
|
||||
Atom WM_PROTOCOLS;
|
||||
Atom WM_STATE;
|
||||
Atom WM_DELETE_WINDOW;
|
||||
@@ -284,14 +286,14 @@ typedef struct _GLFWlibraryX11
|
||||
Atom RESOURCE_MANAGER;
|
||||
|
||||
struct {
|
||||
GLFWbool available;
|
||||
bool available;
|
||||
void* handle;
|
||||
int eventBase;
|
||||
int errorBase;
|
||||
int major;
|
||||
int minor;
|
||||
GLFWbool gammaBroken;
|
||||
GLFWbool monitorBroken;
|
||||
bool gammaBroken;
|
||||
bool monitorBroken;
|
||||
PFN_XRRAllocGamma AllocGamma;
|
||||
PFN_XRRFreeCrtcInfo FreeCrtcInfo;
|
||||
PFN_XRRFreeGamma FreeGamma;
|
||||
@@ -336,7 +338,7 @@ typedef struct _GLFWlibraryX11
|
||||
} xcursor;
|
||||
|
||||
struct {
|
||||
GLFWbool available;
|
||||
bool available;
|
||||
void* handle;
|
||||
int major;
|
||||
int minor;
|
||||
@@ -346,7 +348,7 @@ typedef struct _GLFWlibraryX11
|
||||
} xinerama;
|
||||
|
||||
struct {
|
||||
GLFWbool available;
|
||||
bool available;
|
||||
void* handle;
|
||||
int eventBase;
|
||||
int errorBase;
|
||||
@@ -357,7 +359,7 @@ typedef struct _GLFWlibraryX11
|
||||
} vidmode;
|
||||
|
||||
struct {
|
||||
GLFWbool available;
|
||||
bool available;
|
||||
void* handle;
|
||||
int majorOpcode;
|
||||
int eventBase;
|
||||
@@ -369,7 +371,7 @@ typedef struct _GLFWlibraryX11
|
||||
} xi;
|
||||
|
||||
struct {
|
||||
GLFWbool available;
|
||||
bool available;
|
||||
void* handle;
|
||||
int major;
|
||||
int minor;
|
||||
@@ -406,6 +408,7 @@ typedef struct _GLFWcursorX11
|
||||
|
||||
} _GLFWcursorX11;
|
||||
|
||||
|
||||
void _glfwPollMonitorsX11(void);
|
||||
void _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
||||
void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor);
|
||||
@@ -416,11 +419,11 @@ unsigned long _glfwGetWindowPropertyX11(Window window,
|
||||
Atom property,
|
||||
Atom type,
|
||||
unsigned char** value);
|
||||
GLFWbool _glfwIsVisualTransparentX11(Visual* visual);
|
||||
bool _glfwIsVisualTransparentX11(Visual* visual);
|
||||
|
||||
void _glfwGrabErrorHandlerX11(void);
|
||||
void _glfwReleaseErrorHandlerX11(void);
|
||||
void _glfwInputErrorX11(int error, const char* message);
|
||||
|
||||
void _glfwGetSystemContentScaleX11(float* xscale, float* yscale, GLFWbool bypass_cache);
|
||||
void _glfwGetSystemContentScaleX11(float* xscale, float* yscale, bool bypass_cache);
|
||||
void _glfwPushSelectionToManagerX11(void);
|
||||
|
||||
244
glfw/x11_window.c
vendored
244
glfw/x11_window.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 X11 - www.glfw.org
|
||||
// GLFW 3.4 X11 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include "internal.h"
|
||||
@@ -51,6 +53,7 @@
|
||||
|
||||
#define _GLFW_XDND_VERSION 5
|
||||
|
||||
|
||||
// Wait for data to arrive using poll
|
||||
// This avoids blocking other threads via the per-display Xlib lock that also
|
||||
// covers GLX functions
|
||||
@@ -70,25 +73,26 @@ handleEvents(double timeout) {
|
||||
glfw_ibus_dispatch(&_glfw.x11.xkb.ibus);
|
||||
glfw_dbus_session_bus_dispatch();
|
||||
EVDBG("other dispatch done");
|
||||
if (_glfw.x11.eventLoopData.wakeup_fd_ready) check_for_wakeup_events(&_glfw.x11.eventLoopData);
|
||||
}
|
||||
|
||||
static GLFWbool
|
||||
static bool
|
||||
waitForX11Event(double timeout) {
|
||||
// returns true iff there is X11 data waiting to be read, does not run watches and timers
|
||||
// returns true if there is X11 data waiting to be read, does not run watches and timers
|
||||
double end_time = glfwGetTime() + timeout;
|
||||
while(GLFW_TRUE) {
|
||||
while(true) {
|
||||
if (timeout >= 0) {
|
||||
const int result = pollWithTimeout(_glfw.x11.eventLoopData.fds, 1, timeout);
|
||||
if (result > 0) return GLFW_TRUE;
|
||||
if (result > 0) return true;
|
||||
timeout = end_time - glfwGetTime();
|
||||
if (timeout <= 0) return GLFW_FALSE;
|
||||
if (timeout <= 0) return false;
|
||||
if (result < 0 && (errno == EINTR || errno == EAGAIN)) continue;
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
} else {
|
||||
const int result = poll(_glfw.x11.eventLoopData.fds, 1, -1);
|
||||
if (result > 0) return GLFW_TRUE;
|
||||
if (result > 0) return true;
|
||||
if (result < 0 && (errno == EINTR || errno == EAGAIN)) continue;
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -96,7 +100,7 @@ waitForX11Event(double timeout) {
|
||||
// Waits until a VisibilityNotify event arrives for the specified window or the
|
||||
// timeout period elapses (ICCCM section 4.2.2)
|
||||
//
|
||||
static GLFWbool waitForVisibilityNotify(_GLFWwindow* window)
|
||||
static bool waitForVisibilityNotify(_GLFWwindow* window)
|
||||
{
|
||||
XEvent dummy;
|
||||
|
||||
@@ -106,10 +110,10 @@ static GLFWbool waitForVisibilityNotify(_GLFWwindow* window)
|
||||
&dummy))
|
||||
{
|
||||
if (!waitForX11Event(0.1))
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns whether the window is iconified
|
||||
@@ -138,7 +142,7 @@ static int getWindowState(_GLFWwindow* window)
|
||||
|
||||
// Returns whether the event is a selection event
|
||||
//
|
||||
static Bool isSelectionEvent(Display* display, XEvent* event, XPointer pointer)
|
||||
static Bool isSelectionEvent(Display* display UNUSED, XEvent* event, XPointer pointer UNUSED)
|
||||
{
|
||||
if (event->xany.window != _glfw.x11.helperWindowHandle)
|
||||
return False;
|
||||
@@ -150,7 +154,7 @@ static Bool isSelectionEvent(Display* display, XEvent* event, XPointer pointer)
|
||||
|
||||
// Returns whether it is a _NET_FRAME_EXTENTS event for the specified window
|
||||
//
|
||||
static Bool isFrameExtentsEvent(Display* display, XEvent* event, XPointer pointer)
|
||||
static Bool isFrameExtentsEvent(Display* display UNUSED, XEvent* event, XPointer pointer)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) pointer;
|
||||
return event->type == PropertyNotify &&
|
||||
@@ -161,7 +165,7 @@ static Bool isFrameExtentsEvent(Display* display, XEvent* event, XPointer pointe
|
||||
|
||||
// Returns whether it is a property event for the specified selection transfer
|
||||
//
|
||||
static Bool isSelPropNewValueNotify(Display* display, XEvent* event, XPointer pointer)
|
||||
static Bool isSelPropNewValueNotify(Display* display UNUSED, XEvent* event, XPointer pointer)
|
||||
{
|
||||
XEvent* notification = (XEvent*) pointer;
|
||||
return event->type == PropertyNotify &&
|
||||
@@ -197,10 +201,7 @@ static int translateState(int state)
|
||||
static void sendEventToWM(_GLFWwindow* window, Atom type,
|
||||
long a, long b, long c, long d, long e)
|
||||
{
|
||||
XEvent event;
|
||||
memset(&event, 0, sizeof(event));
|
||||
|
||||
event.type = ClientMessage;
|
||||
XEvent event = { ClientMessage };
|
||||
event.xclient.window = window->x11.handle;
|
||||
event.xclient.format = 32; // Data is 32-bit longs
|
||||
event.xclient.message_type = type;
|
||||
@@ -270,7 +271,7 @@ is_window_fullscreen(_GLFWwindow* window)
|
||||
{
|
||||
Atom* states;
|
||||
unsigned long i;
|
||||
GLFWbool ans = GLFW_FALSE;
|
||||
bool ans = false;
|
||||
if (!_glfw.x11.NET_WM_STATE || !_glfw.x11.NET_WM_STATE_FULLSCREEN)
|
||||
return ans;
|
||||
const unsigned long count =
|
||||
@@ -283,7 +284,7 @@ is_window_fullscreen(_GLFWwindow* window)
|
||||
{
|
||||
if (states[i] == _glfw.x11.NET_WM_STATE_FULLSCREEN)
|
||||
{
|
||||
ans = GLFW_TRUE;
|
||||
ans = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -328,8 +329,7 @@ set_fullscreen(_GLFWwindow *window, bool on) {
|
||||
}
|
||||
|
||||
bool
|
||||
_glfwPlatformToggleFullscreen(_GLFWwindow *window, unsigned int flags) {
|
||||
(void) flags;
|
||||
_glfwPlatformToggleFullscreen(_GLFWwindow *window, unsigned int flags UNUSED) {
|
||||
bool already_fullscreen = is_window_fullscreen(window);
|
||||
set_fullscreen(window, !already_fullscreen);
|
||||
return !already_fullscreen;
|
||||
@@ -499,7 +499,7 @@ static void enableCursor(_GLFWwindow* window)
|
||||
|
||||
// Create the X11 window (and its colormap)
|
||||
//
|
||||
static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||
static bool createNativeWindow(_GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig,
|
||||
Visual* visual, int depth)
|
||||
{
|
||||
@@ -551,7 +551,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputErrorX11(GLFW_PLATFORM_ERROR,
|
||||
"X11: Failed to create window");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
XSaveContext(_glfw.x11.display,
|
||||
@@ -561,7 +561,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||
}
|
||||
|
||||
if (!wndconfig->decorated)
|
||||
_glfwPlatformSetWindowDecorated(window, GLFW_FALSE);
|
||||
_glfwPlatformSetWindowDecorated(window, false);
|
||||
|
||||
if (_glfw.x11.NET_WM_STATE && !window->monitor)
|
||||
{
|
||||
@@ -581,7 +581,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||
{
|
||||
states[count++] = _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT;
|
||||
states[count++] = _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ;
|
||||
window->x11.maximized = GLFW_TRUE;
|
||||
window->x11.maximized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -630,7 +630,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_OUT_OF_MEMORY,
|
||||
"X11: Failed to allocate WM hints");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
hints->flags = StateHint;
|
||||
@@ -684,7 +684,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||
_glfwPlatformGetWindowPos(window, &window->x11.xpos, &window->x11.ypos);
|
||||
_glfwPlatformGetWindowSize(window, &window->x11.width, &window->x11.height);
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Set the specified property to the selection converted to the requested target
|
||||
@@ -841,11 +841,8 @@ static void handleSelectionRequest(XEvent* event)
|
||||
{
|
||||
const XSelectionRequestEvent* request = &event->xselectionrequest;
|
||||
|
||||
XEvent reply;
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
|
||||
XEvent reply = { SelectionNotify };
|
||||
reply.xselection.property = writeTargetToProperty(request);
|
||||
reply.xselection.type = SelectionNotify;
|
||||
reply.xselection.display = request->display;
|
||||
reply.xselection.requestor = request->requestor;
|
||||
reply.xselection.selection = request->selection;
|
||||
@@ -857,7 +854,6 @@ static void handleSelectionRequest(XEvent* event)
|
||||
|
||||
static const char* getSelectionString(Atom selection)
|
||||
{
|
||||
size_t i;
|
||||
char** selectionString = NULL;
|
||||
const Atom targets[] = { _glfw.x11.UTF8_STRING, XA_STRING };
|
||||
const size_t targetCount = sizeof(targets) / sizeof(targets[0]);
|
||||
@@ -878,7 +874,7 @@ static const char* getSelectionString(Atom selection)
|
||||
free(*selectionString);
|
||||
*selectionString = NULL;
|
||||
|
||||
for (i = 0; i < targetCount; i++)
|
||||
for (size_t i = 0; i < targetCount; i++)
|
||||
{
|
||||
char* data;
|
||||
Atom actualType;
|
||||
@@ -1056,7 +1052,7 @@ static void releaseMonitor(_GLFWwindow* window)
|
||||
static void onConfigChange(void)
|
||||
{
|
||||
float xscale, yscale;
|
||||
_glfwGetSystemContentScaleX11(&xscale, &yscale, GLFW_TRUE);
|
||||
_glfwGetSystemContentScaleX11(&xscale, &yscale, true);
|
||||
|
||||
if (xscale != _glfw.x11.contentScaleX || yscale != _glfw.x11.contentScaleY)
|
||||
{
|
||||
@@ -1075,9 +1071,8 @@ static void onConfigChange(void)
|
||||
//
|
||||
static void processEvent(XEvent *event)
|
||||
{
|
||||
_GLFWwindow* window = NULL;
|
||||
static GLFWbool keymap_dirty = GLFW_FALSE;
|
||||
#define UPDATE_KEYMAP_IF_NEEDED if (keymap_dirty) { keymap_dirty = GLFW_FALSE; glfw_xkb_compile_keymap(&_glfw.x11.xkb, NULL); }
|
||||
static bool keymap_dirty = false;
|
||||
#define UPDATE_KEYMAP_IF_NEEDED if (keymap_dirty) { keymap_dirty = false; glfw_xkb_compile_keymap(&_glfw.x11.xkb, NULL); }
|
||||
|
||||
if (_glfw.x11.randr.available)
|
||||
{
|
||||
@@ -1153,7 +1148,7 @@ static void processEvent(XEvent *event)
|
||||
/* fallthrough */
|
||||
case XkbMapNotify:
|
||||
{
|
||||
keymap_dirty = GLFW_TRUE;
|
||||
keymap_dirty = true;
|
||||
return;
|
||||
}
|
||||
case XkbStateNotify:
|
||||
@@ -1170,6 +1165,7 @@ static void processEvent(XEvent *event)
|
||||
return;
|
||||
}
|
||||
|
||||
_GLFWwindow* window = NULL;
|
||||
if (XFindContext(_glfw.x11.display,
|
||||
event->xany.window,
|
||||
_glfw.x11.context,
|
||||
@@ -1310,7 +1306,7 @@ static void processEvent(XEvent *event)
|
||||
if (window->cursorMode == GLFW_CURSOR_HIDDEN)
|
||||
updateCursorImage(window);
|
||||
|
||||
_glfwInputCursorEnter(window, GLFW_TRUE);
|
||||
_glfwInputCursorEnter(window, true);
|
||||
_glfwInputCursorPos(window, x, y);
|
||||
|
||||
window->x11.lastCursorPosX = x;
|
||||
@@ -1320,7 +1316,7 @@ static void processEvent(XEvent *event)
|
||||
|
||||
case LeaveNotify:
|
||||
{
|
||||
_glfwInputCursorEnter(window, GLFW_FALSE);
|
||||
_glfwInputCursorEnter(window, false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1430,7 +1426,7 @@ static void processEvent(XEvent *event)
|
||||
// A drag operation has entered the window
|
||||
unsigned long i, count;
|
||||
Atom* formats = NULL;
|
||||
const GLFWbool list = event->xclient.data.l[1] & 1;
|
||||
const bool list = event->xclient.data.l[1] & 1;
|
||||
|
||||
_glfw.x11.xdnd.source = event->xclient.data.l[0];
|
||||
_glfw.x11.xdnd.version = event->xclient.data.l[1] >> 24;
|
||||
@@ -1487,10 +1483,7 @@ static void processEvent(XEvent *event)
|
||||
}
|
||||
else if (_glfw.x11.xdnd.version >= 2)
|
||||
{
|
||||
XEvent reply;
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
|
||||
reply.type = ClientMessage;
|
||||
XEvent reply = { ClientMessage };
|
||||
reply.xclient.window = _glfw.x11.xdnd.source;
|
||||
reply.xclient.message_type = _glfw.x11.XdndFinished;
|
||||
reply.xclient.format = 32;
|
||||
@@ -1523,10 +1516,7 @@ static void processEvent(XEvent *event)
|
||||
|
||||
_glfwInputCursorPos(window, xpos, ypos);
|
||||
|
||||
XEvent reply;
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
|
||||
reply.type = ClientMessage;
|
||||
XEvent reply = { ClientMessage };
|
||||
reply.xclient.window = _glfw.x11.xdnd.source;
|
||||
reply.xclient.message_type = _glfw.x11.XdndStatus;
|
||||
reply.xclient.format = 32;
|
||||
@@ -1579,10 +1569,7 @@ static void processEvent(XEvent *event)
|
||||
|
||||
if (_glfw.x11.xdnd.version >= 2)
|
||||
{
|
||||
XEvent reply;
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
|
||||
reply.type = ClientMessage;
|
||||
XEvent reply = { ClientMessage };
|
||||
reply.xclient.window = _glfw.x11.xdnd.source;
|
||||
reply.xclient.message_type = _glfw.x11.XdndFinished;
|
||||
reply.xclient.format = 32;
|
||||
@@ -1601,9 +1588,6 @@ static void processEvent(XEvent *event)
|
||||
|
||||
case FocusIn:
|
||||
{
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
disableCursor(window);
|
||||
|
||||
if (event->xfocus.mode == NotifyGrab ||
|
||||
event->xfocus.mode == NotifyUngrab)
|
||||
{
|
||||
@@ -1612,15 +1596,15 @@ static void processEvent(XEvent *event)
|
||||
return;
|
||||
}
|
||||
|
||||
_glfwInputWindowFocus(window, GLFW_TRUE);
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
disableCursor(window);
|
||||
|
||||
_glfwInputWindowFocus(window, true);
|
||||
return;
|
||||
}
|
||||
|
||||
case FocusOut:
|
||||
{
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
enableCursor(window);
|
||||
|
||||
if (event->xfocus.mode == NotifyGrab ||
|
||||
event->xfocus.mode == NotifyUngrab)
|
||||
{
|
||||
@@ -1629,10 +1613,13 @@ static void processEvent(XEvent *event)
|
||||
return;
|
||||
}
|
||||
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
enableCursor(window);
|
||||
|
||||
if (window->monitor && window->autoIconify)
|
||||
_glfwPlatformIconifyWindow(window);
|
||||
|
||||
_glfwInputWindowFocus(window, GLFW_FALSE);
|
||||
_glfwInputWindowFocus(window, false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1653,7 +1640,7 @@ static void processEvent(XEvent *event)
|
||||
if (state != IconicState && state != NormalState)
|
||||
return;
|
||||
|
||||
const GLFWbool iconified = (state == IconicState);
|
||||
const bool iconified = (state == IconicState);
|
||||
if (window->x11.iconified != iconified)
|
||||
{
|
||||
if (window->monitor)
|
||||
@@ -1670,7 +1657,7 @@ static void processEvent(XEvent *event)
|
||||
}
|
||||
else if (event->xproperty.atom == _glfw.x11.NET_WM_STATE)
|
||||
{
|
||||
const GLFWbool maximized = _glfwPlatformWindowMaximized(window);
|
||||
const bool maximized = _glfwPlatformWindowMaximized(window);
|
||||
if (window->x11.maximized != maximized)
|
||||
{
|
||||
window->x11.maximized = maximized;
|
||||
@@ -1720,10 +1707,10 @@ unsigned long _glfwGetWindowPropertyX11(Window window,
|
||||
return itemCount;
|
||||
}
|
||||
|
||||
GLFWbool _glfwIsVisualTransparentX11(Visual* visual)
|
||||
bool _glfwIsVisualTransparentX11(Visual* visual)
|
||||
{
|
||||
if (!_glfw.x11.xrender.available)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
XRenderPictFormat* pf = XRenderFindVisualFormat(_glfw.x11.display, visual);
|
||||
return pf && pf->direct.alphaMask;
|
||||
@@ -1795,21 +1782,21 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
|
||||
{
|
||||
if (!_glfwInitGLX())
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
if (!_glfwChooseVisualGLX(wndconfig, ctxconfig, fbconfig, &visual, &depth))
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
|
||||
{
|
||||
if (!_glfwInitEGL())
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
if (!_glfwChooseVisualEGL(wndconfig, ctxconfig, fbconfig, &visual, &depth))
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
|
||||
{
|
||||
if (!_glfwInitOSMesa())
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1821,24 +1808,24 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
}
|
||||
|
||||
if (!createNativeWindow(window, wndconfig, visual, depth))
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
if (ctxconfig->client != GLFW_NO_API)
|
||||
{
|
||||
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
|
||||
{
|
||||
if (!_glfwCreateContextGLX(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
|
||||
{
|
||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
|
||||
{
|
||||
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1850,7 +1837,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
}
|
||||
|
||||
XFlush(_glfw.x11.display);
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
@@ -2025,8 +2012,8 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
|
||||
int minwidth, int minheight,
|
||||
int maxwidth, int maxheight)
|
||||
int minwidth UNUSED, int minheight UNUSED,
|
||||
int maxwidth UNUSED, int maxheight UNUSED)
|
||||
{
|
||||
int width, height;
|
||||
_glfwPlatformGetWindowSize(window, &width, &height);
|
||||
@@ -2034,7 +2021,7 @@ void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
|
||||
XFlush(_glfw.x11.display);
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)
|
||||
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer UNUSED, int denom UNUSED)
|
||||
{
|
||||
int width, height;
|
||||
_glfwPlatformGetWindowSize(window, &width, &height);
|
||||
@@ -2107,7 +2094,7 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
||||
XFree(extents);
|
||||
}
|
||||
|
||||
void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
|
||||
void _glfwPlatformGetWindowContentScale(_GLFWwindow* window UNUSED,
|
||||
float* xscale, float* yscale)
|
||||
{
|
||||
if (xscale)
|
||||
@@ -2116,7 +2103,7 @@ void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
|
||||
*yscale = _glfw.x11.contentScaleY;
|
||||
}
|
||||
|
||||
double _glfwPlatformGetDoubleClickInterval(_GLFWwindow* window)
|
||||
double _glfwPlatformGetDoubleClickInterval(_GLFWwindow* window UNUSED)
|
||||
{
|
||||
return 0.5;
|
||||
}
|
||||
@@ -2194,7 +2181,7 @@ void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
|
||||
|
||||
int _glfwPlatformWindowBell(_GLFWwindow* window)
|
||||
{
|
||||
return XkbBell(_glfw.x11.display, window->x11.handle, 100, (Atom)0) ? GLFW_TRUE : GLFW_FALSE;
|
||||
return XkbBell(_glfw.x11.display, window->x11.handle, 100, (Atom)0) ? true : false;
|
||||
}
|
||||
|
||||
void _glfwPlatformFocusWindow(_GLFWwindow* window)
|
||||
@@ -2215,7 +2202,7 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
||||
_GLFWmonitor* monitor,
|
||||
int xpos, int ypos,
|
||||
int width, int height,
|
||||
int refreshRate)
|
||||
int refreshRate UNUSED)
|
||||
{
|
||||
if (window->monitor == monitor)
|
||||
{
|
||||
@@ -2245,13 +2232,14 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
||||
|
||||
if (window->monitor)
|
||||
{
|
||||
if (!_glfwPlatformWindowVisible(window))
|
||||
{
|
||||
XMapRaised(_glfw.x11.display, window->x11.handle);
|
||||
waitForVisibilityNotify(window);
|
||||
}
|
||||
updateWindowMode(window);
|
||||
acquireMonitor(window);
|
||||
if (!_glfwPlatformWindowVisible(window))
|
||||
{
|
||||
XMapRaised(_glfw.x11.display, window->x11.handle);
|
||||
waitForVisibilityNotify(window);
|
||||
}
|
||||
|
||||
updateWindowMode(window);
|
||||
acquireMonitor(window);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2272,9 +2260,9 @@ int _glfwPlatformWindowFocused(_GLFWwindow* window)
|
||||
return window->x11.handle == focused;
|
||||
}
|
||||
|
||||
int _glfwPlatformWindowOccluded(_GLFWwindow* window)
|
||||
int _glfwPlatformWindowOccluded(_GLFWwindow* window UNUSED)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
int _glfwPlatformWindowIconified(_GLFWwindow* window)
|
||||
@@ -2293,11 +2281,14 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
||||
{
|
||||
Atom* states;
|
||||
unsigned long i;
|
||||
GLFWbool maximized = GLFW_FALSE;
|
||||
bool maximized = false;
|
||||
|
||||
if (!_glfw.x11.NET_WM_STATE ||
|
||||
!_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT ||
|
||||
!_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
|
||||
!_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT ||
|
||||
!_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
|
||||
{
|
||||
return maximized;
|
||||
}
|
||||
const unsigned long count =
|
||||
_glfwGetWindowPropertyX11(window->x11.handle,
|
||||
_glfw.x11.NET_WM_STATE,
|
||||
@@ -2309,7 +2300,7 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
||||
if (states[i] == _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT ||
|
||||
states[i] == _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
|
||||
{
|
||||
maximized = GLFW_TRUE;
|
||||
maximized = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2332,32 +2323,32 @@ int _glfwPlatformWindowHovered(_GLFWwindow* window)
|
||||
if (!XQueryPointer(_glfw.x11.display, w,
|
||||
&root, &w, &rootX, &rootY, &childX, &childY, &mask))
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (w == window->x11.handle)
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
|
||||
{
|
||||
if (!window->x11.transparent)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
return XGetSelectionOwner(_glfw.x11.display, _glfw.x11.NET_WM_CM_Sx) != None;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, bool enabled UNUSED)
|
||||
{
|
||||
int width, height;
|
||||
_glfwPlatformGetWindowSize(window, &width, &height);
|
||||
updateNormalHints(window, width, height);
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
|
||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, bool enabled)
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
@@ -2388,7 +2379,7 @@ void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, bool enabled)
|
||||
{
|
||||
if (!_glfw.x11.NET_WM_STATE || !_glfw.x11.NET_WM_STATE_ABOVE)
|
||||
return;
|
||||
@@ -2485,14 +2476,12 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
|
||||
}
|
||||
|
||||
static inline unsigned
|
||||
dispatch_x11_queued_events(void) {
|
||||
unsigned dispatched = 0;
|
||||
while (XQLength(_glfw.x11.display) > 0)
|
||||
{
|
||||
dispatch_x11_queued_events(int num_events) {
|
||||
unsigned dispatched = num_events > 0 ? num_events : 0;
|
||||
while (num_events-- > 0) {
|
||||
XEvent event;
|
||||
XNextEvent(_glfw.x11.display, &event);
|
||||
processEvent(&event);
|
||||
dispatched += 1;
|
||||
}
|
||||
return dispatched;
|
||||
}
|
||||
@@ -2503,10 +2492,9 @@ _glfwDispatchX11Events(void) {
|
||||
unsigned dispatched = 0;
|
||||
|
||||
#if defined(__linux__)
|
||||
_glfwDetectJoystickConnectionLinux();
|
||||
if (_glfw.hints.init.enableJoysticks) _glfwDetectJoystickConnectionLinux();
|
||||
#endif
|
||||
XPending(_glfw.x11.display);
|
||||
dispatched += dispatch_x11_queued_events();
|
||||
dispatched += dispatch_x11_queued_events(XEventsQueued(_glfw.x11.display, QueuedAfterFlush));
|
||||
|
||||
window = _glfw.x11.disabledCursorWindow;
|
||||
if (window)
|
||||
@@ -2524,8 +2512,10 @@ _glfwDispatchX11Events(void) {
|
||||
}
|
||||
|
||||
XFlush(_glfw.x11.display);
|
||||
// XFlush can cause events to be queued
|
||||
dispatched += dispatch_x11_queued_events();
|
||||
// XFlush can cause events to be queued, we don't use QueuedAfterFlush here
|
||||
// as something might have inserted events into the queue, but we want to guarantee
|
||||
// a flush.
|
||||
dispatched += dispatch_x11_queued_events(XEventsQueued(_glfw.x11.display, QueuedAlready));
|
||||
return dispatched;
|
||||
}
|
||||
|
||||
@@ -2549,7 +2539,7 @@ void _glfwPlatformWaitEventsTimeout(double timeout)
|
||||
|
||||
void _glfwPlatformPostEmptyEvent(void)
|
||||
{
|
||||
while (write(_glfw.x11.eventLoopData.wakeupFds[1], "w", 1) < 0 && errno == EINTR);
|
||||
wakeupEventLoop(&_glfw.x11.eventLoopData);
|
||||
}
|
||||
|
||||
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
|
||||
@@ -2608,13 +2598,13 @@ int _glfwPlatformGetKeyScancode(int key)
|
||||
|
||||
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
||||
const GLFWimage* image,
|
||||
int xhot, int yhot, int count)
|
||||
int xhot, int yhot, int count UNUSED)
|
||||
{
|
||||
cursor->x11.handle = _glfwCreateCursorX11(image, xhot, yhot);
|
||||
if (!cursor->x11.handle)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, GLFWCursorShape shape)
|
||||
@@ -2633,7 +2623,7 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, GLFWCursorShape shape
|
||||
C(GLFW_SW_RESIZE_CURSOR, XC_bottom_left_corner);
|
||||
C(GLFW_SE_RESIZE_CURSOR, XC_bottom_right_corner);
|
||||
case GLFW_INVALID_CURSOR:
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
#undef C
|
||||
|
||||
@@ -2642,10 +2632,10 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, GLFWCursorShape shape
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: Failed to create standard cursor");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
||||
@@ -2654,7 +2644,7 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
||||
XFreeCursor(_glfw.x11.display, cursor->x11.handle);
|
||||
}
|
||||
|
||||
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
||||
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor UNUSED)
|
||||
{
|
||||
if (window->cursorMode == GLFW_CURSOR_NORMAL)
|
||||
{
|
||||
@@ -2747,7 +2737,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"X11: Vulkan instance missing VK_KHR_xcb_surface extension");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
xcb_connection_t* connection = XGetXCBConnection(_glfw.x11.display);
|
||||
@@ -2755,7 +2745,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: Failed to retrieve XCB connection");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
return vkGetPhysicalDeviceXcbPresentationSupportKHR(device,
|
||||
@@ -2773,7 +2763,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"X11: Vulkan instance missing VK_KHR_xlib_surface extension");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
return vkGetPhysicalDeviceXlibPresentationSupportKHR(device,
|
||||
@@ -2880,7 +2870,7 @@ GLFWAPI Window glfwGetX11Window(GLFWwindow* handle)
|
||||
return window->x11.handle;
|
||||
}
|
||||
|
||||
GLFWAPI int glfwGetXKBScancode(const char* keyName, GLFWbool caseSensitive) {
|
||||
GLFWAPI int glfwGetXKBScancode(const char* keyName, bool caseSensitive) {
|
||||
return glfw_xkb_keysym_from_name(keyName, caseSensitive);
|
||||
}
|
||||
|
||||
|
||||
59
glfw/xkb_glfw.c
vendored
59
glfw/xkb_glfw.c
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 XKB - www.glfw.org
|
||||
// GLFW 3.4 XKB - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2018 Kovid Goyal <kovid@kovidgoyal.net>
|
||||
//
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <stdlib.h>
|
||||
#include "internal.h"
|
||||
#include "xkb_glfw.h"
|
||||
START_ALLOW_CASE_RANGE
|
||||
|
||||
#define debug(...) if (_glfw.hints.init.debugKeyboard) printf(__VA_ARGS__);
|
||||
|
||||
@@ -47,6 +48,7 @@
|
||||
S(backslash, BACKSLASH); \
|
||||
S(bracketright, RIGHT_BRACKET); \
|
||||
S(plus, PLUS); \
|
||||
S(underscore, UNDERSCORE); \
|
||||
S(grave, GRAVE_ACCENT); \
|
||||
S(Escape, ESCAPE); \
|
||||
S(Return, ENTER); \
|
||||
@@ -100,7 +102,7 @@ glfw_key_for_sym(xkb_keysym_t key) {
|
||||
#define S(f, t) case XKB_KEY_##f: return GLFW_KEY_##t
|
||||
#define F(f, t) S(f, t)
|
||||
#define R(s, e, gs, ...) case XKB_KEY_##s ... XKB_KEY_##e: return GLFW_KEY_##gs + key - XKB_KEY_##s
|
||||
#define D(s, e, gs, ...) R(s, e, gs)
|
||||
#define D(s, e, gs, ...) R(s, e, gs, __VA_ARGS__)
|
||||
map_key(key)
|
||||
S(KP_Up, UP);
|
||||
S(KP_Down, DOWN);
|
||||
@@ -114,7 +116,7 @@ glfw_key_for_sym(xkb_keysym_t key) {
|
||||
#undef D
|
||||
#undef R
|
||||
#undef S
|
||||
};
|
||||
}
|
||||
|
||||
xkb_keysym_t
|
||||
glfw_xkb_sym_for_key(int key) {
|
||||
@@ -132,33 +134,34 @@ glfw_xkb_sym_for_key(int key) {
|
||||
#undef R
|
||||
#undef S
|
||||
}
|
||||
END_ALLOW_CASE_RANGE
|
||||
|
||||
#ifdef _GLFW_X11
|
||||
|
||||
GLFWbool
|
||||
bool
|
||||
glfw_xkb_set_x11_events_mask(void) {
|
||||
if (!XkbSelectEvents(_glfw.x11.display, XkbUseCoreKbd, XkbNewKeyboardNotifyMask | XkbMapNotifyMask | XkbStateNotifyMask, XkbNewKeyboardNotifyMask | XkbMapNotifyMask | XkbStateNotifyMask)) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to set XKB events mask");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
GLFWbool
|
||||
bool
|
||||
glfw_xkb_update_x11_keyboard_id(_GLFWXKBData *xkb) {
|
||||
xkb->keyboard_device_id = -1;
|
||||
xcb_connection_t* conn = XGetXCBConnection(_glfw.x11.display);
|
||||
if (!conn) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to retrieve XCB connection");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
xkb->keyboard_device_id = xkb_x11_get_core_keyboard_device_id(conn);
|
||||
if (xkb->keyboard_device_id == -1) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to retrieve core keyboard device id");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
#define xkb_glfw_load_keymap(keymap, ...) {\
|
||||
@@ -166,7 +169,7 @@ glfw_xkb_update_x11_keyboard_id(_GLFWXKBData *xkb) {
|
||||
if (conn) keymap = xkb_x11_keymap_new_from_device(xkb->context, conn, xkb->keyboard_device_id, XKB_KEYMAP_COMPILE_NO_FLAGS); \
|
||||
}
|
||||
|
||||
#define xkb_glfw_load_state(keymap, state, ...) {\
|
||||
#define xkb_glfw_load_state(keymap, state) {\
|
||||
xcb_connection_t* conn = XGetXCBConnection(_glfw.x11.display); \
|
||||
if (conn) state = xkb_x11_state_new_from_device(keymap, conn, xkb->keyboard_device_id); \
|
||||
}
|
||||
@@ -174,7 +177,7 @@ glfw_xkb_update_x11_keyboard_id(_GLFWXKBData *xkb) {
|
||||
#else
|
||||
|
||||
#define xkb_glfw_load_keymap(keymap, map_str) keymap = xkb_keymap_new_from_string(xkb->context, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, 0);
|
||||
#define xkb_glfw_load_state(keymap, state, ...) state = xkb_state_new(keymap);
|
||||
#define xkb_glfw_load_state(keymap, state) state = xkb_state_new(keymap);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -203,17 +206,17 @@ glfw_xkb_release(_GLFWXKBData *xkb) {
|
||||
glfw_ibus_terminate(&xkb->ibus);
|
||||
}
|
||||
|
||||
GLFWbool
|
||||
bool
|
||||
glfw_xkb_create_context(_GLFWXKBData *xkb) {
|
||||
xkb->context = xkb_context_new(0);
|
||||
if (!xkb->context)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Failed to initialize XKB context");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
glfw_connect_to_ibus(&xkb->ibus);
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
static const char*
|
||||
@@ -259,7 +262,7 @@ load_compose_tables(_GLFWXKBData *xkb) {
|
||||
xkb_compose_table_unref(compose_table);
|
||||
}
|
||||
|
||||
GLFWbool
|
||||
bool
|
||||
glfw_xkb_compile_keymap(_GLFWXKBData *xkb, const char *map_str) {
|
||||
const char *err;
|
||||
release_keyboard_data(xkb);
|
||||
@@ -267,13 +270,13 @@ glfw_xkb_compile_keymap(_GLFWXKBData *xkb, const char *map_str) {
|
||||
if (err) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "%s", err);
|
||||
release_keyboard_data(xkb);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
err = load_states(xkb);
|
||||
if (err) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "%s", err);
|
||||
release_keyboard_data(xkb);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
load_compose_tables(xkb);
|
||||
#define S(a, n) xkb->a##Idx = xkb_keymap_mod_get_index(xkb->keymap, n); xkb->a##Mask = 1 << xkb->a##Idx;
|
||||
@@ -291,7 +294,7 @@ glfw_xkb_compile_keymap(_GLFWXKBData *xkb, const char *map_str) {
|
||||
}
|
||||
xkb->states.modifiers = 0;
|
||||
xkb->states.activeUnknownModifiers = 0;
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline xkb_mod_mask_t
|
||||
@@ -325,7 +328,7 @@ glfw_xkb_update_modifiers(_GLFWXKBData *xkb, xkb_mod_mask_t depressed, xkb_mod_m
|
||||
update_modifiers(xkb, &xkb->states);
|
||||
}
|
||||
|
||||
GLFWbool
|
||||
bool
|
||||
glfw_xkb_should_repeat(_GLFWXKBData *xkb, xkb_keycode_t scancode) {
|
||||
#ifdef _GLFW_WAYLAND
|
||||
scancode += 8;
|
||||
@@ -334,7 +337,7 @@ glfw_xkb_should_repeat(_GLFWXKBData *xkb, xkb_keycode_t scancode) {
|
||||
}
|
||||
|
||||
|
||||
static KeyEvent key_event = {};
|
||||
static KeyEvent key_event = {0};
|
||||
|
||||
static inline xkb_keysym_t
|
||||
compose_symbol(struct xkb_compose_state *composeState, xkb_keysym_t sym, int *compose_completed) {
|
||||
@@ -365,7 +368,7 @@ glfw_xkb_keysym_name(xkb_keysym_t sym) {
|
||||
}
|
||||
|
||||
int
|
||||
glfw_xkb_keysym_from_name(const char *name, GLFWbool case_sensitive) {
|
||||
glfw_xkb_keysym_from_name(const char *name, bool case_sensitive) {
|
||||
return (int)xkb_keysym_from_name(name, case_sensitive ? XKB_KEYSYM_NO_FLAGS : XKB_KEYSYM_CASE_INSENSITIVE);
|
||||
}
|
||||
|
||||
@@ -412,7 +415,7 @@ glfw_xkb_update_ime_state(_GLFWwindow *w, _GLFWXKBData *xkb, int which, int a, i
|
||||
int x = 0, y = 0;
|
||||
switch(which) {
|
||||
case 1:
|
||||
glfw_ibus_set_focused(&xkb->ibus, a ? GLFW_TRUE : GLFW_FALSE);
|
||||
glfw_ibus_set_focused(&xkb->ibus, a ? true : false);
|
||||
break;
|
||||
case 2:
|
||||
_glfwPlatformGetWindowPos(w, &x, &y);
|
||||
@@ -423,7 +426,7 @@ glfw_xkb_update_ime_state(_GLFWwindow *w, _GLFWXKBData *xkb, int which, int a, i
|
||||
}
|
||||
|
||||
void
|
||||
glfw_xkb_key_from_ime(KeyEvent *ev, GLFWbool handled_by_ime, GLFWbool failed) {
|
||||
glfw_xkb_key_from_ime(KeyEvent *ev, bool handled_by_ime, bool failed) {
|
||||
_GLFWwindow *window = _glfwWindowForId(ev->window_id);
|
||||
if (failed && window && window->callbacks.keyboard) {
|
||||
// notify application to remove any existing pre-edit text
|
||||
@@ -431,12 +434,12 @@ glfw_xkb_key_from_ime(KeyEvent *ev, GLFWbool handled_by_ime, GLFWbool failed) {
|
||||
}
|
||||
static xkb_keycode_t last_handled_press_keycode = 0;
|
||||
// We filter out release events that correspond to the last press event
|
||||
// handled by the IME system. This wont fix the case of multiple key
|
||||
// handled by the IME system. This won't fix the case of multiple key
|
||||
// presses before a release, but is better than nothing. For that case
|
||||
// you'd need to implement a ring buffer to store pending key presses.
|
||||
xkb_keycode_t prev_handled_press = last_handled_press_keycode;
|
||||
last_handled_press_keycode = 0;
|
||||
GLFWbool is_release = ev->action == GLFW_RELEASE;
|
||||
bool is_release = ev->action == GLFW_RELEASE;
|
||||
debug("From IBUS: scancode: 0x%x name: %s is_release: %d\n", ev->keycode, glfw_xkb_keysym_name(ev->keysym), is_release);
|
||||
if (window && !handled_by_ime && !(is_release && ev->keycode == prev_handled_press)) {
|
||||
debug("↳ to application: glfw_keycode: 0x%x (%s) keysym: 0x%x (%s) action: %s %s text: %s\n",
|
||||
@@ -499,13 +502,13 @@ glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t
|
||||
if (key_event.text[0]) { debug("%s: %s ", text_type, key_event.text); }
|
||||
}
|
||||
int glfw_keycode = glfw_key_for_sym(glfw_sym);
|
||||
GLFWbool is_fallback = GLFW_FALSE;
|
||||
bool is_fallback = false;
|
||||
if (glfw_keycode == GLFW_KEY_UNKNOWN && !key_event.text[0]) {
|
||||
int num_default_syms = xkb_state_key_get_syms(sg->default_state, code_for_sym, &default_syms);
|
||||
if (num_default_syms > 0) {
|
||||
glfw_sym = default_syms[0];
|
||||
glfw_keycode = glfw_key_for_sym(glfw_sym);
|
||||
is_fallback = GLFW_TRUE;
|
||||
is_fallback = true;
|
||||
}
|
||||
}
|
||||
debug(
|
||||
|
||||
20
glfw/xkb_glfw.h
vendored
20
glfw/xkb_glfw.h
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 XKB - www.glfw.org
|
||||
// GLFW 3.4 XKB - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2018 Kovid Goyal <kovid@kovidgoyal.net>
|
||||
//
|
||||
@@ -67,8 +67,8 @@ typedef struct {
|
||||
|
||||
#ifdef _GLFW_X11
|
||||
int32_t keyboard_device_id;
|
||||
GLFWbool available;
|
||||
GLFWbool detectable;
|
||||
bool available;
|
||||
bool detectable;
|
||||
int majorOpcode;
|
||||
int eventBase;
|
||||
int errorBase;
|
||||
@@ -79,18 +79,18 @@ typedef struct {
|
||||
} _GLFWXKBData;
|
||||
|
||||
#ifdef _GLFW_X11
|
||||
GLFWbool glfw_xkb_set_x11_events_mask(void);
|
||||
GLFWbool glfw_xkb_update_x11_keyboard_id(_GLFWXKBData *xkb);
|
||||
bool glfw_xkb_set_x11_events_mask(void);
|
||||
bool glfw_xkb_update_x11_keyboard_id(_GLFWXKBData *xkb);
|
||||
#endif
|
||||
|
||||
void glfw_xkb_release(_GLFWXKBData *xkb);
|
||||
GLFWbool glfw_xkb_create_context(_GLFWXKBData *xkb);
|
||||
GLFWbool glfw_xkb_compile_keymap(_GLFWXKBData *xkb, const char *map_str);
|
||||
bool glfw_xkb_create_context(_GLFWXKBData *xkb);
|
||||
bool glfw_xkb_compile_keymap(_GLFWXKBData *xkb, const char *map_str);
|
||||
void glfw_xkb_update_modifiers(_GLFWXKBData *xkb, xkb_mod_mask_t depressed, xkb_mod_mask_t latched, xkb_mod_mask_t locked, xkb_layout_index_t base_group, xkb_layout_index_t latched_group, xkb_layout_index_t locked_group);
|
||||
GLFWbool glfw_xkb_should_repeat(_GLFWXKBData *xkb, xkb_keycode_t scancode);
|
||||
bool glfw_xkb_should_repeat(_GLFWXKBData *xkb, xkb_keycode_t scancode);
|
||||
const char* glfw_xkb_keysym_name(xkb_keysym_t sym);
|
||||
xkb_keysym_t glfw_xkb_sym_for_key(int key);
|
||||
void glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t scancode, int action);
|
||||
int glfw_xkb_keysym_from_name(const char *name, GLFWbool case_sensitive);
|
||||
int glfw_xkb_keysym_from_name(const char *name, bool case_sensitive);
|
||||
void glfw_xkb_update_ime_state(_GLFWwindow *w, _GLFWXKBData *xkb, int which, int a, int b, int c, int d);
|
||||
void glfw_xkb_key_from_ime(KeyEvent *ev, GLFWbool handled_by_ime, GLFWbool failed);
|
||||
void glfw_xkb_key_from_ime(KeyEvent *ev, bool handled_by_ime, bool failed);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import os
|
||||
from contextlib import suppress
|
||||
|
||||
from kitty.cli import parse_args
|
||||
from kitty.constants import cache_dir
|
||||
@@ -27,10 +28,8 @@ class HistoryCompleter:
|
||||
self.history_path = None
|
||||
if name:
|
||||
ddir = os.path.join(cache_dir(), 'ask')
|
||||
try:
|
||||
with suppress(FileExistsError):
|
||||
os.makedirs(ddir)
|
||||
except FileExistsError:
|
||||
pass
|
||||
self.history_path = os.path.join(ddir, name)
|
||||
|
||||
def complete(self, text, state):
|
||||
@@ -50,10 +49,8 @@ class HistoryCompleter:
|
||||
|
||||
def __enter__(self):
|
||||
if self.history_path:
|
||||
try:
|
||||
with suppress(Exception):
|
||||
readline.read_history_file(self.history_path)
|
||||
except Exception:
|
||||
pass
|
||||
readline.set_completer(self.complete)
|
||||
return self
|
||||
|
||||
@@ -106,10 +103,8 @@ def main(args):
|
||||
print(styled(args.message, bold=True))
|
||||
|
||||
prompt = '> '
|
||||
try:
|
||||
with suppress(KeyboardInterrupt, EOFError):
|
||||
ans['response'] = input(prompt)
|
||||
except (KeyboardInterrupt, EOFError):
|
||||
pass
|
||||
return ans
|
||||
|
||||
|
||||
|
||||
@@ -25,9 +25,9 @@ static inline ssize_t ms_write(int fd, const void* buf, size_t count) { return _
|
||||
|
||||
static inline bool
|
||||
ensure_space(GlobalData *global, size_t sz) {
|
||||
if (global->output_sz < sz + global->output_pos) {
|
||||
if (global->output_sz < sz + global->output_pos || !global->output) {
|
||||
size_t before = global->output_sz;
|
||||
global->output_sz += MAX(sz, (64 * 1024));
|
||||
global->output_sz += MAX(sz, (64u * 1024u));
|
||||
global->output = realloc(global->output, sizeof(text_t) * global->output_sz);
|
||||
if (!global->output) {
|
||||
global->output_sz = before;
|
||||
|
||||
@@ -22,6 +22,12 @@ class Clipboard(Handler):
|
||||
if self.data_to_send is not None:
|
||||
self.cmd.write_to_clipboard(self.data_to_send, self.args.use_primary)
|
||||
if not self.args.get_clipboard:
|
||||
if self.args.wait_for_completion:
|
||||
# ask kitty for the TN terminfo capability and
|
||||
# only quit after a response is received
|
||||
self.print('\x1bP+q544e\x1b\\', end='')
|
||||
self.print('Waiting for completion...')
|
||||
return
|
||||
self.quit_loop(0)
|
||||
return
|
||||
self.cmd.request_from_clipboard(self.args.use_primary)
|
||||
@@ -30,6 +36,15 @@ class Clipboard(Handler):
|
||||
self.clipboard_contents = text
|
||||
self.quit_loop(0)
|
||||
|
||||
def on_capability_response(self, name, val):
|
||||
self.quit_loop(0)
|
||||
|
||||
def on_interrupt(self):
|
||||
self.quit_loop(1)
|
||||
|
||||
def on_eot(self):
|
||||
self.quit_loop(1)
|
||||
|
||||
|
||||
OPTIONS = r'''
|
||||
--get-clipboard
|
||||
@@ -45,6 +60,13 @@ default=False
|
||||
type=bool-set
|
||||
Use the primary selection rather than the clipboard on systems that support it,
|
||||
such as X11.
|
||||
|
||||
|
||||
--wait-for-completion
|
||||
default=False
|
||||
type=bool-set
|
||||
Wait till the copy to clipboard is complete before exiting. Useful if running
|
||||
the kitten in a dedicated, ephemeral window.
|
||||
'''.format
|
||||
help_text = '''\
|
||||
Read or write to the system clipboard.
|
||||
@@ -54,6 +76,7 @@ To set the clipboard text, pipe in the new text on stdin. Use the
|
||||
:file:`stdout`. Note that you must enable reading of clipboard in
|
||||
:file:`kitty.conf` first.
|
||||
'''
|
||||
|
||||
usage = ''
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import re
|
||||
from functools import lru_cache
|
||||
from hashlib import md5
|
||||
from mimetypes import guess_type
|
||||
from contextlib import suppress
|
||||
|
||||
path_name_map = {}
|
||||
|
||||
@@ -140,10 +141,8 @@ def is_image(path):
|
||||
def data_for_path(path):
|
||||
ans = raw_data_for_path(path)
|
||||
if not is_image(path) and not os.path.samefile(path, os.devnull):
|
||||
try:
|
||||
with suppress(UnicodeDecodeError):
|
||||
ans = ans.decode('utf-8')
|
||||
except UnicodeDecodeError:
|
||||
pass
|
||||
return ans
|
||||
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import warnings
|
||||
from collections import defaultdict
|
||||
from functools import partial
|
||||
from gettext import gettext as _
|
||||
from contextlib import suppress
|
||||
|
||||
from kitty.cli import CONFIG_HELP, parse_args
|
||||
from kitty.constants import appname
|
||||
@@ -511,10 +512,8 @@ usage = 'file_or_directory_left file_or_directory_right'
|
||||
|
||||
def terminate_processes(processes):
|
||||
for pid in processes:
|
||||
try:
|
||||
with suppress(Exception):
|
||||
os.kill(pid, signal.SIGKILL)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def main(args):
|
||||
|
||||
@@ -20,7 +20,7 @@ from ..tui.loop import Loop
|
||||
from ..tui.operations import faint, styled
|
||||
|
||||
URL_PREFIXES = 'http https file ftp'.split()
|
||||
HINT_ALPHABET = string.digits + string.ascii_lowercase
|
||||
DEFAULT_HINT_ALPHABET = string.digits + string.ascii_lowercase
|
||||
screen_size = screen_size_function()
|
||||
|
||||
|
||||
@@ -34,21 +34,26 @@ class Mark:
|
||||
|
||||
|
||||
@lru_cache(maxsize=2048)
|
||||
def encode_hint(num):
|
||||
def encode_hint(num, alphabet):
|
||||
res = ''
|
||||
d = len(HINT_ALPHABET)
|
||||
d = len(alphabet)
|
||||
while not res or num > 0:
|
||||
num, i = divmod(num, d)
|
||||
res = HINT_ALPHABET[i] + res
|
||||
res = alphabet[i] + res
|
||||
return res
|
||||
|
||||
|
||||
def decode_hint(x):
|
||||
return int(x, 36)
|
||||
def decode_hint(x, alphabet=DEFAULT_HINT_ALPHABET):
|
||||
base = len(alphabet)
|
||||
index_map = {c: i for i, c in enumerate(alphabet)}
|
||||
i = 0
|
||||
for char in x:
|
||||
i = i * base + index_map[char]
|
||||
return i
|
||||
|
||||
|
||||
def highlight_mark(m, text, current_input):
|
||||
hint = encode_hint(m.index)
|
||||
def highlight_mark(m, text, current_input, alphabet):
|
||||
hint = encode_hint(m.index, alphabet)
|
||||
if current_input and not hint.startswith(current_input):
|
||||
return faint(text)
|
||||
hint = hint[len(current_input):] or ' '
|
||||
@@ -63,11 +68,11 @@ def highlight_mark(m, text, current_input):
|
||||
)
|
||||
|
||||
|
||||
def render(text, current_input, all_marks, ignore_mark_indices):
|
||||
def render(text, current_input, all_marks, ignore_mark_indices, alphabet):
|
||||
for mark in reversed(all_marks):
|
||||
if mark.index in ignore_mark_indices:
|
||||
continue
|
||||
mtext = highlight_mark(mark, text[mark.start:mark.end], current_input)
|
||||
mtext = highlight_mark(mark, text[mark.start:mark.end], current_input, alphabet)
|
||||
text = text[:mark.start] + mtext + text[mark.end:]
|
||||
|
||||
text = text.replace('\0', '')
|
||||
@@ -79,6 +84,7 @@ class Hints(Handler):
|
||||
|
||||
def __init__(self, text, all_marks, index_map, args):
|
||||
self.text, self.index_map = text, index_map
|
||||
self.alphabet = args.alphabet or DEFAULT_HINT_ALPHABET
|
||||
self.all_marks = all_marks
|
||||
self.ignore_mark_indices = set()
|
||||
self.args = args
|
||||
@@ -111,13 +117,13 @@ class Hints(Handler):
|
||||
def on_text(self, text, in_bracketed_paste):
|
||||
changed = False
|
||||
for c in text:
|
||||
if c in HINT_ALPHABET:
|
||||
if c in self.alphabet:
|
||||
self.current_input += c
|
||||
changed = True
|
||||
if changed:
|
||||
matches = [
|
||||
m for idx, m in self.index_map.items()
|
||||
if encode_hint(idx).startswith(self.current_input)
|
||||
if encode_hint(idx, self.alphabet).startswith(self.current_input)
|
||||
]
|
||||
if len(matches) == 1:
|
||||
self.chosen.append(matches[0].text + self.match_suffix)
|
||||
@@ -137,7 +143,7 @@ class Hints(Handler):
|
||||
self.draw_screen()
|
||||
elif key_event is enter_key and self.current_input:
|
||||
try:
|
||||
idx = decode_hint(self.current_input)
|
||||
idx = decode_hint(self.current_input, self.alphabet)
|
||||
self.chosen.append(self.index_map[idx].text + self.match_suffix)
|
||||
self.ignore_mark_indices.add(idx)
|
||||
except Exception:
|
||||
@@ -164,7 +170,7 @@ class Hints(Handler):
|
||||
|
||||
def draw_screen(self):
|
||||
if self.current_text is None:
|
||||
self.current_text = render(self.text, self.current_input, self.all_marks, self.ignore_mark_indices)
|
||||
self.current_text = render(self.text, self.current_input, self.all_marks, self.ignore_mark_indices, self.alphabet)
|
||||
self.cmd.clear_screen()
|
||||
self.write(self.current_text)
|
||||
|
||||
@@ -213,7 +219,7 @@ def url(text, s, e):
|
||||
@postprocessor
|
||||
def brackets(text, s, e):
|
||||
# Remove matching brackets
|
||||
if e > s and e <= len(text):
|
||||
if s < e <= len(text):
|
||||
before = text[s]
|
||||
if before in '({[<' and text[e-1] == closing_bracket_map[before]:
|
||||
s += 1
|
||||
@@ -224,7 +230,7 @@ def brackets(text, s, e):
|
||||
@postprocessor
|
||||
def quotes(text, s, e):
|
||||
# Remove matching quotes
|
||||
if e > s and e <= len(text):
|
||||
if s < e <= len(text):
|
||||
before = text[s]
|
||||
if before in '\'"' and text[e-1] == before:
|
||||
s += 1
|
||||
@@ -246,7 +252,9 @@ def run_loop(args, text, all_marks, index_map):
|
||||
handler = Hints(text, all_marks, index_map, args)
|
||||
loop.loop(handler)
|
||||
if handler.chosen and loop.return_code == 0:
|
||||
return {'match': handler.chosen, 'program': args.program}
|
||||
return {'match': handler.chosen, 'programs': args.program,
|
||||
'multiple_joiner': args.multiple_joiner,
|
||||
'type': args.type}
|
||||
raise SystemExit(loop.return_code)
|
||||
|
||||
|
||||
@@ -331,10 +339,12 @@ def run(args, text):
|
||||
# CLI {{{
|
||||
OPTIONS = r'''
|
||||
--program
|
||||
default=default
|
||||
type=list
|
||||
What program to use to open matched text. Defaults to the default open program
|
||||
for the operating system. Use a value of :file:`-` to paste the match into the
|
||||
for the operating system. Use a value of :file:`-` to paste the match into the
|
||||
terminal window instead. A value of :file:`@` will copy the match to the clipboard.
|
||||
A value of :file:`default` will run the default open program. Can be specified
|
||||
multiple times to run multiple programs.
|
||||
|
||||
|
||||
--type
|
||||
@@ -346,9 +356,11 @@ The type of text to search for.
|
||||
--regex
|
||||
default=(?m)^\s*(.+)\s*$
|
||||
The regular expression to use when :option:`kitty +kitten hints --type`=regex.
|
||||
If you specify a group in the regular expression only the group
|
||||
will be matched. This allow you to match text ignoring a prefix/suffix, as
|
||||
needed. The default expression matches lines.
|
||||
The regular expression is in python syntax. If you specify a group in
|
||||
the regular expression only the group will be matched. This allow you to match
|
||||
text ignoring a prefix/suffix, as needed. The default expression matches lines.
|
||||
To match text over multiple lines you should prefix the regular expression with
|
||||
:code:`(?ms)`, which turns on MULTILINE and DOTALL modes for the regex engine.
|
||||
|
||||
|
||||
--url-prefixes
|
||||
@@ -358,7 +370,7 @@ Comma separated list of recognized URL prefixes.
|
||||
|
||||
--word-characters
|
||||
Characters to consider as part of a word. In addition, all characters marked as
|
||||
alpha-numeric in the unicode database will be considered as word characters.
|
||||
alphanumeric in the unicode database will be considered as word characters.
|
||||
Defaults to the select_by_word_characters setting from kitty.conf.
|
||||
|
||||
|
||||
@@ -374,6 +386,17 @@ Select multiple matches and perform the action on all of them together at the en
|
||||
In this mode, press :kbd:`Esc` to finish selecting.
|
||||
|
||||
|
||||
--multiple-joiner
|
||||
default=auto
|
||||
String to use to join multiple selections when copying to the clipboard or
|
||||
inserting into the terminal. The special strings: "space", "newline", "empty",
|
||||
"json" and "auto" are interpreted as a space character, a newline an empty
|
||||
joiner, a JSON serialized list and an automatic choice, based on the type of
|
||||
text being selected. In addition, integers are interpreted as zero-based
|
||||
indices into the list of selections. You can use 0 for the first selection and
|
||||
-1 for the last.
|
||||
|
||||
|
||||
--add-trailing-space
|
||||
default=auto
|
||||
choices=auto,always,never
|
||||
@@ -386,6 +409,15 @@ default=1
|
||||
type=int
|
||||
The offset (from zero) at which to start hint numbering. Note that only numbers
|
||||
greater than or equal to zero are respected.
|
||||
|
||||
|
||||
--alphabet
|
||||
The list of characters to use for hints. The default is to use numbers and lowercase
|
||||
English alphabets. Specify your preference as a string of characters. Note that
|
||||
unless you specify the hints offset as zero the first match will be highlighted with
|
||||
the second character you specify.
|
||||
|
||||
|
||||
'''.format(','.join(sorted(URL_PREFIXES))).format
|
||||
help_text = 'Select text from the screen using the keyboard. Defaults to searching for URLs.'
|
||||
usage = ''
|
||||
@@ -415,28 +447,50 @@ def main(args):
|
||||
if items:
|
||||
print('Extra command line arguments present: {}'.format(' '.join(items)), file=sys.stderr)
|
||||
input(_('Press Enter to quit'))
|
||||
return
|
||||
return run(args, text)
|
||||
|
||||
|
||||
def handle_result(args, data, target_window_id, boss):
|
||||
program = data['program']
|
||||
programs = data['programs'] or ('default',)
|
||||
matches = tuple(filter(None, data['match']))
|
||||
if program == '-':
|
||||
w = boss.window_id_map.get(target_window_id)
|
||||
if w is not None:
|
||||
joiner = data['multiple_joiner']
|
||||
try:
|
||||
is_int = int(joiner)
|
||||
except Exception:
|
||||
is_int = None
|
||||
text_type = data['type']
|
||||
|
||||
@lru_cache()
|
||||
def joined_text():
|
||||
if is_int is not None:
|
||||
try:
|
||||
return matches[is_int]
|
||||
except IndexError:
|
||||
return matches[-1]
|
||||
if joiner == 'json':
|
||||
import json
|
||||
return json.dumps(matches, ensure_ascii=False, indent='\t')
|
||||
if joiner == 'auto':
|
||||
q = '\n\r' if text_type in ('line', 'url') else ' '
|
||||
else:
|
||||
q = {'newline': '\n\r', 'space': ' '}.get(joiner, '')
|
||||
return q.join(matches)
|
||||
|
||||
for program in programs:
|
||||
if program == '-':
|
||||
w = boss.window_id_map.get(target_window_id)
|
||||
if w is not None:
|
||||
w.paste(joined_text())
|
||||
elif program == '@':
|
||||
set_clipboard_string(joined_text())
|
||||
else:
|
||||
cwd = None
|
||||
w = boss.window_id_map.get(target_window_id)
|
||||
if w is not None:
|
||||
cwd = w.cwd_of_child
|
||||
program = None if program == 'default' else program
|
||||
for m in matches:
|
||||
w.paste(m)
|
||||
elif program == '@':
|
||||
set_clipboard_string(matches[-1])
|
||||
else:
|
||||
cwd = None
|
||||
w = boss.window_id_map.get(target_window_id)
|
||||
if w is not None:
|
||||
cwd = w.cwd_of_child
|
||||
program = None if program == 'default' else program
|
||||
for m in matches:
|
||||
boss.open_url(m, program, cwd=cwd)
|
||||
boss.open_url(m, program, cwd=cwd)
|
||||
|
||||
|
||||
handle_result.type_of_input = 'screen'
|
||||
|
||||
@@ -194,11 +194,13 @@ def process(path, args, is_tempfile):
|
||||
available_height = args.place.height * (ss.height / ss.rows) if args.place else 10 * m.height
|
||||
needs_scaling = m.width > available_width or m.height > available_height
|
||||
needs_scaling = needs_scaling or args.scale_up
|
||||
file_removed = False
|
||||
if m.fmt == 'png' and not needs_scaling:
|
||||
outfile = path
|
||||
transmit_mode = 't' if is_tempfile else 'f'
|
||||
fmt = 100
|
||||
width, height = m.width, m.height
|
||||
file_removed = transmit_mode == 't'
|
||||
else:
|
||||
fmt = 24 if m.mode == 'rgb' else 32
|
||||
transmit_mode = 't'
|
||||
@@ -206,6 +208,7 @@ def process(path, args, is_tempfile):
|
||||
show(outfile, width, height, fmt, transmit_mode, align=args.align, place=args.place)
|
||||
if not args.place:
|
||||
print() # ensure cursor is on a new line
|
||||
return file_removed
|
||||
|
||||
|
||||
def scan(d):
|
||||
@@ -270,15 +273,16 @@ help_text = (
|
||||
usage = 'image-file-or-url-or-directory ...'
|
||||
|
||||
|
||||
def process_single_item(item, args, url_pat, maybe_dir=True):
|
||||
def process_single_item(item, args, url_pat=None, maybe_dir=True):
|
||||
is_tempfile = False
|
||||
file_removed = False
|
||||
try:
|
||||
if isinstance(item, bytes):
|
||||
tf = NamedTemporaryFile(prefix='stdin-image-data-', delete=False)
|
||||
tf.write(item), tf.close()
|
||||
item = tf.name
|
||||
is_tempfile = True
|
||||
if url_pat.match(item) is not None:
|
||||
if url_pat is not None and url_pat.match(item) is not None:
|
||||
from urllib.request import urlretrieve
|
||||
with NamedTemporaryFile(prefix='url-image-data-', delete=False) as tf:
|
||||
try:
|
||||
@@ -287,7 +291,7 @@ def process_single_item(item, args, url_pat, maybe_dir=True):
|
||||
raise SystemExit('Failed to download image at URL: {} with error: {}'.format(item, e))
|
||||
item = tf.name
|
||||
is_tempfile = True
|
||||
process(item, args, is_tempfile)
|
||||
file_removed = process(item, args, is_tempfile)
|
||||
elif item.lower().startswith('file://'):
|
||||
from urllib.parse import urlparse
|
||||
from urllib.request import url2pathname
|
||||
@@ -297,15 +301,15 @@ def process_single_item(item, args, url_pat, maybe_dir=True):
|
||||
else:
|
||||
item = item.path
|
||||
item = url2pathname(item)
|
||||
process(item, args, is_tempfile)
|
||||
file_removed = process(item, args, is_tempfile)
|
||||
else:
|
||||
if maybe_dir and os.path.isdir(item):
|
||||
for x in scan(item):
|
||||
process_single_item(item, args, url_pat, maybe_dir=False)
|
||||
for (x, mt) in scan(item):
|
||||
process_single_item(x, args, url_pat=None, maybe_dir=False)
|
||||
else:
|
||||
process(item, args, is_tempfile)
|
||||
file_removed = process(item, args, is_tempfile)
|
||||
finally:
|
||||
if is_tempfile:
|
||||
if is_tempfile and not file_removed:
|
||||
os.remove(item)
|
||||
|
||||
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from kitty.cli import parse_args
|
||||
from kitty.constants import is_macos, is_wayland
|
||||
from kitty.constants import is_macos
|
||||
|
||||
OPTIONS = r'''
|
||||
--lines
|
||||
@@ -121,7 +122,7 @@ def initial_window_size_func(opts, *a):
|
||||
|
||||
def main(sys_args):
|
||||
global args
|
||||
if is_macos or is_wayland:
|
||||
if is_macos or not os.environ.get('DISPLAY'):
|
||||
raise SystemExit('Currently the panel kitten is supported only on X11 desktops')
|
||||
if not shutil.which('xprop'):
|
||||
raise SystemExit('The xprop program is required for the panel kitten')
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import importlib
|
||||
import os
|
||||
import sys
|
||||
from contextlib import suppress
|
||||
from functools import partial
|
||||
|
||||
aliases = {'url_hints': 'hints'}
|
||||
@@ -15,13 +16,18 @@ def resolved_kitten(k):
|
||||
return aliases.get(k, k).replace('-', '_')
|
||||
|
||||
|
||||
def path_to_custom_kitten(config_dir, kitten):
|
||||
path = os.path.expanduser(kitten)
|
||||
if not os.path.isabs(path):
|
||||
path = os.path.join(config_dir, path)
|
||||
path = os.path.abspath(path)
|
||||
return path
|
||||
|
||||
|
||||
def import_kitten_main_module(config_dir, kitten):
|
||||
if kitten.endswith('.py'):
|
||||
path_modified = False
|
||||
path = os.path.expanduser(kitten)
|
||||
if not os.path.isabs(path):
|
||||
path = os.path.join(config_dir, path)
|
||||
path = os.path.abspath(path)
|
||||
path = path_to_custom_kitten(config_dir, kitten)
|
||||
if os.path.dirname(path):
|
||||
sys.path.insert(0, os.path.dirname(path))
|
||||
path_modified = True
|
||||
@@ -90,12 +96,24 @@ def deserialize(output):
|
||||
|
||||
def run_kitten(kitten, run_name='__main__'):
|
||||
import runpy
|
||||
original_kitten_name = kitten
|
||||
kitten = resolved_kitten(kitten)
|
||||
set_debug(kitten)
|
||||
try:
|
||||
with suppress(ImportError):
|
||||
runpy.run_module('kittens.{}.main'.format(kitten), run_name=run_name)
|
||||
except ImportError:
|
||||
raise SystemExit('No kitten named {}'.format(kitten))
|
||||
return
|
||||
# Look for a custom kitten
|
||||
if not kitten.endswith('.py'):
|
||||
kitten += '.py'
|
||||
from kitty.constants import config_dir
|
||||
path = path_to_custom_kitten(config_dir, kitten)
|
||||
if not os.path.exists(path):
|
||||
print('Available builtin kittens:', file=sys.stderr)
|
||||
for kitten in all_kitten_names():
|
||||
print(kitten, file=sys.stderr)
|
||||
raise SystemExit('No kitten named {}'.format(original_kitten_name))
|
||||
m = runpy.run_path(path, init_globals={'sys': sys, 'os': os}, run_name='__run_kitten__')
|
||||
m['main'](sys.argv)
|
||||
|
||||
|
||||
def all_kitten_names():
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
import os
|
||||
import re
|
||||
import shlex
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
@@ -93,6 +94,18 @@ def parse_ssh_args(args):
|
||||
return ssh_args, server_args, passthrough
|
||||
|
||||
|
||||
def quote(x):
|
||||
# we have to escape unbalanced quotes and other unparsable
|
||||
# args as they will break the shell script
|
||||
# But we do not want to quote things like * or 'echo hello'
|
||||
# See https://github.com/kovidgoyal/kitty/issues/1787
|
||||
try:
|
||||
shlex.split(x)
|
||||
except ValueError:
|
||||
x = shlex.quote(x)
|
||||
return x
|
||||
|
||||
|
||||
def main(args):
|
||||
ssh_args, server_args, passthrough = parse_ssh_args(args[1:])
|
||||
if passthrough:
|
||||
@@ -101,7 +114,7 @@ def main(args):
|
||||
terminfo = subprocess.check_output(['infocmp']).decode('utf-8')
|
||||
sh_script = SHELL_SCRIPT.replace('TERMINFO', terminfo, 1)
|
||||
if len(server_args) > 1:
|
||||
command_to_execute = ["'{}'".format(c.replace("'", """'"'"'""")) for c in server_args[1:]]
|
||||
command_to_execute = [quote(c) for c in server_args[1:]]
|
||||
command_to_execute = 'exec ' + ' '.join(command_to_execute)
|
||||
else:
|
||||
command_to_execute = ''
|
||||
|
||||
@@ -84,6 +84,9 @@ class Handler:
|
||||
def on_clipboard_response(self, text, from_primary=False):
|
||||
pass
|
||||
|
||||
def on_capability_response(self, name, val):
|
||||
pass
|
||||
|
||||
def write(self, data):
|
||||
if isinstance(data, str):
|
||||
data = data.encode('utf-8')
|
||||
|
||||
@@ -8,6 +8,7 @@ import sys
|
||||
from base64 import standard_b64encode
|
||||
from collections import defaultdict, deque
|
||||
from itertools import count
|
||||
from contextlib import suppress
|
||||
|
||||
from kitty.utils import fit_image
|
||||
|
||||
@@ -172,10 +173,8 @@ class ImageManager:
|
||||
if in_flight:
|
||||
pl = in_flight.popleft()
|
||||
if payload.startswith('ENOENT:'):
|
||||
try:
|
||||
with suppress(Exception):
|
||||
self.resend_image(image_id, pl)
|
||||
except Exception:
|
||||
pass
|
||||
if not in_flight:
|
||||
self.placements_in_flight.pop(image_id, None)
|
||||
|
||||
@@ -250,7 +249,8 @@ class ImageManager:
|
||||
cmd, standard_b64encode(rgba_path.encode(fsenc)))
|
||||
else:
|
||||
import zlib
|
||||
data = open(rgba_path, 'rb').read()
|
||||
with open(rgba_path, 'rb') as f:
|
||||
data = f.read()
|
||||
cmd['S'] = len(data)
|
||||
data = zlib.compress(data)
|
||||
cmd['o'] = 'z'
|
||||
|
||||
@@ -214,9 +214,20 @@ class Loop:
|
||||
self.handler.on_text(chunk, self.in_bracketed_paste)
|
||||
|
||||
def _on_dcs(self, dcs):
|
||||
debug(dcs)
|
||||
if dcs.startswith('@kitty-cmd'):
|
||||
import json
|
||||
self.handler.on_kitty_cmd_response(json.loads(dcs[len('@kitty-cmd'):]))
|
||||
elif dcs.startswith('1+r'):
|
||||
from binascii import unhexlify
|
||||
vals = dcs[3:].split(';')
|
||||
for q in vals:
|
||||
parts = q.split('=', 1)
|
||||
try:
|
||||
name, val = parts[0], unhexlify(parts[1]).decode('utf-8', 'replace')
|
||||
except Exception:
|
||||
continue
|
||||
self.handler.on_capability_response(name, val)
|
||||
|
||||
def _on_csi(self, csi):
|
||||
q = csi[-1]
|
||||
|
||||
@@ -7,6 +7,7 @@ import string
|
||||
import subprocess
|
||||
from functools import lru_cache
|
||||
from gettext import gettext as _
|
||||
from contextlib import suppress
|
||||
|
||||
from kitty.config import cached_values_for
|
||||
from kitty.constants import config_dir
|
||||
@@ -239,11 +240,10 @@ class Table:
|
||||
|
||||
|
||||
def is_index(w):
|
||||
try:
|
||||
with suppress(Exception):
|
||||
int(w.lstrip(INDEX_CHAR), 16)
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
return False
|
||||
|
||||
|
||||
class UnicodeInput(Handler):
|
||||
@@ -293,24 +293,21 @@ class UnicodeInput(Handler):
|
||||
self.update_codepoints()
|
||||
self.current_char = None
|
||||
if self.mode is HEX:
|
||||
try:
|
||||
if self.line_edit.current_input.startswith(INDEX_CHAR) and len(self.line_edit.current_input) > 1:
|
||||
self.current_char = chr(self.table.codepoint_at_hint(self.line_edit.current_input[1:]))
|
||||
else:
|
||||
with suppress(Exception):
|
||||
if self.line_edit.current_input.startswith(INDEX_CHAR):
|
||||
if len(self.line_edit.current_input) > 1:
|
||||
self.current_char = chr(self.table.codepoint_at_hint(self.line_edit.current_input[1:]))
|
||||
elif self.line_edit.current_input:
|
||||
code = int(self.line_edit.current_input, 16)
|
||||
self.current_char = chr(code)
|
||||
except Exception:
|
||||
pass
|
||||
elif self.mode is NAME:
|
||||
cc = self.table.current_codepoint
|
||||
if cc:
|
||||
self.current_char = chr(cc)
|
||||
else:
|
||||
try:
|
||||
with suppress(Exception):
|
||||
if self.line_edit.current_input:
|
||||
self.current_char = chr(self.table.codepoint_at_hint(self.line_edit.current_input.lstrip(INDEX_CHAR)))
|
||||
except Exception:
|
||||
pass
|
||||
if self.current_char is not None:
|
||||
code = ord(self.current_char)
|
||||
if not codepoint_ok(code):
|
||||
@@ -395,19 +392,20 @@ class UnicodeInput(Handler):
|
||||
try:
|
||||
val = int(self.line_edit.current_input, 16)
|
||||
except Exception:
|
||||
return
|
||||
if key_event.key is TAB:
|
||||
self.line_edit.current_input = hex(val + 0x10)[2:]
|
||||
self.refresh()
|
||||
return
|
||||
if key_event.key is UP:
|
||||
self.line_edit.current_input = hex(val + 1)[2:]
|
||||
self.refresh()
|
||||
return
|
||||
if key_event.key is DOWN:
|
||||
self.line_edit.current_input = hex(val - 1)[2:]
|
||||
self.refresh()
|
||||
return
|
||||
pass
|
||||
else:
|
||||
if key_event.key is TAB:
|
||||
self.line_edit.current_input = hex(val + 0x10)[2:]
|
||||
self.refresh()
|
||||
return
|
||||
if key_event.key is UP:
|
||||
self.line_edit.current_input = hex(val + 1)[2:]
|
||||
self.refresh()
|
||||
return
|
||||
if key_event.key is DOWN:
|
||||
self.line_edit.current_input = hex(val - 1)[2:]
|
||||
self.refresh()
|
||||
return
|
||||
if self.mode is NAME and key_event.type is not RELEASE and not key_event.mods:
|
||||
if key_event.key is TAB:
|
||||
if key_event.mods == SHIFT:
|
||||
@@ -483,10 +481,8 @@ def main(args):
|
||||
handler = UnicodeInput(cached_values)
|
||||
loop.loop(handler)
|
||||
if handler.current_char and loop.return_code == 0:
|
||||
try:
|
||||
with suppress(Exception):
|
||||
handler.recent.remove(ord(handler.current_char))
|
||||
except Exception:
|
||||
pass
|
||||
recent = [ord(handler.current_char)] + handler.recent
|
||||
cached_values['recent'] = recent[:len(DEFAULT_SET)]
|
||||
return handler.current_char
|
||||
|
||||
41478
kittens/unicode_input/names.h
generated
41478
kittens/unicode_input/names.h
generated
File diff suppressed because one or more lines are too long
@@ -7,5 +7,5 @@ out vec4 color;
|
||||
|
||||
void main() {
|
||||
color = texture(image, texcoord);
|
||||
color = vec4(color.rgb / color.a, color.a);
|
||||
color = vec4(color.rgb, color.a);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ from .utils import load_shaders
|
||||
|
||||
try:
|
||||
from enum import IntFlag
|
||||
except Exception:
|
||||
except ImportError:
|
||||
from enum import IntEnum as IntFlag
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ class Borders:
|
||||
bw, pw = self.border_width, self.padding_width
|
||||
if bw + pw <= 0:
|
||||
return
|
||||
draw_borders = bw > 0 and draw_window_borders and len(windows) > 1
|
||||
draw_borders = bw > 0 and draw_window_borders
|
||||
if draw_borders:
|
||||
border_data = current_layout.resolve_borders(windows, active_window)
|
||||
|
||||
|
||||
@@ -6,11 +6,12 @@ import atexit
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
from contextlib import suppress
|
||||
from functools import partial
|
||||
from gettext import gettext as _
|
||||
from weakref import WeakValueDictionary
|
||||
|
||||
from .child import cached_process_data
|
||||
from .child import cached_process_data, cwd_of_process
|
||||
from .cli import create_opts, parse_args
|
||||
from .conf.utils import to_cmdline
|
||||
from .config import initial_window_size_func, prepare_config_file_for_editing
|
||||
@@ -24,10 +25,11 @@ from .fast_data_types import (
|
||||
change_os_window_state, create_os_window, current_os_window,
|
||||
destroy_global_data, get_clipboard_string, global_font_size,
|
||||
mark_os_window_for_close, os_window_font_size, patch_global_colors,
|
||||
set_clipboard_string, set_in_sequence_mode, toggle_fullscreen
|
||||
safe_pipe, set_clipboard_string, set_in_sequence_mode, thread_write,
|
||||
toggle_fullscreen, toggle_maximized
|
||||
)
|
||||
from .keys import get_shortcut, shortcut_matches
|
||||
from .layout import set_draw_borders_options
|
||||
from .layout import set_layout_options
|
||||
from .remote_control import handle_cmd
|
||||
from .rgb import Color, color_from_int
|
||||
from .session import create_sessions
|
||||
@@ -104,7 +106,7 @@ class DumpCommands: # {{{
|
||||
class Boss:
|
||||
|
||||
def __init__(self, os_window_id, opts, args, cached_values, new_os_window_trigger):
|
||||
set_draw_borders_options(opts)
|
||||
set_layout_options(opts)
|
||||
self.clipboard_buffers = {}
|
||||
self.update_check_process = None
|
||||
self.window_id_map = WeakValueDictionary()
|
||||
@@ -133,13 +135,13 @@ class Boss:
|
||||
if new_os_window_trigger is not None:
|
||||
self.keymap.pop(new_os_window_trigger, None)
|
||||
for startup_session in startup_sessions:
|
||||
os_window_id = self.add_os_window(startup_session, os_window_id=os_window_id)
|
||||
self.add_os_window(startup_session, os_window_id=os_window_id)
|
||||
os_window_id = None
|
||||
if args.start_as != 'normal':
|
||||
if args.start_as == 'fullscreen':
|
||||
self.toggle_fullscreen()
|
||||
else:
|
||||
change_os_window_state(args.start_as)
|
||||
os_window_id = None
|
||||
if is_macos:
|
||||
from .fast_data_types import cocoa_set_notification_activated_callback
|
||||
cocoa_set_notification_activated_callback(self.notification_activated)
|
||||
@@ -361,6 +363,9 @@ class Boss:
|
||||
def toggle_fullscreen(self):
|
||||
toggle_fullscreen()
|
||||
|
||||
def toggle_maximized(self):
|
||||
toggle_maximized()
|
||||
|
||||
def start(self):
|
||||
if not getattr(self, 'io_thread_started', False):
|
||||
self.child_monitor.start()
|
||||
@@ -614,12 +619,12 @@ class Boss:
|
||||
if tm is not None:
|
||||
tm.update_tab_bar_data()
|
||||
|
||||
def on_drop(self, os_window_id, paths):
|
||||
def on_drop(self, os_window_id, strings):
|
||||
tm = self.os_window_map.get(os_window_id)
|
||||
if tm is not None:
|
||||
w = tm.active_window
|
||||
if w is not None:
|
||||
w.paste('\n'.join(paths))
|
||||
w.paste('\n'.join(strings))
|
||||
|
||||
def on_os_window_closed(self, os_window_id, viewport_width, viewport_height):
|
||||
self.cached_values['window-size'] = viewport_width, viewport_height
|
||||
@@ -635,16 +640,12 @@ class Boss:
|
||||
def notify_on_os_window_death(self, address):
|
||||
import socket
|
||||
s = socket.socket(family=socket.AF_UNIX)
|
||||
try:
|
||||
with suppress(Exception):
|
||||
s.connect(address)
|
||||
s.sendall(b'c')
|
||||
try:
|
||||
with suppress(EnvironmentError):
|
||||
s.shutdown(socket.SHUT_RDWR)
|
||||
except EnvironmentError:
|
||||
pass
|
||||
s.close()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def display_scrollback(self, window, data, cmd):
|
||||
tab = self.active_tab
|
||||
@@ -715,7 +716,9 @@ class Boss:
|
||||
},
|
||||
cwd=w.cwd_of_child,
|
||||
overlay_for=w.id
|
||||
))
|
||||
),
|
||||
copy_colors_from=w
|
||||
)
|
||||
overlay_window.action_on_close = partial(self.on_kitten_finish, w.id, end_kitten)
|
||||
return overlay_window
|
||||
|
||||
@@ -756,10 +759,10 @@ class Boss:
|
||||
def kitty_shell(self, window_type):
|
||||
cmd = ['@', kitty_exe(), '@']
|
||||
if window_type == 'tab':
|
||||
self._new_tab(cmd).active_window
|
||||
self._new_tab(cmd)
|
||||
elif window_type == 'os_window':
|
||||
os_window_id = self._new_os_window(cmd)
|
||||
self.os_window_map[os_window_id].active_window
|
||||
self.os_window_map[os_window_id]
|
||||
elif window_type == 'overlay':
|
||||
w = self.active_window
|
||||
tab = self.active_tab
|
||||
@@ -845,7 +848,8 @@ class Boss:
|
||||
def set_active_tab(self, tab):
|
||||
tm = self.active_tab_manager
|
||||
if tm is not None:
|
||||
tm.set_active_tab(tab)
|
||||
return tm.set_active_tab(tab)
|
||||
return False
|
||||
|
||||
def next_tab(self):
|
||||
tm = self.active_tab_manager
|
||||
@@ -909,14 +913,30 @@ class Boss:
|
||||
tm.new_tab(special_window=create_window(), cwd_from=cwd_from)
|
||||
elif dest == 'os_window':
|
||||
self._new_os_window(create_window(), cwd_from=cwd_from)
|
||||
elif dest in ('clipboard', 'primary'):
|
||||
env, stdin = self.process_stdin_source(stdin=source, window=window)
|
||||
if stdin:
|
||||
func = set_clipboard_string if dest == 'clipboard' else set_primary_selection
|
||||
func(stdin)
|
||||
else:
|
||||
import subprocess
|
||||
env, stdin = self.process_stdin_source(stdin=source, window=window)
|
||||
cwd = None
|
||||
if cwd_from:
|
||||
with suppress(Exception):
|
||||
cwd = cwd_of_process(cwd_from)
|
||||
if stdin:
|
||||
p = subprocess.Popen(cmd, env=env, stdin=subprocess.PIPE)
|
||||
p.communicate(stdin)
|
||||
r, w = safe_pipe(False)
|
||||
try:
|
||||
subprocess.Popen(cmd, env=env, stdin=r, cwd=cwd)
|
||||
except Exception:
|
||||
os.close(w)
|
||||
else:
|
||||
thread_write(w, stdin)
|
||||
finally:
|
||||
os.close(r)
|
||||
else:
|
||||
subprocess.Popen(cmd)
|
||||
subprocess.Popen(cmd, env=env, cwd=cwd)
|
||||
|
||||
def args_to_special_window(self, args, cwd_from=None):
|
||||
args = list(args)
|
||||
@@ -971,10 +991,14 @@ class Boss:
|
||||
def _new_window(self, args, cwd_from=None):
|
||||
tab = self.active_tab
|
||||
if tab is not None:
|
||||
location = None
|
||||
if args and args[0].startswith('!'):
|
||||
location = args[0][1:].lower()
|
||||
args = args[1:]
|
||||
if args:
|
||||
return tab.new_special_window(self.args_to_special_window(args, cwd_from=cwd_from))
|
||||
return tab.new_special_window(self.args_to_special_window(args, cwd_from=cwd_from), location=location)
|
||||
else:
|
||||
return tab.new_window(cwd_from=cwd_from)
|
||||
return tab.new_window(cwd_from=cwd_from, location=location)
|
||||
|
||||
def new_window(self, *args):
|
||||
self._new_window(args)
|
||||
@@ -1028,18 +1052,14 @@ class Boss:
|
||||
|
||||
def safe_delete_temp_file(self, path):
|
||||
if is_path_in_temp_dir(path):
|
||||
try:
|
||||
with suppress(FileNotFoundError):
|
||||
os.remove(path)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
def set_update_check_process(self, process=None):
|
||||
if self.update_check_process is not None:
|
||||
try:
|
||||
with suppress(Exception):
|
||||
if self.update_check_process.poll() is None:
|
||||
self.update_check_process.kill()
|
||||
except Exception:
|
||||
pass
|
||||
self.update_check_process = process
|
||||
|
||||
def on_monitored_pid_death(self, pid, exit_status):
|
||||
|
||||
@@ -51,10 +51,48 @@ vec4 alpha_blend_premul(vec3 over, float over_alpha, vec3 under, float under_alp
|
||||
float alpha = mix(under_alpha, 1.0f, over_alpha);
|
||||
return vec4(premul_blend(over, over_alpha, under), alpha);
|
||||
}
|
||||
|
||||
vec4 blend_onto_opaque_premul(vec3 over, float over_alpha, vec3 under) {
|
||||
// same as alpha_blend_premul with under_alpha = 1 outputs a blended color
|
||||
// with alpha 1 which is effectively pre-multiplied since alpha is 1
|
||||
return vec4(premul_blend(over, over_alpha, under), 1.0);
|
||||
}
|
||||
|
||||
|
||||
// }}}
|
||||
|
||||
|
||||
/*
|
||||
* Explanation of rendering:
|
||||
* There are a couple of cases, in order of increasing complexity:
|
||||
* 1) Simple -- this path is used when there are either no images, or all images are
|
||||
* drawn on top of text and the background is opaque. In this case, there is a single pass,
|
||||
* of this shader with cell foreground and background colors blended directly.
|
||||
* Expected output is a color premultiplied by alpha, with an alpha specified as well.
|
||||
*
|
||||
* 2) Interleaved -- this path is used if background is not opaque and there are images or
|
||||
* if the background is opaque but there are images under text. Rendering happens in
|
||||
* multiple passes drawing the background and foreground separately and blending.
|
||||
*
|
||||
* 2a) Opaque bg with images under text
|
||||
* There are multiple passes, each pass is blended onto the previous using the opaque blend func (alpha, 1- alpha):
|
||||
* 1) Draw only the background -- expected output is color with alpha 1
|
||||
* 2) Draw the images that are supposed to be below text. This happens in the graphics shader
|
||||
* 3) Draw the special cells (selection/cursor). Output is same as from step 1, with bg_alpha 1 for special cells and 0 otherwise
|
||||
* 4) Draw the foreground -- expected output is color with alpha which is blended using the opaque blend func
|
||||
* 5) Draw the images that are supposed to be above text again in the graphics shader
|
||||
*
|
||||
* 2b) Transparent bg with images
|
||||
* First everything is rendered into a framebuffer, and then the framebauffer is blended onto
|
||||
* the screen. The framebuffer is needed because it allows access to the background color pixels
|
||||
* to blend with the image pixels. The steps are basically the same as for 2a.
|
||||
*
|
||||
* In this shader exactly *one* of SIMPLE, SPECIAL, FOREGROUND or BACKGROUND will be defined, corresponding
|
||||
* to the appropriate rendering pass from above.
|
||||
*/
|
||||
#ifdef NEEDS_FOREGROUND
|
||||
vec4 calculate_foreground() {
|
||||
// returns the effective foreground color in pre-multiplied form
|
||||
vec4 text_fg = texture(sprites, sprite_pos);
|
||||
vec3 fg = mix(foreground, text_fg.rgb, colored_sprite);
|
||||
float text_alpha = text_fg.a;
|
||||
@@ -70,15 +108,12 @@ vec4 calculate_foreground() {
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
#ifdef BACKGROUND
|
||||
#ifdef SIMPLE
|
||||
vec4 fg = calculate_foreground();
|
||||
#ifdef TRANSPARENT
|
||||
// bg_alpha is doubled to match rendering in the SIMPLE case
|
||||
// and also rendering of the margin/padding, see https://github.com/kovidgoyal/kitty/pull/1291
|
||||
// to test use background_opacity, window_margin_width and icat to display
|
||||
// an image.
|
||||
final_color = vec4(background.rgb * bg_alpha * bg_alpha, bg_alpha);
|
||||
final_color = alpha_blend_premul(fg.rgb, fg.a, background.rgb * bg_alpha, bg_alpha);
|
||||
#else
|
||||
final_color = vec4(background.rgb, 1.0f);
|
||||
final_color = blend_onto_opaque_premul(fg.rgb, fg.a, background.rgb);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -90,29 +125,22 @@ void main() {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(FOREGROUND) || defined(SIMPLE)
|
||||
// FOREGROUND or SIMPLE
|
||||
vec4 fg = calculate_foreground(); // pre-multiplied foreground
|
||||
#ifdef BACKGROUND
|
||||
#ifdef TRANSPARENT
|
||||
final_color = vec4(background.rgb * bg_alpha, bg_alpha);
|
||||
#else
|
||||
final_color = vec4(background.rgb, 1.0f);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef FOREGROUND
|
||||
// FOREGROUND
|
||||
vec4 fg = calculate_foreground(); // pre-multiplied foreground
|
||||
#ifdef TRANSPARENT
|
||||
final_color = fg;
|
||||
#else
|
||||
final_color = vec4(fg.rgb / fg.a, fg.a);
|
||||
#endif
|
||||
|
||||
#else
|
||||
// SIMPLE
|
||||
#ifdef TRANSPARENT
|
||||
final_color = alpha_blend_premul(fg.rgb, fg.a, background * bg_alpha, bg_alpha);
|
||||
final_color = vec4(final_color.rgb, final_color.a);
|
||||
#else
|
||||
// since background alpha is 1.0, it is effectively pre-multiplied
|
||||
final_color = vec4(premul_blend(fg.rgb, fg.a, background), 1.0f);
|
||||
final_color = vec4(final_color.rgb, final_color.a);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ vec3 choose_color(float q, vec3 a, vec3 b) {
|
||||
return mix(b, a, q);
|
||||
}
|
||||
|
||||
float are_integers_equal(float a, float b) { // return 1 iff equal otherwise 0
|
||||
float are_integers_equal(float a, float b) { // return 1 if equal otherwise 0
|
||||
float delta = abs(a - b); // delta can be 0, 1 or larger
|
||||
return step(delta, 0.5); // 0 if 0.5 < delta else 1
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* Distributed under terms of the GPL3 license.
|
||||
*/
|
||||
|
||||
#include "loop-utils.h"
|
||||
#include "state.h"
|
||||
#include "threading.h"
|
||||
#include "screen.h"
|
||||
@@ -16,10 +17,16 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#include <sys/socket.h>
|
||||
#include <signal.h>
|
||||
extern PyTypeObject Screen_Type;
|
||||
|
||||
#ifdef DEBUG_EVENT_LOOP
|
||||
#define EVDBG(...) log_event(__VA_ARGS__)
|
||||
#else
|
||||
#define EVDBG(...)
|
||||
#endif
|
||||
|
||||
#define EXTRA_FDS 2
|
||||
#ifndef MSG_NOSIGNAL
|
||||
// Apple does not implement MSG_NOSIGNAL
|
||||
@@ -46,6 +53,7 @@ typedef struct {
|
||||
int talk_fd, listen_fd;
|
||||
Message *messages;
|
||||
size_t messages_capacity, messages_count;
|
||||
LoopData io_loop_data;
|
||||
} ChildMonitor;
|
||||
|
||||
|
||||
@@ -77,7 +85,6 @@ static pthread_mutex_t children_lock;
|
||||
static bool kill_signal_received = false;
|
||||
static ChildMonitor *the_monitor = NULL;
|
||||
static uint8_t drain_buf[1024];
|
||||
static int signal_fds[2], wakeup_fds[2];
|
||||
|
||||
|
||||
typedef struct {
|
||||
@@ -110,39 +117,6 @@ set_maximum_wait(double val) {
|
||||
if (val >= 0 && (val < maximum_wait || maximum_wait < 0)) maximum_wait = val;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_signal(int sig_num) {
|
||||
int save_err = errno;
|
||||
unsigned char byte = (unsigned char)sig_num;
|
||||
while(true) {
|
||||
ssize_t ret = write(signal_fds[1], &byte, 1);
|
||||
if (ret < 0 && errno == EINTR) continue;
|
||||
break;
|
||||
}
|
||||
errno = save_err;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
self_pipe(int fds[2]) {
|
||||
#ifdef __APPLE__
|
||||
int flags;
|
||||
flags = pipe(fds);
|
||||
if (flags != 0) return false;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
flags = fcntl(fds[i], F_GETFD);
|
||||
if (flags == -1) { return false; }
|
||||
if (fcntl(fds[i], F_SETFD, flags | FD_CLOEXEC) == -1) { return false; }
|
||||
flags = fcntl(fds[i], F_GETFL);
|
||||
if (flags == -1) { return false; }
|
||||
if (fcntl(fds[i], F_SETFL, flags | O_NONBLOCK) == -1) { return false; }
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
return pipe2(fds, O_CLOEXEC | O_NONBLOCK) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static PyObject *
|
||||
new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
|
||||
ChildMonitor *self;
|
||||
@@ -156,13 +130,9 @@ new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
|
||||
PyErr_Format(PyExc_RuntimeError, "Failed to create children_lock mutex: %s", strerror(ret));
|
||||
return NULL;
|
||||
}
|
||||
if (!self_pipe(wakeup_fds)) return PyErr_SetFromErrno(PyExc_OSError);
|
||||
if (!self_pipe(signal_fds)) return PyErr_SetFromErrno(PyExc_OSError);
|
||||
struct sigaction act = {.sa_handler=handle_signal};
|
||||
#define SA(which) { if (sigaction(which, &act, NULL) != 0) return PyErr_SetFromErrno(PyExc_OSError); if (siginterrupt(which, false) != 0) return PyErr_SetFromErrno(PyExc_OSError);}
|
||||
SA(SIGINT); SA(SIGTERM); SA(SIGCHLD);
|
||||
#undef SA
|
||||
self = (ChildMonitor *)type->tp_alloc(type, 0);
|
||||
if (!init_loop_data(&self->io_loop_data)) return PyErr_SetFromErrno(PyExc_OSError);
|
||||
if (!install_signal_handlers(&self->io_loop_data)) return PyErr_SetFromErrno(PyExc_OSError);
|
||||
self->talk_fd = talk_fd;
|
||||
self->listen_fd = listen_fd;
|
||||
if (self == NULL) return PyErr_NoMemory();
|
||||
@@ -172,7 +142,7 @@ new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
|
||||
parse_func = parse_worker_dump;
|
||||
} else parse_func = parse_worker;
|
||||
self->count = 0;
|
||||
fds[0].fd = wakeup_fds[0]; fds[1].fd = signal_fds[0];
|
||||
fds[0].fd = self->io_loop_data.wakeup_read_fd; fds[1].fd = self->io_loop_data.signal_read_fd;
|
||||
fds[0].events = POLLIN; fds[1].events = POLLIN;
|
||||
the_monitor = self;
|
||||
|
||||
@@ -193,22 +163,12 @@ dealloc(ChildMonitor* self) {
|
||||
add_queue_count--;
|
||||
FREE_CHILD(add_queue[add_queue_count]);
|
||||
}
|
||||
close(wakeup_fds[0]);
|
||||
close(wakeup_fds[1]);
|
||||
close(signal_fds[0]);
|
||||
close(signal_fds[1]);
|
||||
free_loop_data(&self->io_loop_data);
|
||||
}
|
||||
|
||||
void
|
||||
wakeup_io_loop(bool in_signal_handler) {
|
||||
while(true) {
|
||||
ssize_t ret = write(wakeup_fds[1], "w", 1);
|
||||
if (ret < 0) {
|
||||
if (errno == EINTR) continue;
|
||||
if (!in_signal_handler) perror("Failed to write to wakeup fd with error");
|
||||
}
|
||||
break;
|
||||
}
|
||||
static void
|
||||
wakeup_io_loop(ChildMonitor *self, bool in_signal_handler) {
|
||||
wakeup_loop(&self->io_loop_data, in_signal_handler);
|
||||
}
|
||||
|
||||
static void* io_loop(void *data);
|
||||
@@ -231,11 +191,10 @@ start(PyObject *s, PyObject *a UNUSED) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
static PyObject *
|
||||
wakeup(PYNOARG) {
|
||||
wakeup(ChildMonitor *self, PyObject *args UNUSED) {
|
||||
#define wakeup_doc "wakeup() -> wakeup the ChildMonitor I/O thread, forcing it to exit from poll() if it is waiting there."
|
||||
wakeup_io_loop(false);
|
||||
wakeup_io_loop(self, false);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
@@ -254,7 +213,7 @@ add_child(ChildMonitor *self, PyObject *args) {
|
||||
INCREF_CHILD(add_queue[add_queue_count]);
|
||||
add_queue_count++;
|
||||
children_mutex(unlock);
|
||||
wakeup_io_loop(false);
|
||||
wakeup_io_loop(self, false);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
@@ -301,7 +260,7 @@ schedule_write_to_child(unsigned long id, unsigned int num, ...) {
|
||||
screen->write_buf = PyMem_RawRealloc(screen->write_buf, screen->write_buf_sz);
|
||||
if (screen->write_buf == NULL) { fatal("Out of memory."); }
|
||||
}
|
||||
if (screen->write_buf_used) wakeup_io_loop(false);
|
||||
if (screen->write_buf_used) wakeup_io_loop(self, false);
|
||||
screen_mutex(unlock, write);
|
||||
break;
|
||||
}
|
||||
@@ -323,12 +282,9 @@ needs_write(ChildMonitor UNUSED *self, PyObject *args) {
|
||||
static PyObject *
|
||||
shutdown_monitor(ChildMonitor *self, PyObject *a UNUSED) {
|
||||
#define shutdown_monitor_doc "shutdown_monitor() -> Shutdown the monitor loop."
|
||||
signal(SIGINT, SIG_DFL);
|
||||
signal(SIGTERM, SIG_DFL);
|
||||
signal(SIGCHLD, SIG_DFL);
|
||||
self->shutting_down = true;
|
||||
wakeup_talk_loop(false);
|
||||
wakeup_io_loop(false);
|
||||
wakeup_io_loop(self, false);
|
||||
int ret = pthread_join(self->io_thread, NULL);
|
||||
if (ret != 0) return PyErr_Format(PyExc_OSError, "Failed to join() I/O thread with error: %s", strerror(ret));
|
||||
if (talk_thread_started) {
|
||||
@@ -339,15 +295,17 @@ shutdown_monitor(ChildMonitor *self, PyObject *a UNUSED) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static inline void
|
||||
static inline bool
|
||||
do_parse(ChildMonitor *self, Screen *screen, double now) {
|
||||
bool input_read = false;
|
||||
screen_mutex(lock, read);
|
||||
if (screen->read_buf_sz || screen->pending_mode.used) {
|
||||
double time_since_new_input = now - screen->new_input_at;
|
||||
if (time_since_new_input >= OPT(input_delay)) {
|
||||
bool read_buf_full = screen->read_buf_sz >= READ_BUF_SZ;
|
||||
input_read = true;
|
||||
parse_func(screen, self->dump_callback, now);
|
||||
if (read_buf_full) wakeup_io_loop(false); // Ensure the read fd has POLLIN set
|
||||
if (read_buf_full) wakeup_io_loop(self, false); // Ensure the read fd has POLLIN set
|
||||
screen->new_input_at = 0;
|
||||
if (screen->pending_mode.activated_at) {
|
||||
double time_since_pending = MAX(0, now - screen->pending_mode.activated_at);
|
||||
@@ -356,12 +314,14 @@ do_parse(ChildMonitor *self, Screen *screen, double now) {
|
||||
} else set_maximum_wait(OPT(input_delay) - time_since_new_input);
|
||||
}
|
||||
screen_mutex(unlock, read);
|
||||
return input_read;
|
||||
}
|
||||
|
||||
static void
|
||||
static bool
|
||||
parse_input(ChildMonitor *self) {
|
||||
// Parse all available input that was read in the I/O thread.
|
||||
size_t count = 0, remove_count = 0;
|
||||
bool input_read = false;
|
||||
double now = monotonic();
|
||||
PyObject *msg = NULL;
|
||||
children_mutex(lock);
|
||||
@@ -416,10 +376,11 @@ parse_input(ChildMonitor *self) {
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
if (!scratch[i].needs_removal) {
|
||||
do_parse(self, scratch[i].screen, now);
|
||||
if (do_parse(self, scratch[i].screen, now)) input_read = true;
|
||||
}
|
||||
DECREF_CHILD(scratch[i]);
|
||||
}
|
||||
return input_read;
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -432,7 +393,7 @@ mark_child_for_close(ChildMonitor *self, id_type window_id) {
|
||||
}
|
||||
}
|
||||
children_mutex(unlock);
|
||||
wakeup_io_loop(false);
|
||||
wakeup_io_loop(self, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -521,9 +482,7 @@ pyset_iutf8(ChildMonitor *self, PyObject *args) {
|
||||
#undef INCREF_CHILD
|
||||
#undef DECREF_CHILD
|
||||
|
||||
static double last_render_at = -DBL_MAX;
|
||||
|
||||
extern void cocoa_update_title(PyObject*);
|
||||
extern void cocoa_update_menu_bar_title(PyObject*);
|
||||
|
||||
static inline void
|
||||
collect_cursor_info(CursorRenderInfo *ans, Window *w, double now, OSWindow *os_window) {
|
||||
@@ -559,7 +518,7 @@ update_window_title(Window *w, OSWindow *os_window) {
|
||||
Py_INCREF(os_window->window_title);
|
||||
set_os_window_title(os_window, PyUnicode_AsUTF8(w->title));
|
||||
#ifdef __APPLE__
|
||||
if (os_window->is_focused && OPT(macos_show_window_title_in_menubar)) cocoa_update_title(w->title);
|
||||
if (os_window->is_focused && (OPT(macos_show_window_title_in) & MENUBAR)) cocoa_update_menu_bar_title(w->title);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
@@ -672,10 +631,19 @@ draw_resizing_text(OSWindow *w) {
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool
|
||||
no_render_frame_received_recently(OSWindow *w, double now, double max_wait) {
|
||||
bool ans = now - w->last_render_frame_received_at > max_wait;
|
||||
if (ans) log_error("No render frame received in %f seconds, re-requesting at: %f", max_wait, now);
|
||||
return ans;
|
||||
}
|
||||
|
||||
static inline void
|
||||
render(double now) {
|
||||
render(double now, bool input_read) {
|
||||
EVDBG("input_read: %d", input_read);
|
||||
static double last_render_at = -DBL_MAX;
|
||||
double time_since_last_render = now - last_render_at;
|
||||
if (time_since_last_render < OPT(repaint_delay)) {
|
||||
if (!input_read && time_since_last_render < OPT(repaint_delay)) {
|
||||
set_maximum_wait(OPT(repaint_delay) - time_since_last_render);
|
||||
return;
|
||||
}
|
||||
@@ -688,7 +656,7 @@ render(double now) {
|
||||
continue;
|
||||
}
|
||||
if (USE_RENDER_FRAMES && w->render_state != RENDER_FRAME_READY) {
|
||||
if (w->render_state == RENDER_FRAME_NOT_REQUESTED) request_frame_render(w);
|
||||
if (w->render_state == RENDER_FRAME_NOT_REQUESTED || no_render_frame_received_recently(w, now, 0.25)) request_frame_render(w);
|
||||
continue;
|
||||
}
|
||||
make_os_window_context_current(w);
|
||||
@@ -723,7 +691,7 @@ typedef struct { int fd; uint8_t *buf; size_t sz; } ThreadWriteData;
|
||||
|
||||
static inline ThreadWriteData*
|
||||
alloc_twd(size_t sz) {
|
||||
ThreadWriteData *data = malloc(sizeof(ThreadWriteData));
|
||||
ThreadWriteData *data = calloc(1, sizeof(ThreadWriteData));
|
||||
if (data != NULL) {
|
||||
data->sz = sz;
|
||||
data->buf = malloc(sz);
|
||||
@@ -771,11 +739,25 @@ static void*
|
||||
thread_write(void *x) {
|
||||
ThreadWriteData *data = (ThreadWriteData*)x;
|
||||
set_thread_name("KittyWriteStdin");
|
||||
FILE *f = fdopen(data->fd, "w");
|
||||
if (fwrite(data->buf, 1, data->sz, f) != data->sz) {
|
||||
log_error("Failed to write all data");
|
||||
int flags = fcntl(data->fd, F_GETFL, 0);
|
||||
if (flags == -1) { free_twd(data); return 0; }
|
||||
flags &= ~O_NONBLOCK;
|
||||
fcntl(data->fd, F_SETFL, flags);
|
||||
size_t pos = 0;
|
||||
while (pos < data->sz) {
|
||||
errno = 0;
|
||||
ssize_t nbytes = write(data->fd, data->buf + pos, data->sz - pos);
|
||||
if (nbytes < 0) {
|
||||
if (errno == EAGAIN || errno == EINTR) continue;
|
||||
break;
|
||||
}
|
||||
if (nbytes == 0) break;
|
||||
pos += nbytes;
|
||||
}
|
||||
fclose(f);
|
||||
if (pos < data->sz) {
|
||||
log_error("Failed to write all data to STDIN of child process with error: %s", strerror(errno));
|
||||
}
|
||||
safe_close(data->fd);
|
||||
free_twd(data);
|
||||
return 0;
|
||||
}
|
||||
@@ -792,7 +774,8 @@ cm_thread_write(PyObject UNUSED *self, PyObject *args) {
|
||||
data->fd = fd;
|
||||
memcpy(data->buf, buf, data->sz);
|
||||
int ret = pthread_create(&thread, NULL, thread_write, data);
|
||||
if (ret != 0) { free_twd(data); return PyErr_SetFromErrno(PyExc_OSError); }
|
||||
if (ret != 0) { safe_close(fd); free_twd(data); return PyErr_SetFromErrno(PyExc_OSError); }
|
||||
pthread_detach(thread);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
@@ -913,21 +896,23 @@ static void process_global_state(void *data);
|
||||
|
||||
static void
|
||||
do_state_check(id_type timer_id UNUSED, void *data) {
|
||||
ChildMonitor *self = data;
|
||||
process_global_state(self);
|
||||
EVDBG("State check timer fired");
|
||||
process_global_state(data);
|
||||
}
|
||||
|
||||
static id_type state_check_timer = 0;
|
||||
|
||||
static void
|
||||
process_global_state(void *data) {
|
||||
EVDBG("Processing global state");
|
||||
ChildMonitor *self = data;
|
||||
maximum_wait = -1;
|
||||
bool state_check_timer_enabled = false;
|
||||
|
||||
double now = monotonic();
|
||||
if (global_state.has_pending_resizes) process_pending_resizes(now);
|
||||
render(now);
|
||||
bool input_read = parse_input(self);
|
||||
render(now, input_read);
|
||||
#ifdef __APPLE__
|
||||
if (cocoa_pending_actions) {
|
||||
if (cocoa_pending_actions & PREFERENCES_WINDOW) { call_boss(edit_config_file, NULL); }
|
||||
@@ -941,7 +926,6 @@ process_global_state(void *data) {
|
||||
cocoa_pending_actions = 0;
|
||||
}
|
||||
#endif
|
||||
parse_input(self);
|
||||
if (global_state.terminate) {
|
||||
global_state.terminate = false;
|
||||
close_all_windows();
|
||||
@@ -954,7 +938,8 @@ process_global_state(void *data) {
|
||||
if (global_state.has_pending_closes) has_open_windows = process_pending_closes(self);
|
||||
if (has_open_windows) {
|
||||
if (maximum_wait >= 0) {
|
||||
state_check_timer_enabled = true;
|
||||
if (maximum_wait == 0) request_tick_callback();
|
||||
else state_check_timer_enabled = true;
|
||||
}
|
||||
} else {
|
||||
stop_main_loop();
|
||||
@@ -1005,7 +990,7 @@ hangup(pid_t pid) {
|
||||
|
||||
static inline void
|
||||
cleanup_child(ssize_t i) {
|
||||
close(children[i].fd);
|
||||
safe_close(children[i].fd);
|
||||
hangup(children[i].pid);
|
||||
}
|
||||
|
||||
@@ -1074,35 +1059,28 @@ drain_fd(int fd) {
|
||||
ssize_t len = read(fd, drain_buf, sizeof(drain_buf));
|
||||
if (len < 0) {
|
||||
if (errno == EINTR) continue;
|
||||
if (errno != EIO) perror("Call to read() from drain fd failed");
|
||||
break;
|
||||
}
|
||||
if (len > 0) continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
read_signals(int fd, bool *kill_signal, bool *child_died) {
|
||||
static char buf[256];
|
||||
while(true) {
|
||||
ssize_t len = read(fd, buf, sizeof(buf));
|
||||
if (len < 0) {
|
||||
if (errno == EINTR) continue;
|
||||
if (errno != EIO) perror("Call to read() from read_signals() failed");
|
||||
typedef struct { bool kill_signal, child_died; } SignalSet;
|
||||
|
||||
static void
|
||||
handle_signal(int signum, void *data) {
|
||||
SignalSet *ss = data;
|
||||
switch(signum) {
|
||||
case SIGINT:
|
||||
case SIGTERM:
|
||||
ss->kill_signal = true;
|
||||
break;
|
||||
case SIGCHLD:
|
||||
ss->child_died = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
for (ssize_t i = 0; i < len; i++) {
|
||||
switch(buf[i]) {
|
||||
case SIGCHLD:
|
||||
*child_died = true; break;
|
||||
case SIGINT:
|
||||
case SIGTERM:
|
||||
*kill_signal = true; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1212,11 +1190,11 @@ io_loop(void *data) {
|
||||
if (ret > 0) {
|
||||
if (fds[0].revents && POLLIN) drain_fd(fds[0].fd); // wakeup
|
||||
if (fds[1].revents && POLLIN) {
|
||||
SignalSet ss = {0};
|
||||
data_received = true;
|
||||
bool kill_signal = false, child_died = false;
|
||||
read_signals(fds[1].fd, &kill_signal, &child_died);
|
||||
if (kill_signal) { children_mutex(lock); kill_signal_received = true; children_mutex(unlock); }
|
||||
if (child_died) reap_children(self, OPT(close_on_child_death));
|
||||
read_signals(fds[1].fd, handle_signal, &ss);
|
||||
if (ss.kill_signal) { children_mutex(lock); kill_signal_received = true; children_mutex(unlock); }
|
||||
if (ss.child_died) reap_children(self, OPT(close_on_child_death));
|
||||
}
|
||||
for (i = 0; i < self->count; i++) {
|
||||
if (fds[EXTRA_FDS + i].revents & (POLLIN | POLLHUP)) {
|
||||
@@ -1296,14 +1274,14 @@ typedef struct {
|
||||
PeerReadData *reads;
|
||||
PeerWriteData *writes;
|
||||
PeerWriteData *queued_writes;
|
||||
int wakeup_fds[2];
|
||||
LoopData loop_data;
|
||||
pthread_mutex_t peer_lock;
|
||||
} TalkData;
|
||||
|
||||
static TalkData talk_data = {0};
|
||||
typedef struct pollfd PollFD;
|
||||
#define PEER_LIMIT 256
|
||||
#define nuke_socket(s) { shutdown(s, SHUT_RDWR); close(s); }
|
||||
#define nuke_socket(s) { shutdown(s, SHUT_RDWR); safe_close(s); }
|
||||
|
||||
static inline bool
|
||||
accept_peer(int listen_fd, bool shutting_down) {
|
||||
@@ -1336,7 +1314,7 @@ read_from_peer(ChildMonitor *self, int s) {
|
||||
if (rd->fd == s) {
|
||||
if (rd->used >= rd->capacity) {
|
||||
if (rd->capacity >= 1024 * 1024) failed("Ignoring too large message from peer");
|
||||
rd->capacity = MAX(8192, rd->capacity * 2);
|
||||
rd->capacity = MAX(8192u, rd->capacity * 2);
|
||||
rd->data = realloc(rd->data, rd->capacity);
|
||||
if (!rd->data) failed("Out of memory");
|
||||
}
|
||||
@@ -1424,7 +1402,7 @@ prune_finished_writes(void) {
|
||||
PeerWriteData *wd = talk_data.writes + i;
|
||||
if (wd->finished) {
|
||||
remove_poll_fd(wd->fd);
|
||||
shutdown(wd->fd, SHUT_WR); close(wd->fd);
|
||||
shutdown(wd->fd, SHUT_WR); safe_close(wd->fd);
|
||||
free(wd->data);
|
||||
ssize_t num_to_right = talk_data.num_writes - 1 - i;
|
||||
if (num_to_right > 0) memmove(talk_data.writes + i, talk_data.writes + i + 1, num_to_right * sizeof(PeerWriteData));
|
||||
@@ -1436,15 +1414,7 @@ prune_finished_writes(void) {
|
||||
|
||||
static void
|
||||
wakeup_talk_loop(bool in_signal_handler) {
|
||||
if (talk_data.wakeup_fds[1] <= 0) return;
|
||||
while(true) {
|
||||
ssize_t ret = write(talk_data.wakeup_fds[1], "w", 1);
|
||||
if (ret < 0) {
|
||||
if (errno == EINTR) continue;
|
||||
if (!in_signal_handler) perror("Failed to write to talk wakeup fd with error");
|
||||
}
|
||||
break;
|
||||
}
|
||||
wakeup_loop(&talk_data.loop_data, in_signal_handler);
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -1473,7 +1443,7 @@ talk_loop(void *data) {
|
||||
ChildMonitor *self = (ChildMonitor*)data;
|
||||
set_thread_name("KittyPeerMon");
|
||||
if ((pthread_mutex_init(&talk_data.peer_lock, NULL)) != 0) { perror("Failed to create peer mutex"); return 0; }
|
||||
if (!self_pipe(talk_data.wakeup_fds)) { perror("Failed to create wakeup fds for talk thread"); return 0; }
|
||||
if (!init_loop_data(&talk_data.loop_data)) { log_error("Failed to create wakeup fd for talk thread with error: %s", strerror(errno)); }
|
||||
ensure_space_for(&talk_data, fds, PollFD, 8, fds_capacity, 8, false);
|
||||
#define add_listener(which) \
|
||||
if (self->which > -1) { \
|
||||
@@ -1481,7 +1451,7 @@ talk_loop(void *data) {
|
||||
}
|
||||
add_listener(talk_fd); add_listener(listen_fd);
|
||||
#undef add_listener
|
||||
talk_data.fds[talk_data.num_listen_fds].fd = talk_data.wakeup_fds[0]; talk_data.fds[talk_data.num_listen_fds++].events = POLLIN;
|
||||
talk_data.fds[talk_data.num_listen_fds].fd = talk_data.loop_data.wakeup_read_fd; talk_data.fds[talk_data.num_listen_fds++].events = POLLIN;
|
||||
|
||||
while (LIKELY(!self->shutting_down)) {
|
||||
for (size_t i = 0; i < talk_data.num_listen_fds + talk_data.num_talk_fds; i++) { talk_data.fds[i].revents = 0; }
|
||||
@@ -1504,7 +1474,7 @@ talk_loop(void *data) {
|
||||
} else if (ret < 0) { if (errno != EAGAIN && errno != EINTR) perror("poll() on talk fds failed"); }
|
||||
}
|
||||
end:
|
||||
close(talk_data.wakeup_fds[0]); close(talk_data.wakeup_fds[1]);
|
||||
free_loop_data(&talk_data.loop_data);
|
||||
free(talk_data.fds); free(talk_data.reads); free(talk_data.writes); free(talk_data.queued_writes);
|
||||
return 0;
|
||||
}
|
||||
@@ -1530,8 +1500,8 @@ add_peer_writer(int fd, const char* msg, size_t msg_sz) {
|
||||
|
||||
static void
|
||||
send_response(int fd, const char *msg, size_t msg_sz) {
|
||||
if (msg == NULL) { shutdown(fd, SHUT_WR); close(fd); return; }
|
||||
if (!add_peer_writer(fd, msg, msg_sz)) { shutdown(fd, SHUT_WR); close(fd); }
|
||||
if (msg == NULL) { shutdown(fd, SHUT_WR); safe_close(fd); return; }
|
||||
if (!add_peer_writer(fd, msg, msg_sz)) { shutdown(fd, SHUT_WR); safe_close(fd); }
|
||||
else wakeup_talk_loop(false);
|
||||
}
|
||||
|
||||
@@ -1565,18 +1535,20 @@ PyTypeObject ChildMonitor_Type = {
|
||||
|
||||
|
||||
static PyObject*
|
||||
safe_pipe(PYNOARG) {
|
||||
safe_pipe(PyObject *self UNUSED, PyObject *args) {
|
||||
int nonblock = 1;
|
||||
if (!PyArg_ParseTuple(args, "|p", &nonblock)) return NULL;
|
||||
int fds[2] = {0};
|
||||
if (!self_pipe(fds)) return PyErr_SetFromErrno(PyExc_OSError);
|
||||
if (!self_pipe(fds, nonblock)) return PyErr_SetFromErrno(PyExc_OSError);
|
||||
return Py_BuildValue("ii", fds[0], fds[1]);
|
||||
}
|
||||
|
||||
static PyMethodDef module_methods[] = {
|
||||
METHODB(safe_pipe, METH_NOARGS),
|
||||
METHODB(safe_pipe, METH_VARARGS),
|
||||
{"add_timer", (PyCFunction)add_python_timer, METH_VARARGS, ""},
|
||||
{"remove_timer", (PyCFunction)remove_python_timer, METH_VARARGS, ""},
|
||||
METHODB(monitor_pid, METH_VARARGS),
|
||||
{"set_iutf8", (PyCFunction)pyset_iutf8, METH_VARARGS, ""},
|
||||
{"set_iutf8_winid", (PyCFunction)pyset_iutf8, METH_VARARGS, ""},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user