PatchworkOS  19e446b
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 <patchwork/event.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <sys/fs.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(&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 fd_t klog = open("/dev/klog");
87 if (klog == ERR)
88 {
89 abort();
90 }
91
92 if (dup2(klog, STDOUT_FILENO) == ERR)
93 {
94 close(klog);
95 abort();
96 }
97 close(klog);
98
99 kbd = open("/dev/kbd/0/events:nonblock");
100 if (kbd == ERR)
101 {
102 printf("dwm: failed to open keyboard (%s)\n", strerror(errno));
103 abort();
104 }
105
106 char* name = readfiles("/dev/kbd/0/name");
107 if (name != NULL)
108 {
109 printf("dwm: using keyboard '%s'\n", name);
110 free(name);
111 }
112
113 mouse = open("/dev/mouse/0/events:nonblock");
114 if (mouse == ERR)
115 {
116 printf("dwm: failed to open mouse (%s)\n", strerror(errno));
117 abort();
118 }
119
120 name = readfiles("/dev/mouse/0/name");
121 if (name != NULL)
122 {
123 printf("dwm: using mouse '%s'\n", name);
124 free(name);
125 }
126
127 id = readfiles("/net/local/seqpacket:nonblock");
128 if (id == NULL)
129 {
130 printf("dwm: failed to read seqpacket id (%s)\n", strerror(errno));
131 abort();
132 }
133
134 if (writefiles(F("/net/local/%s/ctl", id), "bind dwm && listen") == ERR)
135 {
136 printf("dwm: failed to bind socket (%s)\n", strerror(errno));
137 abort();
138 }
139
140 data = open(F("/net/local/%s/data:nonblock", id));
141 if (data == ERR)
142 {
143 printf("dwm: failed to open data file (%s)\n", strerror(errno));
144 abort();
145 }
146
148 clientAmount = 0;
149
152 wall = NULL;
153 cursor = NULL;
156
157 focus = NULL;
158
159 pollCtx = NULL;
160}
161
162void dwm_deinit(void)
163{
164 close(kbd);
165 close(mouse);
166 close(data);
167
168 free(pollCtx);
169}
170
172{
173 event_report_t event;
174 event.flags = flags;
175 surface_get_info(surface, &event.info);
176
177 client_send_event(client, surface->id, EVENT_REPORT, &event, sizeof(event));
178
179 event_global_report_t globalEvent;
180 globalEvent.flags = flags;
181 globalEvent.info = event.info;
182
183 dwm_send_event_to_all(SURFACE_ID_NONE, EVENT_GLOBAL_REPORT, &globalEvent, sizeof(globalEvent));
184}
185
187{
188 surface_t* panel;
189 LIST_FOR_EACH_REVERSE(panel, &panels, dwmEntry)
190 {
191 if (panel->id == id)
192 {
193 return panel;
194 }
195 }
196
197 surface_t* window;
198 LIST_FOR_EACH_REVERSE(window, &windows, dwmEntry)
199 {
200 if (window->id == id)
201 {
202 return window;
203 }
204 }
205
206 if (wall != NULL && wall->id == id)
207 {
208 return wall;
209 }
210
211 if (fullscreen != NULL && fullscreen->id == id)
212 {
213 return fullscreen;
214 }
215
216 return NULL;
217}
218
220{
221 switch (surface->type)
222 {
223 case SURFACE_WINDOW:
224 {
225 list_push_back(&windows, &surface->dwmEntry);
226 }
227 break;
228 case SURFACE_PANEL:
229 {
230 list_push_back(&panels, &surface->dwmEntry);
231 }
232 break;
233 case SURFACE_CURSOR:
234 {
235 if (cursor != NULL)
236 {
237 printf("dwm: attach (cursor != NULL)\n");
238 errno = EALREADY;
239 return ERR;
240 }
241
242 cursor = surface;
243 }
244 break;
245 case SURFACE_WALL:
246 {
247 if (wall != NULL)
248 {
249 printf("dwm: attach (wall != NULL)\n");
250 errno = EALREADY;
251 return ERR;
252 }
253
254 wall = surface;
255 }
256 break;
258 {
259 if (fullscreen != NULL)
260 {
261 printf("dwm: attach (fullscreen != NULL)\n");
262 errno = EALREADY;
263 return ERR;
264 }
265
266 fullscreen = surface;
267 focus = surface;
268 }
269 break;
270 default:
271 {
272 printf("dwm: attach (default)\n");
273 errno = EINVAL;
274 return ERR;
275 }
276 }
277
279 surface_get_info(surface, &event.info);
281 return 0;
282}
283
284void dwm_detach(surface_t* surface)
285{
286 if (surface == focus)
287 {
288 focus = NULL;
289 }
290 if (surface == prevCursorTarget)
291 {
293 }
294
296 surface_get_info(surface, &event.info);
298
299 switch (surface->type)
300 {
301 case SURFACE_WINDOW:
302 {
303 list_remove(&surface->dwmEntry);
304 }
305 break;
306 case SURFACE_PANEL:
307 {
308 list_remove(&surface->dwmEntry);
309 }
310 break;
311 case SURFACE_CURSOR:
312 {
313 cursor = NULL;
314 }
315 break;
316 case SURFACE_WALL:
317 {
318 wall = NULL;
319 }
320 break;
322 {
324 focus = NULL;
325 }
326 break;
327 default:
328 {
329 printf("dwm: attempt to detach invalid surface\n");
330 abort();
331 }
332 }
333}
334
336{
337 if (fullscreen != NULL)
338 {
339 return;
340 }
341
342 if (surface == focus)
343 {
344 return;
345 }
346
347 if (focus != NULL)
348 {
349 focus->flags &= ~SURFACE_FOCUSED;
351 }
352
353 if (surface != NULL)
354 {
355 surface->flags |= SURFACE_FOCUSED;
356 if (surface->type == SURFACE_WINDOW)
357 {
358 // Move to end of list
359 list_remove(&surface->dwmEntry);
360 list_push_back(&windows, &surface->dwmEntry);
361 }
362 focus = surface;
364 }
365 else
366 {
367 focus = NULL;
368 }
369}
370
372{
373 if (fullscreen != NULL)
374 {
375 return fullscreen;
376 }
377
378 surface_t* panel;
379 LIST_FOR_EACH_REVERSE(panel, &panels, dwmEntry)
380 {
381 rect_t rect = SURFACE_SCREEN_RECT(panel);
382 if (RECT_CONTAINS_POINT(&rect, point))
383 {
384 return panel;
385 }
386 }
387
388 surface_t* window;
389 LIST_FOR_EACH_REVERSE(window, &windows, dwmEntry)
390 {
391 rect_t rect = SURFACE_SCREEN_RECT(window);
392 if (RECT_CONTAINS_POINT(&rect, point))
393 {
394 return window;
395 }
396 }
397
398 if (wall == NULL)
399 {
400 return NULL;
401 }
402
403 rect_t wallRect = SURFACE_SCREEN_RECT(wall);
404 if (RECT_CONTAINS_POINT(&wallRect, point))
405 {
406 return wall;
407 }
408
409 return NULL;
410}
411
412/// @todo Optimize this function to avoid iterating over all surfaces every time.
414{
415 clock_t deadline = CLOCKS_NEVER;
416 surface_t* nextTimer = NULL;
417
418 surface_t* window;
419 LIST_FOR_EACH(window, &windows, dwmEntry)
420 {
421 if (window->timer.deadline < deadline)
422 {
423 deadline = window->timer.deadline;
424 nextTimer = window;
425 }
426 }
427
428 surface_t* panel;
429 LIST_FOR_EACH(panel, &panels, dwmEntry)
430 {
431 if (panel->timer.deadline < deadline)
432 {
433 deadline = panel->timer.deadline;
434 nextTimer = panel;
435 }
436 }
437
438 if (wall != NULL && wall->timer.deadline < deadline)
439 {
440 deadline = wall->timer.deadline;
441 nextTimer = wall;
442 }
443
444 if (cursor != NULL && cursor->timer.deadline < deadline)
445 {
446 deadline = cursor->timer.deadline;
447 nextTimer = cursor;
448 }
449
450 if (fullscreen != NULL && fullscreen->timer.deadline < deadline)
451 {
452 deadline = fullscreen->timer.deadline;
453 nextTimer = fullscreen;
454 }
455
456 return nextTimer;
457}
458
459static void dwm_kbd_read(void)
460{
461 static kbd_mods_t mods = KBD_MOD_NONE;
462
463 keycode_t code = -1;
464 char suffix = -1;
465 int result = scan(kbd, "%u%c", &code, &suffix);
466 if (result != 2)
467 {
468 printf("dwm: failed to read keyboard event (s)\n", strerror(errno));
469 return;
470 }
471
472 code = kbd_translate(code);
473
474 if (code == KBD_LEFT_SHIFT || code == KBD_RIGHT_SHIFT)
475 {
476 if (suffix == '_')
477 {
478 mods |= KBD_MOD_SHIFT;
479 }
480 else
481 {
482 mods &= ~KBD_MOD_SHIFT;
483 }
484 }
485 else if (code == KBD_LEFT_CTRL || code == KBD_RIGHT_CTRL)
486 {
487 if (suffix == '_')
488 {
489 mods |= KBD_MOD_CTRL;
490 }
491 else
492 {
493 mods &= ~KBD_MOD_CTRL;
494 }
495 }
496 else if (code == KBD_LEFT_ALT || code == KBD_RIGHT_ALT)
497 {
498 if (suffix == '_')
499 {
500 mods |= KBD_MOD_ALT;
501 }
502 else
503 {
504 mods &= ~KBD_MOD_ALT;
505 }
506 }
507 else if (code == KBD_LEFT_SUPER || code == KBD_RIGHT_SUPER)
508 {
509 if (suffix == '_')
510 {
511 mods |= KBD_MOD_SUPER;
512 }
513 else
514 {
515 mods &= ~KBD_MOD_SUPER;
516 }
517 }
518 else if (code == KBD_CAPS_LOCK && suffix == '_')
519 {
520 mods ^= KBD_MOD_CAPS;
521 }
522
523 if (focus != NULL)
524 {
525 event_kbd_t event;
526 event.type = suffix == '_' ? KBD_PRESS : KBD_RELEASE;
527 event.mods = mods;
528 event.code = code;
529 event.ascii = kbd_ascii(code, mods);
531
532 event_global_kbd_t globalEvent;
533 globalEvent.type = event.type;
534 globalEvent.mods = event.mods;
535 globalEvent.code = event.code;
536 globalEvent.ascii = event.ascii;
537 dwm_send_event_to_all(SURFACE_ID_NONE, EVENT_GLOBAL_KBD, &globalEvent, sizeof(globalEvent));
538 }
539}
540
542{
543 static mouse_buttons_t prevHeld = MOUSE_NONE;
544
545 if (cursor == NULL)
546 {
547 return;
548 }
549
550 mouse_buttons_t held = buttons;
551 mouse_buttons_t pressed = buttons & ~prevHeld;
552 mouse_buttons_t released = prevHeld & ~buttons;
553
554 point_t oldCursorPos = cursor->pos;
555 cursor->pos.x = CLAMP(cursor->pos.x + x, 0, (int64_t)screen_width() - 1);
556 cursor->pos.y = CLAMP(cursor->pos.y + y, 0, (int64_t)screen_height() - 1);
557
558 point_t cursorDelta = {.x = cursor->pos.x - oldCursorPos.x, .y = cursor->pos.y - oldCursorPos.y};
560 if (surface != prevCursorTarget)
561 {
562 if (prevCursorTarget != NULL)
563 {
564 event_cursor_leave_t event = {
565 .held = held,
566 .pressed = MOUSE_NONE,
567 .released = MOUSE_NONE,
568 .pos.x = cursor->pos.x - prevCursorTarget->pos.x,
569 .pos.y = cursor->pos.y - prevCursorTarget->pos.y,
570 .screenPos = cursor->pos,
571 .delta = cursorDelta,
572 };
574 sizeof(event_cursor_leave_t));
575 }
576
577 if (surface != NULL)
578 {
579 event_cursor_enter_t event = {
580 .held = held,
581 .pressed = MOUSE_NONE,
582 .released = MOUSE_NONE,
583 .pos.x = cursor->pos.x - surface->pos.x,
584 .pos.y = cursor->pos.y - surface->pos.y,
585 .screenPos = cursor->pos,
586 .delta = cursorDelta,
587 };
588 client_send_event(surface->client, surface->id, EVENT_CURSOR_ENTER, &event, sizeof(event_cursor_enter_t));
589 }
590 prevCursorTarget = surface;
591 }
592
593 if (pressed != MOUSE_NONE)
594 {
595 dwm_focus_set(surface);
596 rect_t surfaceRect = SURFACE_SCREEN_RECT(surface);
597 compositor_invalidate(&surfaceRect);
598 }
599
600 surface_t* destSurface;
601 if (held != MOUSE_NONE && focus != NULL)
602 {
603 destSurface = focus;
604 }
605 else
606 {
607 destSurface = surface;
608 }
609
610 if (destSurface != NULL)
611 {
612 event_mouse_t event = {
613 .held = held,
614 .pressed = pressed,
615 .released = released,
616 .pos.x = cursor->pos.x - destSurface->pos.x,
617 .pos.y = cursor->pos.y - destSurface->pos.y,
618 .screenPos = cursor->pos,
619 .delta = cursorDelta,
620 };
621 client_send_event(destSurface->client, destSurface->id, EVENT_MOUSE, &event, sizeof(event_mouse_t));
622
623 event_global_mouse_t globalEvent = event;
624 globalEvent.pos = globalEvent.screenPos;
625 dwm_send_event_to_all(SURFACE_ID_NONE, EVENT_GLOBAL_MOUSE, &globalEvent, sizeof(globalEvent));
626 }
627
628 prevHeld = held;
629}
630
631static void dwm_mouse_read(void)
632{
633 static mouse_buttons_t buttons = MOUSE_NONE;
634
635 int64_t x = 0;
636 int64_t y = 0;
637 while (1)
638 {
639 int64_t value;
640 char suffix;
641 if (scan(mouse, "%lld%c", &value, &suffix) != 2)
642 {
643 if (errno != EAGAIN)
644 {
645 printf("dwm: failed to read mouse event (s)\n", strerror(errno));
646 }
647 break;
648 }
649
650 switch (suffix)
651 {
652 case 'x':
653 x += value;
654 break;
655 case 'y':
656 y += value;
657 break;
658 case '_':
659 if (x != 0 || y != 0)
660 {
661 dwm_handle_mouse_event(x, y, buttons);
662 x = 0;
663 y = 0;
664 }
665 buttons |= (1 << value);
666 dwm_handle_mouse_event(0, 0, buttons);
667 break;
668 case '^':
669 if (x != 0 || y != 0)
670 {
671 dwm_handle_mouse_event(x, y, buttons);
672 x = 0;
673 y = 0;
674 }
675 buttons &= ~(1 << value);
676 dwm_handle_mouse_event(0, 0, buttons);
677 break;
678 default:
679 printf("dwm: unknown mouse event suffix '%c'\n", suffix);
680 break;
681 }
682 }
683
684 if (x != 0 || y != 0)
685 {
686 dwm_handle_mouse_event(x, y, buttons);
687 }
688}
689
690static void dwm_poll_ctx_update(void)
691{
692 void* newCtx = realloc(pollCtx, sizeof(poll_ctx_t) + (sizeof(pollfd_t) * clientAmount));
693 if (newCtx == NULL)
694 {
695 printf("dwm: failed to realloc pollCtx\n");
696 abort();
697 }
698 else
699 {
700 pollCtx = newCtx;
701 }
702 pollCtx->data.fd = data;
704 pollCtx->data.revents = 0;
705 pollCtx->kbd.fd = kbd;
707 pollCtx->kbd.revents = 0;
710 pollCtx->mouse.revents = 0;
711
712 uint64_t i = 0;
713 client_t* client;
714 LIST_FOR_EACH(client, &clients, entry)
715 {
716 pollfd_t* fd = &pollCtx->clients[i++];
717 fd->fd = client->fd;
718 fd->events = POLLIN;
719 fd->revents = 0;
720 }
721}
722
723static void dwm_poll(void)
724{
726
727 surface_t* timer = dwm_next_timer();
728 clock_t timeout = CLOCKS_NEVER;
729 if (timer != NULL)
730 {
731 clock_t time = uptime();
732 timeout = timer->timer.deadline > time ? timer->timer.deadline - time : 0;
733 }
734
735 uint64_t events = poll((pollfd_t*)pollCtx, sizeof(poll_ctx_t) / sizeof(pollfd_t) + clientAmount, timeout);
736 if (events == ERR)
737 {
738 printf("dwm: poll failed (%s)\n", strerror(errno));
739 abort();
740 }
741
742 clock_t time = uptime();
743 if (timer != NULL && time >= timer->timer.deadline)
744 {
745 if (timer->timer.flags & TIMER_REPEAT)
746 {
747 timer->timer.deadline = time + timer->timer.timeout;
748 }
749 else
750 {
751 timer->timer.deadline = CLOCKS_NEVER;
752 }
753 client_send_event(timer->client, timer->id, EVENT_TIMER, NULL, 0);
754 }
755}
756
757static void dwm_update(void)
758{
759 dwm_poll();
760
761 if (pollCtx->data.revents & POLLIN)
762 {
764 return; // The clients array is now invalid, so we have to update it.
765 }
766 if (pollCtx->kbd.revents & POLLIN)
767 {
768 dwm_kbd_read();
769 }
771 {
773 }
774
775 uint64_t i = 0;
776 client_t* client;
777 client_t* temp;
778 LIST_FOR_EACH_SAFE(client, temp, &clients, entry)
779 {
780 pollfd_t* fd = &pollCtx->clients[i++];
781 if (fd->revents & POLLHUP)
782 {
783 printf("dwm: client %d hung up\n", client->fd);
784 dwm_client_disconnect(client);
785 }
786 else if (fd->revents & POLLERR)
787 {
788 printf("dwm: client %d error\n", client->fd);
789 dwm_client_disconnect(client);
790 }
791 else if (fd->revents & POLLIN)
792 {
793 if (client_receive_cmds(client) == ERR)
794 {
795 printf("dwm: client %d receive commands failed (%s)\n", client->fd, strerror(errno));
796 dwm_client_disconnect(client);
797 }
798 }
799 }
800
801 compositor_ctx_t ctx = {
802 .windows = &windows,
803 .panels = &panels,
804 .wall = wall,
805 .cursor = cursor,
806 .fullscreen = fullscreen,
807 };
808 compositor_draw(&ctx);
809}
810
811void dwm_loop(void)
812{
813 while (1)
814 {
815 dwm_update();
816 }
817}
int64_t x
Definition main.c:152
int64_t y
Definition main.c:153
char kbd_ascii(keycode_t code, kbd_mods_t mods)
Definition kbd.c:102
keycode_t kbd_translate(keycode_t code)
Definition kbd.c:97
uint64_t screen_height(void)
Definition screen.c:175
uint64_t screen_width(void)
Definition screen.c:170
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:18
@ 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:757
static surface_t * cursor
Definition dwm.c:32
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:413
static void dwm_mouse_read(void)
Definition dwm.c:631
static list_t windows
Definition dwm.c:29
static surface_t * focus
Definition dwm.c:36
static void dwm_handle_mouse_event(int64_t x, int64_t y, mouse_buttons_t buttons)
Definition dwm.c:541
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:371
static void dwm_kbd_read(void)
Definition dwm.c:459
static void dwm_poll(void)
Definition dwm.c:723
static char * id
Definition dwm.c:20
static void dwm_poll_ctx_update(void)
Definition dwm.c:690
#define EVENT_GLOBAL_REPORT
Definition event.h:92
#define EVENT_GLOBAL_ATTACH
Definition event.h:90
#define EVENT_GLOBAL_DETACH
Definition event.h:91
#define EVENT_GLOBAL_KBD
Definition event.h:93
#define EVENT_CURSOR_LEAVE
Definition event.h:87
#define EVENT_MOUSE
Definition event.h:84
report_flags_t
Report flags.
Definition event.h:33
#define EVENT_CURSOR_ENTER
Definition event.h:86
kbd_mods_t
Keyboard modifiers type.
Definition event.h:146
#define EVENT_GLOBAL_MOUSE
Definition event.h:94
#define EVENT_KBD
Definition event.h:83
uint16_t event_type_t
Event type.
Definition event.h:71
#define EVENT_REPORT
Definition event.h:88
mouse_buttons_t
Mouse buttons enum.
Definition event.h:173
#define EVENT_TIMER
Definition event.h:85
@ REPORT_IS_FOCUSED
Definition event.h:37
@ KBD_MOD_SUPER
Super (Windows/Command) modifier.
Definition event.h:152
@ KBD_MOD_CAPS
Caps Lock modifier.
Definition event.h:148
@ KBD_MOD_NONE
No modifier.
Definition event.h:147
@ KBD_MOD_CTRL
Control modifier.
Definition event.h:150
@ KBD_MOD_ALT
Alt modifier.
Definition event.h:151
@ KBD_MOD_SHIFT
Shift modifier.
Definition event.h:149
@ KBD_RELEASE
Key release event.
Definition event.h:138
@ KBD_PRESS
Key press event.
Definition event.h:137
@ MOUSE_NONE
None.
Definition event.h:174
#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
#define EAGAIN
Try again.
Definition errno.h:87
fd_t dup2(fd_t oldFd, fd_t newFd)
System call for duplicating file descriptors, with a destination.
Definition dup2.c:8
fd_t open(const char *path)
System call for opening files.
Definition open.c:8
size_t writefiles(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 close(fd_t fd)
System call for closing files.
Definition close.c:8
char * readfiles(const char *path)
Wrapper for reading an entire file directly into a null-terminated string.
Definition sreadfile.c:3
#define F(format,...)
Allocates a formatted string on the stack.
Definition fs.h:67
uint64_t poll(pollfd_t *fds, uint64_t amount, clock_t timeout)
System call for polling files.
Definition poll.c:8
#define STDOUT_FILENO
Standard output file descriptor.
Definition fs.h:36
uint64_t scan(fd_t fd, const char *format,...)
Wrapper for reading from a file descriptor using scan formatting.
Definition scan.c:6
@ POLLIN
File descriptor is ready to read.
Definition fs.h:288
@ POLLHUP
Stream socket peer closed connection, or shut down writing of connection.
Definition fs.h:291
@ POLLERR
File descriptor caused an error.
Definition fs.h:290
keycode_t
Keyboard keycode type.
Definition kbd.h:29
@ KBD_RIGHT_SUPER
Right Super key.
Definition kbd.h:260
@ KBD_LEFT_ALT
Left Alt key.
Definition kbd.h:255
@ KBD_LEFT_SHIFT
Left Shift key.
Definition kbd.h:254
@ KBD_RIGHT_SHIFT
Right Shift key.
Definition kbd.h:258
@ KBD_LEFT_CTRL
Left Control key.
Definition kbd.h:253
@ KBD_RIGHT_ALT
Right Alt key.
Definition kbd.h:259
@ KBD_CAPS_LOCK
Caps Lock key.
Definition kbd.h:89
@ KBD_RIGHT_CTRL
Right Control key.
Definition kbd.h:257
@ KBD_LEFT_SUPER
Left Super key.
Definition kbd.h:256
#define LIST_FOR_EACH(elem, list, member)
Iterates over a list.
Definition list.h:58
static void list_remove(list_entry_t *entry)
Removes a list entry from its current list.
Definition list.h:290
static void list_push_back(list_t *list, list_entry_t *entry)
Pushes an entry to the end of the list.
Definition list.h:322
#define LIST_FOR_EACH_SAFE(elem, temp, list, member)
Safely iterates over a list, allowing for element removal during iteration.
Definition list.h:73
#define LIST_FOR_EACH_REVERSE(elem, list, member)
Iterates over a list in reverse.
Definition list.h:86
static void list_init(list_t *list)
Initializes a list.
Definition list.h:185
#define CLAMP(x, low, high)
Definition math.h:19
clock_t uptime(void)
System call for retreving the time since boot.
Definition uptime.c:6
#define NULL
Pointer error value.
Definition NULL.h:25
#define ERR
Integer error value.
Definition ERR.h:17
__UINT64_TYPE__ fd_t
File descriptor type.
Definition fd_t.h:10
__UINT64_TYPE__ clock_t
A nanosecond time.
Definition clock_t.h:13
void dwm_focus_set(surface_t *surface)
Definition dwm.c:335
uint64_t dwm_attach(surface_t *surface)
Definition dwm.c:219
void dwm_report_produce(surface_t *surface, client_t *client, report_flags_t flags)
Definition dwm.c:171
void dwm_detach(surface_t *surface)
Definition dwm.c:284
void dwm_loop(void)
Definition dwm.c:811
surface_t * dwm_surface_find(surface_id_t id)
Definition dwm.c:186
void dwm_init(void)
Definition dwm.c:84
void dwm_deinit(void)
Definition dwm.c:162
static dentry_t * klog
Definition log.c:29
static const path_flag_t flags[]
Definition path.c:47
#define RECT_CONTAINS_POINT(rect, point)
Definition rect.h:61
#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:3
_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:226
surface_info_t info
Definition event.h:227
Global Detach event.
Definition event.h:236
surface_info_t info
Definition event.h:237
Keyboard event.
Definition event.h:161
kbd_mods_t mods
Definition event.h:163
kbd_event_type_t type
Definition event.h:162
keycode_t code
Definition event.h:164
char ascii
Definition event.h:165
Mouse event.
Definition event.h:186
point_t screenPos
Definition event.h:191
mouse_buttons_t held
Definition event.h:187
point_t pos
Definition event.h:190
Report event.
Definition event.h:215
surface_info_t info
Definition event.h:217
report_flags_t flags
Definition event.h:216
A doubly linked list.
Definition list.h:46
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 fs.h:305
poll_events_t revents
The events that occurred.
Definition fs.h:308
poll_events_t events
The events to wait for.
Definition fs.h:307
fd_t fd
The file descriptor to poll.
Definition fs.h:306
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