PatchworkOS  c9fea19
A non-POSIX operating system.
Loading...
Searching...
No Matches
dwm.c
Go to the documentation of this file.
1#include "dwm.h"
2
3#include "client.h"
4#include "compositor.h"
5#include "kbd.h"
6#include "screen.h"
7#include "surface.h"
8
9#include <errno.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#include <sys/fb.h>
14#include <sys/io.h>
15#include <sys/list.h>
16#include <sys/math.h>
17#include <sys/proc.h>
18#include <threads.h>
19
20static char* id;
21static fd_t data;
22
23static fd_t kbd;
24static fd_t mouse;
25
28
35
37
39
41{
42 fd_t fd = open(F("/net/local/%s/accept:nonblock", id));
43 if (fd == ERR)
44 {
45 printf("dwm: failed to open accept file (%s)\n", strerror(errno));
46 return NULL;
47 }
48
49 client_t* client = client_new(fd);
50 if (client == NULL)
51 {
52 printf("dwm: failed to accept client (%s)\n", strerror(errno));
53 close(fd);
54 return NULL;
55 }
56
57 list_push_back(&clients, &client->entry);
59 printf("dwm: accepted client %d total %lu\n", client->fd, clientAmount);
60 return client;
61}
62
63static void dwm_client_disconnect(client_t* client)
64{
65 list_remove(&clients, &client->entry);
66 client_free(client);
68 printf("dwm: disconnect client\n");
69}
70
71static void dwm_send_event_to_all(surface_id_t target, event_type_t type, void* data, uint64_t size)
72{
73 client_t* client;
74 client_t* temp;
75 LIST_FOR_EACH_SAFE(client, temp, &clients, entry)
76 {
77 if (client_send_event(client, target, type, data, size) == ERR)
78 {
80 }
81 }
82}
83
84void dwm_init(void)
85{
86 kbd = open("/dev/kbd/0/events");
87 if (kbd == ERR)
88 {
89 printf("dwm: failed to open keyboard (%s)\n", strerror(errno));
90 abort();
91 }
92
93 char* name = sreadfile("/dev/kbd/0/name");
94 if (name != NULL)
95 {
96 printf("dwm: using keyboard '%s'\n", name);
97 free(name);
98 }
99
100 mouse = open("/dev/mouse/0/events");
101 if (mouse == ERR)
102 {
103 printf("dwm: failed to open mouse (%s)\n", strerror(errno));
104 abort();
105 }
106
107 name = sreadfile("/dev/mouse/0/name");
108 if (name != NULL)
109 {
110 printf("dwm: using mouse '%s'\n", name);
111 free(name);
112 }
113
114 id = sreadfile("/net/local/seqpacket:nonblock");
115 if (id == NULL)
116 {
117 printf("dwm: failed to read seqpacket id (%s)\n", strerror(errno));
118 abort();
119 }
120
121 if (swritefile(F("/net/local/%s/ctl", id), "bind dwm && listen") == ERR)
122 {
123 printf("dwm: failed to bind socket (%s)\n", strerror(errno));
124 abort();
125 }
126
127 data = open(F("/net/local/%s/data", id));
128 if (data == ERR)
129 {
130 printf("dwm: failed to open data file (%s)\n", strerror(errno));
131 abort();
132 }
133
135 clientAmount = 0;
136
139 wall = NULL;
140 cursor = NULL;
143
144 focus = NULL;
145
146 pollCtx = NULL;
147}
148
149void dwm_deinit(void)
150{
151 close(kbd);
152 close(mouse);
153 close(data);
154
155 free(pollCtx);
156}
157
159{
160 event_report_t event;
161 event.flags = flags;
162 surface_get_info(surface, &event.info);
163
164 client_send_event(client, surface->id, EVENT_REPORT, &event, sizeof(event));
165
166 event_global_report_t globaEVENT_LIB;
167 globaEVENT_LIB.flags = flags;
168 globaEVENT_LIB.info = event.info;
169
170 dwm_send_event_to_all(SURFACE_ID_NONE, EVENT_GLOBAL_REPORT, &globaEVENT_LIB, sizeof(globaEVENT_LIB));
171}
172
174{
175 surface_t* panel;
176 LIST_FOR_EACH_REVERSE(panel, &panels, dwmEntry)
177 {
178 if (panel->id == id)
179 {
180 return panel;
181 }
182 }
183
184 surface_t* window;
185 LIST_FOR_EACH_REVERSE(window, &windows, dwmEntry)
186 {
187 if (window->id == id)
188 {
189 return window;
190 }
191 }
192
193 if (wall != NULL && wall->id == id)
194 {
195 return wall;
196 }
197
198 if (fullscreen != NULL && fullscreen->id == id)
199 {
200 return fullscreen;
201 }
202
203 return NULL;
204}
205
207{
208 switch (surface->type)
209 {
210 case SURFACE_WINDOW:
211 {
212 list_push_back(&windows, &surface->dwmEntry);
213 }
214 break;
215 case SURFACE_PANEL:
216 {
217 list_push_back(&panels, &surface->dwmEntry);
218 }
219 break;
220 case SURFACE_CURSOR:
221 {
222 if (cursor != NULL)
223 {
224 printf("dwm: attach (cursor != NULL)\n");
225 errno = EALREADY;
226 return ERR;
227 }
228
229 cursor = surface;
230 }
231 break;
232 case SURFACE_WALL:
233 {
234 if (wall != NULL)
235 {
236 printf("dwm: attach (wall != NULL)\n");
237 errno = EALREADY;
238 return ERR;
239 }
240
241 wall = surface;
242 }
243 break;
245 {
246 if (fullscreen != NULL)
247 {
248 printf("dwm: attach (fullscreen != NULL)\n");
249 errno = EALREADY;
250 return ERR;
251 }
252
253 fullscreen = surface;
254 focus = surface;
255 }
256 break;
257 default:
258 {
259 printf("dwm: attach (default)\n");
260 errno = EINVAL;
261 return ERR;
262 }
263 }
264
266 surface_get_info(surface, &event.info);
268 return 0;
269}
270
271void dwm_detach(surface_t* surface)
272{
273 if (surface == focus)
274 {
275 focus = NULL;
276 }
277 if (surface == prevCursorTarget)
278 {
280 }
281
283 surface_get_info(surface, &event.info);
285
286 switch (surface->type)
287 {
288 case SURFACE_WINDOW:
289 {
290 list_remove(&windows, &surface->dwmEntry);
291 }
292 break;
293 case SURFACE_PANEL:
294 {
295 list_remove(&panels, &surface->dwmEntry);
296 }
297 break;
298 case SURFACE_CURSOR:
299 {
300 cursor = NULL;
301 }
302 break;
303 case SURFACE_WALL:
304 {
305 wall = NULL;
306 }
307 break;
309 {
311 focus = NULL;
312 }
313 break;
314 default:
315 {
316 printf("dwm: attempt to detach invalid surface\n");
317 abort();
318 }
319 }
320}
321
323{
324 if (fullscreen != NULL)
325 {
326 return;
327 }
328
329 if (surface == focus)
330 {
331 return;
332 }
333
334 if (focus != NULL)
335 {
336 focus->flags &= ~SURFACE_FOCUSED;
338 }
339
340 if (surface != NULL)
341 {
342 surface->flags |= SURFACE_FOCUSED;
343 if (surface->type == SURFACE_WINDOW)
344 {
345 // Move to end of list
346 list_remove(&windows, &surface->dwmEntry);
347 list_push_back(&windows, &surface->dwmEntry);
348 }
349 focus = surface;
351 }
352 else
353 {
354 focus = NULL;
355 }
356}
357
359{
360 if (fullscreen != NULL)
361 {
362 return fullscreen;
363 }
364
365 surface_t* panel;
366 LIST_FOR_EACH_REVERSE(panel, &panels, dwmEntry)
367 {
368 rect_t rect = SURFACE_SCREEN_RECT(panel);
369 if (RECT_CONTAINS_POINT(&rect, point))
370 {
371 return panel;
372 }
373 }
374
375 surface_t* window;
376 LIST_FOR_EACH_REVERSE(window, &windows, dwmEntry)
377 {
378 rect_t rect = SURFACE_SCREEN_RECT(window);
379 if (RECT_CONTAINS_POINT(&rect, point))
380 {
381 return window;
382 }
383 }
384
385 if (wall == NULL)
386 {
387 return NULL;
388 }
389
390 rect_t wallRect = SURFACE_SCREEN_RECT(wall);
391 if (RECT_CONTAINS_POINT(&wallRect, point))
392 {
393 return wall;
394 }
395
396 return NULL;
397}
398
399/// @todo Optimize this function to avoid iterating over all surfaces every time.
401{
402 clock_t deadline = CLOCKS_NEVER;
403 surface_t* nextTimer = NULL;
404
405 surface_t* window;
406 LIST_FOR_EACH(window, &windows, dwmEntry)
407 {
408 if (window->timer.deadline < deadline)
409 {
410 deadline = window->timer.deadline;
411 nextTimer = window;
412 }
413 }
414
415 surface_t* panel;
416 LIST_FOR_EACH(panel, &panels, dwmEntry)
417 {
418 if (panel->timer.deadline < deadline)
419 {
420 deadline = panel->timer.deadline;
421 nextTimer = panel;
422 }
423 }
424
425 if (wall != NULL && wall->timer.deadline < deadline)
426 {
427 deadline = wall->timer.deadline;
428 nextTimer = wall;
429 }
430
431 if (cursor != NULL && cursor->timer.deadline < deadline)
432 {
433 deadline = cursor->timer.deadline;
434 nextTimer = cursor;
435 }
436
437 if (fullscreen != NULL && fullscreen->timer.deadline < deadline)
438 {
439 deadline = fullscreen->timer.deadline;
440 nextTimer = fullscreen;
441 }
442
443 return nextTimer;
444}
445
446static void dwm_kbd_read(void)
447{
448 if (poll1(kbd, POLLIN, 0) == POLLIN)
449 {
450 // The kbd_event_t and event_kbd_t naming is a bit weird.
451 kbd_event_t kbdEvent;
452 if (read(kbd, &kbdEvent, sizeof(kbd_event_t)) != sizeof(kbd_event_t))
453 {
454 printf("dwm: failed to read kbd event\n");
455 return;
456 }
457
458 if (focus == NULL)
459 {
460 return;
461 }
462
463 event_kbd_t event;
464 event.type = kbdEvent.type;
465 event.mods = kbdEvent.mods;
466 event.code = kbdEvent.code;
467 event.ascii = kbd_ascii(event.code, event.mods);
469
470 event_global_kbd_t globaEVENT_LIB = event;
471 dwm_send_event_to_all(SURFACE_ID_NONE, EVENT_GLOBAL_KBD, &globaEVENT_LIB, sizeof(globaEVENT_LIB));
472 }
473}
474
475static void dwm_handle_mouse_event(const mouse_event_t* mouseEvent)
476{
477 static mouse_buttons_t prevHeld = MOUSE_NONE;
478
479 if (cursor == NULL)
480 {
481 return;
482 }
483
484 mouse_buttons_t held = mouseEvent->buttons;
485 mouse_buttons_t pressed = mouseEvent->buttons & ~prevHeld;
486 mouse_buttons_t released = prevHeld & ~mouseEvent->buttons;
487
488 point_t oldCursorPos = cursor->pos;
489 cursor->pos.x = CLAMP(cursor->pos.x + mouseEvent->deltaX, 0, (int64_t)screen_width() - 1);
490 cursor->pos.y = CLAMP(cursor->pos.y + mouseEvent->deltaY, 0, (int64_t)screen_height() - 1);
491
492 point_t cursorDelta = {.x = cursor->pos.x - oldCursorPos.x, .y = cursor->pos.y - oldCursorPos.y};
494 if (surface != prevCursorTarget)
495 {
496 if (prevCursorTarget != NULL)
497 {
498 event_cursor_leave_t event = {
499 .held = held,
500 .pressed = MOUSE_NONE,
501 .released = MOUSE_NONE,
502 .pos.x = cursor->pos.x - prevCursorTarget->pos.x,
503 .pos.y = cursor->pos.y - prevCursorTarget->pos.y,
504 .screenPos = cursor->pos,
505 .delta = cursorDelta,
506 };
508 sizeof(event_cursor_leave_t));
509 }
510
511 if (surface != NULL)
512 {
513 event_cursor_enter_t event = {
514 .held = held,
515 .pressed = MOUSE_NONE,
516 .released = MOUSE_NONE,
517 .pos.x = cursor->pos.x - surface->pos.x,
518 .pos.y = cursor->pos.y - surface->pos.y,
519 .screenPos = cursor->pos,
520 .delta = cursorDelta,
521 };
522 client_send_event(surface->client, surface->id, EVENT_CURSOR_ENTER, &event, sizeof(event_cursor_enter_t));
523 }
524 prevCursorTarget = surface;
525 }
526
527 if (pressed != MOUSE_NONE)
528 {
529 dwm_focus_set(surface);
530 rect_t surfaceRect = SURFACE_SCREEN_RECT(surface);
531 compositor_invalidate(&surfaceRect);
532 }
533
534 surface_t* destSurface;
535 if (held != MOUSE_NONE && focus != NULL)
536 {
537 destSurface = focus;
538 }
539 else
540 {
541 destSurface = surface;
542 }
543
544 if (destSurface != NULL)
545 {
546 event_mouse_t event = {
547 .held = held,
548 .pressed = pressed,
549 .released = released,
550 .pos.x = cursor->pos.x - destSurface->pos.x,
551 .pos.y = cursor->pos.y - destSurface->pos.y,
552 .screenPos = cursor->pos,
553 .delta = cursorDelta,
554 };
555 client_send_event(destSurface->client, destSurface->id, EVENT_MOUSE, &event, sizeof(event_mouse_t));
556
557 event_global_mouse_t globaEVENT_LIB = event;
558 globaEVENT_LIB.pos = globaEVENT_LIB.screenPos;
559 dwm_send_event_to_all(SURFACE_ID_NONE, EVENT_GLOBAL_MOUSE, &globaEVENT_LIB, sizeof(globaEVENT_LIB));
560 }
561
562 prevHeld = held;
563}
564
565static void dwm_mouse_read(void)
566{
567 static mouse_buttons_t prevHeld = MOUSE_NONE;
568
569 mouse_event_t total = {0};
570 bool received = false;
571 while (1)
572 {
573 if (poll1(mouse, POLLIN, 0) != POLLIN)
574 {
575 break;
576 }
577
578 mouse_event_t mouseEvent;
579 if (read(mouse, &mouseEvent, sizeof(mouse_event_t)) != sizeof(mouse_event_t))
580 {
581 printf("dwm: failed to read mouse event\n");
582 return;
583 }
584
585 total.buttons |= mouseEvent.buttons;
586 total.deltaX += mouseEvent.deltaX;
587 total.deltaY += mouseEvent.deltaY;
588 received = true;
589 }
590
591 if (!received)
592 {
593 return;
594 }
595
597}
598
599static void dwm_poll_ctx_update(void)
600{
601 void* newCtx = realloc(pollCtx, sizeof(poll_ctx_t) + (sizeof(pollfd_t) * clientAmount));
602 if (newCtx == NULL)
603 {
604 printf("dwm: failed to realloc pollCtx\n");
605 abort();
606 }
607 else
608 {
609 pollCtx = newCtx;
610 }
611 pollCtx->data.fd = data;
613 pollCtx->data.revents = 0;
614 pollCtx->kbd.fd = kbd;
616 pollCtx->kbd.revents = 0;
619 pollCtx->mouse.revents = 0;
620
621 uint64_t i = 0;
622 client_t* client;
623 LIST_FOR_EACH(client, &clients, entry)
624 {
625 pollfd_t* fd = &pollCtx->clients[i++];
626 fd->fd = client->fd;
627 fd->events = POLLIN;
628 fd->revents = 0;
629 }
630}
631
632static void dwm_poll(void)
633{
635
636 surface_t* timer = dwm_next_timer();
637 clock_t timeout = CLOCKS_NEVER;
638 if (timer != NULL)
639 {
640 clock_t time = uptime();
641 timeout = timer->timer.deadline > time ? timer->timer.deadline - time : 0;
642 }
643
644 uint64_t events = poll((pollfd_t*)pollCtx, sizeof(poll_ctx_t) / sizeof(pollfd_t) + clientAmount, timeout);
645 if (events == ERR)
646 {
647 printf("dwm: poll failed (%s)\n", strerror(errno));
648 abort();
649 }
650
651 clock_t time = uptime();
652 if (timer != NULL && time >= timer->timer.deadline)
653 {
654 if (timer->timer.flags & TIMER_REPEAT)
655 {
656 timer->timer.deadline = time + timer->timer.timeout;
657 }
658 else
659 {
660 timer->timer.deadline = CLOCKS_NEVER;
661 }
662 client_send_event(timer->client, timer->id, EVENT_TIMER, NULL, 0);
663 }
664}
665
666static void dwm_update(void)
667{
668 dwm_poll();
669
670 if (pollCtx->data.revents & POLLIN)
671 {
673 return; // The clients array is now invalid, so we have to update it.
674 }
675 if (pollCtx->kbd.revents & POLLIN)
676 {
677 dwm_kbd_read();
678 }
680 {
682 }
683
684 uint64_t i = 0;
685 client_t* client;
686 client_t* temp;
687 LIST_FOR_EACH_SAFE(client, temp, &clients, entry)
688 {
689 pollfd_t* fd = &pollCtx->clients[i++];
690 if (fd->revents & POLLHUP)
691 {
692 printf("dwm: client %d hung up\n", client->fd);
693 dwm_client_disconnect(client);
694 }
695 else if (fd->revents & POLLERR)
696 {
697 printf("dwm: client %d error\n", client->fd);
698 dwm_client_disconnect(client);
699 }
700 else if (fd->revents & POLLIN)
701 {
702 if (client_receive_cmds(client) == ERR)
703 {
704 printf("dwm: client %d receive commands failed (%s)\n", client->fd, strerror(errno));
705 dwm_client_disconnect(client);
706 }
707 }
708 }
709
710 compositor_ctx_t ctx = {
711 .windows = &windows,
712 .panels = &panels,
713 .wall = wall,
714 .cursor = cursor,
715 .fullscreen = fullscreen,
716 };
717 compositor_draw(&ctx);
718}
719
720void dwm_loop(void)
721{
722 while (1)
723 {
724 dwm_update();
725 }
726}
uint64_t client_receive_cmds(client_t *client)
Definition client.c:427
void client_free(client_t *client)
Definition client.c:52
uint64_t client_send_event(client_t *client, surface_id_t target, event_type_t type, void *data, uint64_t size)
Definition client.c:516
client_t * client_new(fd_t fd)
Definition client.c:32
#define CLOCKS_NEVER
Definition clock_t.h:16
@ TIMER_REPEAT
Definition cmd.h:77
void compositor_invalidate(const rect_t *rect)
Definition compositor.c:135
void compositor_draw(compositor_ctx_t *ctx)
Definition compositor.c:117
static surface_t * wall
Definition dwm.c:31
static fd_t kbd
Definition dwm.c:23
static uint64_t clientAmount
Definition dwm.c:27
static void dwm_update(void)
Definition dwm.c:666
static surface_t * cursor
Definition dwm.c:32
static void dwm_handle_mouse_event(const mouse_event_t *mouseEvent)
Definition dwm.c:475
static poll_ctx_t * pollCtx
Definition dwm.c:38
static void dwm_client_disconnect(client_t *client)
Definition dwm.c:63
static list_t panels
Definition dwm.c:30
static surface_t * fullscreen
Definition dwm.c:33
static list_t clients
Definition dwm.c:26
static surface_t * dwm_next_timer(void)
Definition dwm.c:400
static void dwm_mouse_read(void)
Definition dwm.c:565
static list_t windows
Definition dwm.c:29
static surface_t * focus
Definition dwm.c:36
static void dwm_send_event_to_all(surface_id_t target, event_type_t type, void *data, uint64_t size)
Definition dwm.c:71
static fd_t data
Definition dwm.c:21
static client_t * dwm_client_accept(void)
Definition dwm.c:40
static surface_t * prevCursorTarget
Definition dwm.c:34
static fd_t mouse
Definition dwm.c:24
static surface_t * dwm_surface_under_point(const point_t *point)
Definition dwm.c:358
static void dwm_kbd_read(void)
Definition dwm.c:446
static void dwm_poll(void)
Definition dwm.c:632
static char * id
Definition dwm.c:20
static void dwm_poll_ctx_update(void)
Definition dwm.c:599
#define EVENT_GLOBAL_REPORT
Definition event.h:93
#define EVENT_GLOBAL_ATTACH
Definition event.h:91
#define EVENT_GLOBAL_DETACH
Definition event.h:92
#define EVENT_GLOBAL_KBD
Definition event.h:94
#define EVENT_CURSOR_LEAVE
Definition event.h:88
#define EVENT_MOUSE
Definition event.h:85
report_flags_t
Report flags.
Definition event.h:34
#define EVENT_CURSOR_ENTER
Definition event.h:87
#define EVENT_GLOBAL_MOUSE
Definition event.h:95
#define EVENT_KBD
Definition event.h:84
uint16_t event_type_t
Event type.
Definition event.h:72
#define EVENT_REPORT
Definition event.h:89
#define EVENT_TIMER
Definition event.h:86
@ REPORT_IS_FOCUSED
Definition event.h:38
#define SURFACE_ID_NONE
Definition surface.h:54
uint64_t surface_id_t
Definition surface.h:53
@ SURFACE_WALL
Definition surface.h:38
@ SURFACE_WINDOW
Definition surface.h:35
@ SURFACE_PANEL
Definition surface.h:36
@ SURFACE_CURSOR
Definition surface.h:37
@ SURFACE_FULLSCREEN
Definition surface.h:39
@ SURFACE_FOCUSED
Definition surface.h:50
#define EINVAL
Invalid argument.
Definition errno.h:142
#define EALREADY
Operation already in progress.
Definition errno.h:597
#define errno
Error number variable.
Definition errno.h:27
fd_t open(const char *path)
System call for opening files.
Definition open.c:9
poll_events_t poll1(fd_t fd, poll_events_t events, clock_t timeout)
Wrapper for polling one file.
Definition poll1.c:9
uint64_t close(fd_t fd)
System call for closing files.
Definition close.c:9
#define F(format,...)
Format string macro.
Definition io.h:83
uint64_t swritefile(const char *path, const char *string)
Wrapper for writing a null-terminated string directly to a file using a path.
Definition swritefile.c:4
uint64_t poll(pollfd_t *fds, uint64_t amount, clock_t timeout)
System call for polling files.
Definition poll.c:9
uint64_t read(fd_t fd, void *buffer, uint64_t count)
System call for reading from files.
Definition read.c:9
char * sreadfile(const char *path)
Wrapper for reading an entire file directly into a null-terminated string.
Definition sreadfile.c:3
@ POLLIN
File descriptor is ready to read.
Definition io.h:259
@ POLLHUP
Stream socket peer closed connection, or shut down writing of connection.
Definition io.h:262
@ POLLERR
File descriptor caused an error.
Definition io.h:261
#define LIST_FOR_EACH(elem, list, member)
Iterates over a list.
Definition list.h:63
static void list_push_back(list_t *list, list_entry_t *entry)
Pushes an entry to the end of the list.
Definition list.h:343
#define LIST_FOR_EACH_SAFE(elem, temp, list, member)
Safely iterates over a list, allowing for element removal during iteration.
Definition list.h:79
static void list_remove(list_t *list, list_entry_t *entry)
Removes a list entry from its current list.
Definition list.h:315
#define LIST_FOR_EACH_REVERSE(elem, list, member)
Iterates over a list in reverse.
Definition list.h:93
static void list_init(list_t *list)
Initializes a list.
Definition list.h:196
#define CLAMP(x, low, high)
Definition math.h:17
mouse_buttons_t
Mouse buttons enum.
Definition mouse.h:31
@ MOUSE_NONE
None.
Definition mouse.h:32
clock_t uptime(void)
System call for retreving the time since boot.
Definition uptime.c:6
#define NULL
Pointer error value.
Definition NULL.h:23
#define ERR
Integer error value.
Definition ERR.h:17
__UINT64_TYPE__ fd_t
A file descriptor.
Definition fd_t.h:12
__UINT64_TYPE__ clock_t
A nanosecond time.
Definition clock_t.h:13
void dwm_focus_set(surface_t *surface)
Definition dwm.c:322
uint64_t dwm_attach(surface_t *surface)
Definition dwm.c:206
void dwm_report_produce(surface_t *surface, client_t *client, report_flags_t flags)
Definition dwm.c:158
void dwm_detach(surface_t *surface)
Definition dwm.c:271
void dwm_loop(void)
Definition dwm.c:720
surface_t * dwm_surface_find(surface_id_t id)
Definition dwm.c:173
void dwm_init(void)
Definition dwm.c:84
void dwm_deinit(void)
Definition dwm.c:149
static const path_flag_t flags[]
Definition path.c:42
char kbd_ascii(keycode_t code, kbd_mods_t mods)
Definition kbd.c:95
#define RECT_CONTAINS_POINT(rect, point)
Definition rect.h:61
uint64_t screen_height(void)
Definition screen.c:199
uint64_t screen_width(void)
Definition screen.c:194
#define SURFACE_SCREEN_RECT(surface)
Definition surface.h:37
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__INT64_TYPE__ int64_t
Definition stdint.h:16
_PUBLIC int printf(const char *_RESTRICT format,...)
Definition printf.c:5
_PUBLIC void * realloc(void *ptr, size_t size)
Definition realloc.c:13
_PUBLIC _NORETURN void abort(void)
Definition abort.c:9
_PUBLIC void free(void *ptr)
Definition free.c:11
_PUBLIC char * strerror(int errnum)
Definition strerror.c:6
list_entry_t entry
Definition client.h:14
fd_t fd
Definition client.h:15
list_t * windows
Definition compositor.h:11
Global Attach event.
Definition event.h:191
surface_info_t info
Definition event.h:192
Global Detach event.
Definition event.h:201
surface_info_t info
Definition event.h:202
Keyboard event.
Definition event.h:138
kbd_mods_t mods
Definition event.h:140
kbd_event_type_t type
Definition event.h:139
keycode_t code
Definition event.h:141
Mouse event.
Definition event.h:151
point_t screenPos
Definition event.h:156
mouse_buttons_t held
Definition event.h:152
point_t pos
Definition event.h:155
Report event.
Definition event.h:180
surface_info_t info
Definition event.h:182
report_flags_t flags
Definition event.h:181
Keyboard event structure.
Definition kbd.h:313
kbd_event_type_t type
Type of keyboard event (press or release)
Definition kbd.h:315
keycode_t code
Keycode of the key involved in the event.
Definition kbd.h:317
kbd_mods_t mods
Active keyboard modifiers.
Definition kbd.h:316
A doubly linked list.
Definition list.h:49
Mouse event structure.
Definition mouse.h:45
mouse_buttons_t buttons
Which buttons were held down durring the event.
Definition mouse.h:47
int64_t deltaY
Change in Y coordinate.
Definition mouse.h:49
int64_t deltaX
Change in X coordinate.
Definition mouse.h:48
int64_t y
Definition point.h:14
int64_t x
Definition point.h:13
pollfd_t mouse
Definition dwm.h:24
pollfd_t clients[]
Definition dwm.h:25
pollfd_t kbd
Definition dwm.h:23
pollfd_t data
Definition dwm.h:22
Poll file descriptor structure.
Definition io.h:276
poll_events_t revents
The events that occurred.
Definition io.h:279
poll_events_t events
The events to wait for.
Definition io.h:278
fd_t fd
The file descriptor to poll.
Definition io.h:277
Definition rect.h:13
client_t * client
Definition surface.h:24
surface_type_t type
Definition surface.h:31
timer_t timer
Definition surface.h:32
point_t pos
Definition surface.h:25
surface_id_t id
Definition surface.h:30
list_entry_t dwmEntry
Definition surface.h:22
surface_flags_t flags
Definition surface.h:33
timer_flags_t flags
Definition surface.h:15
clock_t timeout
Definition surface.h:16
clock_t deadline
Definition surface.h:17
void surface_get_info(surface_t *surface, surface_info_t *info)
Definition surface.c:63
_PUBLIC time_t time(time_t *timer)
Definition time.c:5