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

View Raw

More Information

⬅️ Previous capture (2023-01-29)

➡️ 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

23 #include <err.h>

24 #include <errno.h>

25 #include <limits.h>

26 #include <stdarg.h>

27 #include <stdio.h>

28 #include <stdlib.h>

29 #include <string.h>

30 #include <unistd.h>

31

32 #include "calmwm.h"

33

34 static struct geom screen_apply_gap(struct screen_ctx *, struct geom);

35 static void screen_scan(struct screen_ctx *);

36

37 void

38 screen_init(int which)

39 {

40 struct screen_ctx *sc;

41 XSetWindowAttributes attr;

42

43 sc = xmalloc(sizeof(*sc));

44

45 TAILQ_INIT(&sc->clientq);

46 TAILQ_INIT(&sc->regionq);

47 TAILQ_INIT(&sc->groupq);

48

49 sc->which = which;

50 sc->rootwin = RootWindow(X_Dpy, sc->which);

51 sc->colormap = DefaultColormap(X_Dpy, sc->which);

52 sc->visual = DefaultVisual(X_Dpy, sc->which);

53 sc->cycling = 0;

54 sc->hideall = 0;

55

56 conf_screen(sc);

57

58 xu_ewmh_net_supported(sc);

59 xu_ewmh_net_supported_wm_check(sc);

60

61 conf_group(sc);

62 sc->group_last = sc->group_active;

63 screen_update_geometry(sc);

64

65 xu_ewmh_net_desktop_names(sc);

66 xu_ewmh_net_number_of_desktops(sc);

67 xu_ewmh_net_showing_desktop(sc);

68 xu_ewmh_net_virtual_roots(sc);

69

70 attr.cursor = Conf.cursor[CF_NORMAL];

71 attr.event_mask = SubstructureRedirectMask | SubstructureNotifyMask |

72 EnterWindowMask | PropertyChangeMask | ButtonPressMask;

73 XChangeWindowAttributes(X_Dpy, sc->rootwin, (CWEventMask | CWCursor), &attr);

74

75 if (Conf.xrandr)

76 XRRSelectInput(X_Dpy, sc->rootwin, RRScreenChangeNotifyMask);

77

78 screen_scan(sc);

79 screen_updatestackingorder(sc);

80

81 TAILQ_INSERT_TAIL(&Screenq, sc, entry);

82

83 XSync(X_Dpy, False);

84 }

85

86 static void

87 screen_scan(struct screen_ctx *sc)

88 {

89 struct client_ctx *cc, *active = NULL;

90 Window *wins, w0, w1, rwin, cwin;

91 unsigned int nwins, i, mask;

92 int rx, ry, wx, wy;

93

94 XQueryPointer(X_Dpy, sc->rootwin, &rwin, &cwin,

95 &rx, &ry, &wx, &wy, &mask);

96

97 if (XQueryTree(X_Dpy, sc->rootwin, &w0, &w1, &wins, &nwins)) {

98 for (i = 0; i < nwins; i++) {

99 if ((cc = client_init(wins[i], sc)) != NULL)

100 if (cc->win == cwin)

101 active = cc;

102 }

103 XFree(wins);

104 }

105 if (active)

106 client_set_active(active);

107 }

108

109 struct screen_ctx *

110 screen_find(Window win)

111 {

112 struct screen_ctx *sc;

113

114 TAILQ_FOREACH(sc, &Screenq, entry) {

115 if (sc->rootwin == win)

116 return sc;

117 }

118 warnx("%s: failure win 0x%lx", __func__, win);

119 return NULL;

120 }

121

122 void

123 screen_updatestackingorder(struct screen_ctx *sc)

124 {

125 Window *wins, w0, w1;

126 struct client_ctx *cc;

127 unsigned int nwins, i, s;

128

129 if (XQueryTree(X_Dpy, sc->rootwin, &w0, &w1, &wins, &nwins)) {

130 for (s = 0, i = 0; i < nwins; i++) {

131 /* Skip hidden windows */

132 if ((cc = client_find(wins[i])) == NULL ||

133 cc->flags & CLIENT_HIDDEN)

134 continue;

135

136 cc->stackingorder = s++;

137 }

138 XFree(wins);

139 }

140 }

141

142 struct region_ctx *

143 region_find(struct screen_ctx *sc, int x, int y)

144 {

145 struct region_ctx *rc;

146

147 TAILQ_FOREACH(rc, &sc->regionq, entry) {

148 if ((x >= rc->view.x) && (x < (rc->view.x + rc->view.w)) &&

149 (y >= rc->view.y) && (y < (rc->view.y + rc->view.h))) {

150 break;

151 }

152 }

153 return rc;

154 }

155

156 struct geom

157 screen_area(struct screen_ctx *sc, int x, int y, int apply_gap)

158 {

159 struct region_ctx *rc;

160 struct geom area = sc->view;

161

162 TAILQ_FOREACH(rc, &sc->regionq, entry) {

163 if ((x >= rc->view.x) && (x < (rc->view.x + rc->view.w)) &&

164 (y >= rc->view.y) && (y < (rc->view.y + rc->view.h))) {

165 area = rc->view;

166 break;

167 }

168 }

169 if (apply_gap)

170 area = screen_apply_gap(sc, area);

171 return area;

172 }

173

174 void

175 screen_update_geometry(struct screen_ctx *sc)

176 {

177 struct region_ctx *rc;

178

179 sc->view.x = 0;

180 sc->view.y = 0;

181 sc->view.w = DisplayWidth(X_Dpy, sc->which);

182 sc->view.h = DisplayHeight(X_Dpy, sc->which);

183 sc->work = screen_apply_gap(sc, sc->view);

184

185 while ((rc = TAILQ_FIRST(&sc->regionq)) != NULL) {

186 TAILQ_REMOVE(&sc->regionq, rc, entry);

187 free(rc);

188 }

189

190 if (Conf.xrandr) {

191 XRRScreenResources *sr;

192 XRRCrtcInfo *ci;

193 int i;

194

195 sr = XRRGetScreenResources(X_Dpy, sc->rootwin);

196 for (i = 0, ci = NULL; i < sr->ncrtc; i++) {

197 ci = XRRGetCrtcInfo(X_Dpy, sr, sr->crtcs[i]);

198 if (ci == NULL)

199 continue;

200 if (ci->noutput == 0) {

201 XRRFreeCrtcInfo(ci);

202 continue;

203 }

204

205 rc = xmalloc(sizeof(*rc));

206 rc->num = i;

207 rc->view.x = ci->x;

208 rc->view.y = ci->y;

209 rc->view.w = ci->width;

210 rc->view.h = ci->height;

211 rc->work = screen_apply_gap(sc, rc->view);

212 TAILQ_INSERT_TAIL(&sc->regionq, rc, entry);

213

214 XRRFreeCrtcInfo(ci);

215 }

216 XRRFreeScreenResources(sr);

217 } else {

218 rc = xmalloc(sizeof(*rc));

219 rc->num = 0;

220 rc->view.x = 0;

221 rc->view.y = 0;

222 rc->view.w = DisplayWidth(X_Dpy, sc->which);

223 rc->view.h = DisplayHeight(X_Dpy, sc->which);

224 rc->work = screen_apply_gap(sc, rc->view);

225 TAILQ_INSERT_TAIL(&sc->regionq, rc, entry);

226 }

227

228 xu_ewmh_net_desktop_geometry(sc);

229 xu_ewmh_net_desktop_viewport(sc);

230 xu_ewmh_net_workarea(sc);

231 }

232

233 static struct geom

234 screen_apply_gap(struct screen_ctx *sc, struct geom geom)

235 {

236 geom.x += sc->gap.left;

237 geom.y += sc->gap.top;

238 geom.w -= (sc->gap.left + sc->gap.right);

239 geom.h -= (sc->gap.top + sc->gap.bottom);

240

241 return geom;

242 }

243

244 /* Bring back clients which are beyond the screen. */

245 void

246 screen_assert_clients_within(struct screen_ctx *sc)

247 {

248 struct client_ctx *cc;

249 int top, left, right, bottom;

250

251 TAILQ_FOREACH(cc, &sc->clientq, entry) {

252 if (cc->sc != sc)

253 continue;

254 top = cc->geom.y;

255 left = cc->geom.x;

256 right = cc->geom.x + cc->geom.w + (cc->bwidth * 2) - 1;

257 bottom = cc->geom.y + cc->geom.h + (cc->bwidth * 2) - 1;

258 if ((top > sc->view.h || left > sc->view.w) ||

259 (bottom < 0 || right < 0)) {

260 cc->geom.x = sc->gap.left;

261 cc->geom.y = sc->gap.top;

262 client_move(cc);

263 }

264 }

265 }

266

267 void

268 screen_prop_win_create(struct screen_ctx *sc, Window win)

269 {

270 sc->prop.win = XCreateSimpleWindow(X_Dpy, win, 0, 0, 1, 1, 0,

271 sc->xftcolor[CWM_COLOR_MENU_BG].pixel,

272 sc->xftcolor[CWM_COLOR_MENU_BG].pixel);

273 sc->prop.xftdraw = XftDrawCreate(X_Dpy, sc->prop.win,

274 sc->visual, sc->colormap);

275

276 XMapWindow(X_Dpy, sc->prop.win);

277 }

278

279 void

280 screen_prop_win_destroy(struct screen_ctx *sc)

281 {

282 XftDrawDestroy(sc->prop.xftdraw);

283 XDestroyWindow(X_Dpy, sc->prop.win);

284 }

285

286 void

287 screen_prop_win_draw(struct screen_ctx *sc, const char *fmt, ...)

288 {

289 va_list ap;

290 char *text;

291 XGlyphInfo extents;

292

293 va_start(ap, fmt);

294 xvasprintf(&text, fmt, ap);

295 va_end(ap);

296

297 XftTextExtentsUtf8(X_Dpy, sc->xftfont, (const FcChar8*)text,

298 strlen(text), &extents);

299 XResizeWindow(X_Dpy, sc->prop.win, extents.xOff, sc->xftfont->height);

300 XClearWindow(X_Dpy, sc->prop.win);

301 XftDrawStringUtf8(sc->prop.xftdraw, &sc->xftcolor[CWM_COLOR_MENU_FONT],

302 sc->xftfont, 0, sc->xftfont->ascent + 1,

303 (const FcChar8*)text, strlen(text));

304

305 free(text);

306 }

307