]> git.lizzy.rs Git - bspwm.git/blob - bspwm.c
Toggle fullscreen, cycle leaf, more messages
[bspwm.git] / bspwm.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <signal.h>
6 #include <fcntl.h>
7 #include <sys/socket.h>
8 #include <sys/un.h>
9 #include <sys/select.h>
10 #include <sys/stat.h>
11 #include <sys/wait.h>
12 #include <xcb/xcb.h>
13 #include <xcb/xcb_event.h>
14 #include <xcb/xcb_ewmh.h>
15 #include "helpers.h"
16 #include "types.h"
17 #include "settings.h"
18 #include "messages.h"
19 #include "rules.h"
20 #include "events.h"
21 #include "common.h"
22 #include "utils.h"
23 #include "bspwm.h"
24 #include "tree.h"
25 #include "ewmh.h"
26
27 void quit(void)
28 {
29     running = false;
30 }
31
32 int register_events(void)
33 {
34     xcb_generic_error_t *err;
35     uint32_t values[] = {XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_BUTTON_PRESS};
36     err = xcb_request_check(dpy, xcb_change_window_attributes_checked(dpy, screen->root, XCB_CW_EVENT_MASK, values));
37     if (err != NULL)
38         return 1;
39     return 0;
40 }
41
42
43 void handle_zombie(int sig)
44 {
45     while (waitpid(-1, NULL, WNOHANG) > 0)
46         ;
47     signal(sig, handle_zombie);
48 }
49
50 void setup(int default_screen)
51 {
52     signal(SIGCHLD, handle_zombie);
53     ewmh_init();
54     screen = screen_of_display(dpy, default_screen);
55     if (!screen)
56         die("error: cannot aquire screen\n");
57
58     screen_width = screen->width_in_pixels;
59     screen_height = screen->height_in_pixels;
60
61     xcb_atom_t net_atoms[] = {ewmh._NET_SUPPORTED, ewmh._NET_WM_STATE_FULLSCREEN, ewmh._NET_WM_STATE, ewmh._NET_ACTIVE_WINDOW};
62
63     xcb_ewmh_set_supported(&ewmh, default_screen, LENGTH(net_atoms), net_atoms);
64     xcb_ewmh_set_wm_name(&ewmh, screen->root, LENGTH(WM_NAME), WM_NAME);
65
66     desk = make_desktop(DESK_NAME);
67     last_desk = NULL;
68     desk_head = desk;
69     desk_tail = desk;
70     rule_head = make_rule();
71
72     split_mode = MODE_AUTOMATIC;
73 }
74
75 int main(void)
76 {
77     fd_set descriptors;
78     int sock_fd, ret_fd, dpy_fd, sel, nbr;
79     struct sockaddr_un sock_address;
80     char *sock_path;
81     char msg[BUFSIZ], rsp[BUFSIZ];
82
83     xcb_generic_event_t *event;
84
85     running = true;
86
87     dpy = xcb_connect(NULL, &default_screen);
88
89     if (xcb_connection_has_error(dpy))
90         die("error: cannot open display\n");
91
92     setup(default_screen);
93
94     /* if (register_events() == 1) { */
95     /*     xcb_disconnect(dpy); */
96     /*     die("another WM is already running\n"); */
97     /* } */
98
99     dpy_fd = xcb_get_file_descriptor(dpy);
100
101     sock_path = getenv(SOCK_PATH);
102
103     if (sock_path == NULL)
104         die("BSPWM_SOCKET environment variable is not set\n");
105
106     sock_address.sun_family = AF_UNIX;
107     strcpy(sock_address.sun_path, sock_path);
108     unlink(sock_path);
109
110     sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
111
112     if (sock_fd == -1) 
113         die("error: could not create socket\n");
114
115     bind(sock_fd, (struct sockaddr *) &sock_address, sizeof(sock_address));
116     listen(sock_fd, SOMAXCONN);
117
118     sel = MAX(sock_fd, dpy_fd) + 1;
119
120     load_settings();
121     run_autostart();
122     update_root_dimensions();
123
124     xcb_flush(dpy);
125
126     while (running) {
127
128         FD_ZERO(&descriptors);
129         FD_SET(sock_fd, &descriptors);
130         FD_SET(dpy_fd, &descriptors);
131
132         if (select(sel, &descriptors, NULL, NULL, NULL)) {
133
134             if (FD_ISSET(dpy_fd, &descriptors)) {
135                 while ((event = xcb_poll_for_event(dpy)) != NULL) {
136                     handle_event(event);
137                     free(event);
138                 }
139             }
140
141             if (FD_ISSET(sock_fd, &descriptors)) {
142                 ret_fd = accept(sock_fd, NULL, 0);
143                 if (ret_fd > 0 && (nbr = recv(ret_fd, msg, sizeof(msg), 0)) > 0) {
144                     msg[nbr] = '\0';
145                     strcpy(rsp, EMPTY_RESPONSE);
146                     process_message(msg, rsp);
147                     send(ret_fd, rsp, strlen(rsp), 0);
148                     close(ret_fd);
149                 }
150             }
151         }
152     }
153
154     close(sock_fd);
155     xcb_disconnect(dpy);
156     return 0;
157 }