💾 Archived View for gemini.rmf-dev.com › repo › Vaati › cwm › files › f81a2f684d447ad4b9ce05487ddd05… captured on 2023-01-29 at 04:31:20. Gemini links have been rewritten to link to archived content

View Raw

More Information

➡️ Next capture (2023-03-20)

-=-=-=-=-=-=-

0 /*

1 * calmwm - the calm window manager

2 *

3 * Copyright (c) 2004 Marius Aamodt Eriksen <marius@monkey.org>

4 *

5 * Permission to use, copy, modify, and distribute this software for any

6 * purpose with or without fee is hereby granted, provided that the above

7 * copyright notice and this permission notice appear in all copies.

8 *

9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES

10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF

11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR

12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES

13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN

14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF

15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

16 *

17 * $OpenBSD$

18 */

19

20 #include <sys/types.h>

21 #include <sys/queue.h>

22 #include <sys/wait.h>

23

24 #include <err.h>

25 #include <errno.h>

26 #include <getopt.h>

27 #include <limits.h>

28 #include <locale.h>

29 #include <poll.h>

30 #include <signal.h>

31 #include <stdio.h>

32 #include <stdlib.h>

33 #include <string.h>

34 #include <unistd.h>

35

36 #include "calmwm.h"

37

38 Display *X_Dpy;

39 Time Last_Event_Time = CurrentTime;

40 Atom cwmh[CWMH_NITEMS];

41 Atom ewmh[EWMH_NITEMS];

42 struct screen_q Screenq = TAILQ_HEAD_INITIALIZER(Screenq);

43 struct conf Conf;

44 volatile sig_atomic_t cwm_status;

45

46 __dead void usage(void);

47 static void sighdlr(int);

48 static int x_errorhandler(Display *, XErrorEvent *);

49 static int x_init(const char *);

50 static void x_teardown(void);

51 static int x_wmerrorhandler(Display *, XErrorEvent *);

52

53 int

54 main(int argc, char **argv)

55 {

56 char *display_name = NULL;

57 char *fallback;

58 int ch, xfd, nflag = 0;

59 struct pollfd pfd[1];

60

61 if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())

62 warnx("no locale support");

63 mbtowc(NULL, NULL, MB_CUR_MAX);

64

65 conf_init(&Conf);

66

67 fallback = u_argv(argv);

68 Conf.wm_argv = u_argv(argv);

69 while ((ch = getopt(argc, argv, "c:d:nv")) != -1) {

70 switch (ch) {

71 case 'c':

72 free(Conf.conf_file);

73 Conf.conf_file = xstrdup(optarg);

74 break;

75 case 'd':

76 display_name = optarg;

77 break;

78 case 'n':

79 nflag = 1;

80 break;

81 case 'v':

82 Conf.debug++;

83 break;

84 default:

85 usage();

86 }

87 }

88 argc -= optind;

89 argv += optind;

90

91 if (signal(SIGCHLD, sighdlr) == SIG_ERR ||

92 signal(SIGHUP, sighdlr) == SIG_ERR ||

93 signal(SIGINT, sighdlr) == SIG_ERR ||

94 signal(SIGTERM, sighdlr) == SIG_ERR)

95 err(1, "signal");

96

97 if (parse_config(Conf.conf_file, &Conf) == -1) {

98 warnx("error parsing config file");

99 if (nflag)

100 return 1;

101 }

102 if (nflag)

103 return 0;

104

105 xfd = x_init(display_name);

106 cwm_status = CWM_RUNNING;

107

108 if (pledge("stdio rpath proc exec", NULL) == -1)

109 err(1, "pledge");

110

111 memset(&pfd, 0, sizeof(pfd));

112 pfd[0].fd = xfd;

113 pfd[0].events = POLLIN;

114 while (cwm_status == CWM_RUNNING) {

115 xev_process();

116 if (poll(pfd, 1, INFTIM) == -1) {

117 if (errno != EINTR)

118 warn("poll");

119 }

120 }

121 x_teardown();

122 if (cwm_status == CWM_EXEC_WM) {

123 u_exec(Conf.wm_argv);

124 warnx("'%s' failed to start, starting fallback", Conf.wm_argv);

125 u_exec(fallback);

126 }

127

128 return 0;

129 }

130

131 static int

132 x_init(const char *dpyname)

133 {

134 int i;

135

136 if ((X_Dpy = XOpenDisplay(dpyname)) == NULL)

137 errx(1, "unable to open display \"%s\"", XDisplayName(dpyname));

138

139 XSetErrorHandler(x_wmerrorhandler);

140 XSelectInput(X_Dpy, DefaultRootWindow(X_Dpy), SubstructureRedirectMask);

141 XSync(X_Dpy, False);

142 XSetErrorHandler(x_errorhandler);

143

144 Conf.xrandr = XRRQueryExtension(X_Dpy, &Conf.xrandr_event_base, &i);

145

146 xu_atom_init();

147 conf_cursor(&Conf);

148

149 for (i = 0; i < ScreenCount(X_Dpy); i++)

150 screen_init(i);

151

152 return ConnectionNumber(X_Dpy);

153 }

154

155 static void

156 x_teardown(void)

157 {

158 struct screen_ctx *sc;

159 unsigned int i;

160

161 conf_clear(&Conf);

162

163 TAILQ_FOREACH(sc, &Screenq, entry) {

164 for (i = 0; i < CWM_COLOR_NITEMS; i++)

165 XftColorFree(X_Dpy, DefaultVisual(X_Dpy, sc->which),

166 DefaultColormap(X_Dpy, sc->which),

167 &sc->xftcolor[i]);

168 XftFontClose(X_Dpy, sc->xftfont);

169 XUngrabKey(X_Dpy, AnyKey, AnyModifier, sc->rootwin);

170 }

171 XUngrabPointer(X_Dpy, CurrentTime);

172 XUngrabKeyboard(X_Dpy, CurrentTime);

173 for (i = 0; i < CF_NITEMS; i++)

174 XFreeCursor(X_Dpy, Conf.cursor[i]);

175 XSync(X_Dpy, False);

176 XSetInputFocus(X_Dpy, PointerRoot, RevertToPointerRoot, CurrentTime);

177 XCloseDisplay(X_Dpy);

178 }

179

180 static int

181 x_wmerrorhandler(Display *dpy, XErrorEvent *e)

182 {

183 errx(1, "root window unavailable - perhaps another wm is running?");

184 return 0;

185 }

186

187 static int

188 x_errorhandler(Display *dpy, XErrorEvent *e)

189 {

190 #ifdef DEBUG

191 char msg[80], number[80], req[80];

192

193 XGetErrorText(X_Dpy, e->error_code, msg, sizeof(msg));

194 (void)snprintf(number, sizeof(number), "%d", e->request_code);

195 XGetErrorDatabaseText(X_Dpy, "XRequest", number,

196 "<unknown>", req, sizeof(req));

197

198 warnx("%s(0x%x): %s", req, (unsigned int)e->resourceid, msg);

199 #endif

200 return 0;

201 }

202

203 static void

204 sighdlr(int sig)

205 {

206 pid_t pid;

207 int save_errno = errno, status;

208

209 switch (sig) {

210 case SIGCHLD:

211 /* Collect dead children. */

212 while ((pid = waitpid(WAIT_ANY, &status, WNOHANG)) > 0 ||

213 (pid < 0 && errno == EINTR))

214 ;

215 break;

216 case SIGHUP:

217 cwm_status = CWM_EXEC_WM;

218 break;

219 case SIGINT:

220 case SIGTERM:

221 cwm_status = CWM_QUIT;

222 break;

223 }

224

225 errno = save_errno;

226 }

227

228 __dead void

229 usage(void)

230 {

231 extern char *__progname;

232

233 (void)fprintf(stderr, "usage: %s [-nv] [-c file] [-d display]\n",

234 __progname);

235 exit(1);

236 }

237