annotate semiconginev2/platform/linux/window.nim @ 1228:4e465583ea32

did: rename texture to image
author sam <sam@basx.dev>
date Thu, 18 Jul 2024 16:33:24 +0700
parents 56781cc0fc7c
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1191
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
1 import ../../thirdparty/x11/xlib
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
2 import ../../thirdparty/x11/xutil
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
3 import ../../thirdparty/x11/keysym
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
4 import ../../thirdparty/x11/x as x11
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
5 import ../../thirdparty/x11/xkblib
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
6
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
7 include ./symkey_map
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
8
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
9 var deleteMessage*: Atom
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
10
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
11 type
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
12 NativeWindow* = object
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
13 display*: ptr xlib.Display
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
14 window*: x11.Window
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
15 emptyCursor: Cursor
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
16
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
17 template checkXlibResult(call: untyped) =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
18 let value = call
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
19 if value == 0:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
20 raise newException(Exception, "Xlib error: " & astToStr(call) &
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
21 " returned " & $value)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
22
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
23 proc XErrorLogger(display: PDisplay, event: PXErrorEvent): cint {.cdecl.} =
1192
90bf0cab1d02 did: so many, many things
sam <sam@basx.dev>
parents: 1191
diff changeset
24 logging.error &"Xlib: {event[]}"
1191
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
25
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
26 proc CreateWindow*(title: string): NativeWindow =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
27 checkXlibResult XInitThreads()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
28 let display = XOpenDisplay(nil)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
29 if display == nil:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
30 quit "Failed to open display"
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
31 discard XSetErrorHandler(XErrorLogger)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
32
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
33 let rootWindow = display.XDefaultRootWindow()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
34 discard display.XkbSetDetectableAutoRepeat(true, nil)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
35 var
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
36 attribs: XWindowAttributes
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
37 width = cuint(800)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
38 height = cuint(600)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
39 checkXlibResult display.XGetWindowAttributes(rootWindow, addr(attribs))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
40
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
41 var attrs = XSetWindowAttributes()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
42 let window = XCreateWindow(
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
43 display,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
44 rootWindow,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
45 (attribs.width - cint(width)) div 2, (attribs.height - cint(height)) div 2,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
46 width, height,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
47 0,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
48 CopyFromParent,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
49 InputOutput,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
50 cast[PVisual](CopyFromParent),
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
51 0, # CWOverrideRedirect,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
52 addr attrs,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
53 # foregroundColor, backgroundColor
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
54 )
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
55 checkXlibResult XSetStandardProperties(display, window, title, "window", 0, nil, 0, nil)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
56 checkXlibResult XSelectInput(display, window, PointerMotionMask or ButtonPressMask or ButtonReleaseMask or KeyPressMask or KeyReleaseMask or ExposureMask)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
57 checkXlibResult XMapWindow(display, window)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
58
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
59 deleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", XBool(false))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
60 checkXlibResult XSetWMProtocols(display, window, addr(deleteMessage), 1)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
61
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
62 var data = "\0".cstring
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
63 var pixmap = display.XCreateBitmapFromData(window, data, 1, 1)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
64 var color: XColor
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
65 var empty_cursor = display.XCreatePixmapCursor(pixmap, pixmap, addr(color), addr(color), 0, 0)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
66 checkXlibResult display.XFreePixmap(pixmap)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
67 return NativeWindow(display: display, window: window, emptyCursor: empty_cursor)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
68
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
69 proc SetTitle*(window: NativeWindow, title: string) =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
70 checkXlibResult XSetStandardProperties(window.display, window.window, title, "window", 0, nil, 0, nil)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
71
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
72 proc Fullscreen*(window: var NativeWindow, enable: bool) =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
73 var
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
74 wm_state = window.display.XInternAtom("_NET_WM_STATE", 0)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
75 wm_fullscreen = window.display.XInternAtom("_NET_WM_STATE_FULLSCREEN", 0)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
76 var
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
77 xev: XEvent
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
78 xev.xclient = XClientMessageEvent(
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
79 message_type: wm_state,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
80 format: 32,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
81 window: window.window,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
82 data: XClientMessageData(
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
83 l: [
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
84 int(not enable) xor 1,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
85 clong(wm_fullscreen),
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
86 0,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
87 0,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
88 0
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
89 ]
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
90 )
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
91 )
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
92 xev.theType = ClientMessage
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
93
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
94 checkXlibResult window.display.XSendEvent(
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
95 window.display.DefaultRootWindow(),
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
96 0,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
97 SubstructureRedirectMask or SubstructureNotifyMask,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
98 addr xev
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
99 )
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
100 checkXlibResult window.display.XFlush()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
101
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
102 proc HideSystemCursor*(window: NativeWindow) =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
103 checkXlibResult XDefineCursor(window.display, window.window, window.emptyCursor)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
104 checkXlibResult window.display.XFlush()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
105
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
106 proc ShowSystemCursor*(window: NativeWindow) =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
107 checkXlibResult XUndefineCursor(window.display, window.window)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
108 checkXlibResult window.display.XFlush()
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
109
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
110 proc Destroy*(window: NativeWindow) =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
111 checkXlibResult window.display.XFreeCursor(window.emptyCursor)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
112 checkXlibResult window.display.XDestroyWindow(window.window)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
113 discard window.display.XCloseDisplay() # always returns 0
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
114
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
115 proc Size*(window: NativeWindow): (int, int) =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
116 var attribs: XWindowAttributes
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
117 checkXlibResult XGetWindowAttributes(window.display, window.window, addr(attribs))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
118 return (int(attribs.width), int(attribs.height))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
119
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
120 proc PendingEvents*(window: NativeWindow): seq[Event] =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
121 var event: XEvent
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
122 while window.display.XPending() > 0:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
123 discard window.display.XNextEvent(addr(event))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
124 case event.theType
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
125 of ClientMessage:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
126 if cast[Atom](event.xclient.data.l[0]) == deleteMessage:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
127 result.add(Event(eventType: Quit))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
128 of KeyPress:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
129 let keyevent = cast[PXKeyEvent](addr(event))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
130 let xkey = int(keyevent.keycode)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
131 result.add Event(eventType: KeyPressed, key: KeyTypeMap.getOrDefault(xkey, Key.UNKNOWN))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
132 of KeyRelease:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
133 let keyevent = cast[PXKeyEvent](addr(event))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
134 let xkey = int(keyevent.keycode)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
135 result.add Event(eventType: KeyReleased, key: KeyTypeMap.getOrDefault(xkey, Key.UNKNOWN))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
136 of ButtonPress:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
137 let button = int(cast[PXButtonEvent](addr(event)).button)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
138 if button == Button4:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
139 result.add Event(eventType: MouseWheel, amount: 1'f32)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
140 elif button == Button5:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
141 result.add Event(eventType: MouseWheel, amount: -1'f32)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
142 else:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
143 result.add Event(eventType: MousePressed, button: MouseButtonTypeMap.getOrDefault(button, MouseButton.UNKNOWN))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
144 of ButtonRelease:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
145 let button = int(cast[PXButtonEvent](addr(event)).button)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
146 result.add Event(eventType: MouseReleased, button: MouseButtonTypeMap.getOrDefault(button, MouseButton.UNKNOWN))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
147 of MotionNotify:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
148 let motion = cast[PXMotionEvent](addr(event))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
149 result.add Event(eventType: MouseMoved, x: motion.x, y: motion.y)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
150 of ConfigureNotify, Expose:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
151 result.add Event(eventType: ResizedWindow)
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
152 else:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
153 discard
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
154
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
155
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
156 proc GetMousePosition*(window: NativeWindow): Option[Vec2f] =
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
157 var
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
158 root: x11.Window
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
159 win: x11.Window
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
160 rootX: cint
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
161 rootY: cint
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
162 winX: cint
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
163 winY: cint
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
164 mask: cuint
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
165 onscreen = XQueryPointer(
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
166 window.display,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
167 window.window,
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
168 addr(root),
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
169 addr(win),
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
170 addr(rootX),
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
171 addr(rootY),
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
172 addr(winX),
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
173 addr(winY),
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
174 addr(mask),
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
175 )
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
176 if onscreen != 0:
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
177 result = some(Vec2f([float32(winX), float32(winY)]))
239adab121a3 sync from bedroom to office
sam <sam@basx.dev>
parents:
diff changeset
178