logo

oasis

Own branch of Oasis Linux (upstream: <https://git.sr.ht/~mcf/oasis/>) git clone https://anongit.hacktivis.me/git/oasis.git

0001-Port-to-wayland-using-wld-and-swc-panels.patch (36663B)


  1. From d186aa8891ca777615b8138416c95565c05e0a09 Mon Sep 17 00:00:00 2001
  2. From: Michael Forney <mforney@mforney.org>
  3. Date: Thu, 27 Oct 2016 21:04:23 -0700
  4. Subject: [PATCH] Port to wayland using wld and swc panels
  5. ---
  6. Makefile | 16 +-
  7. config.mk | 20 +-
  8. dmenu.c | 566 ++++++++++++++++++++++++++++--------------------------
  9. drw.c | 130 ++++++-------
  10. drw.h | 26 ++-
  11. 5 files changed, 381 insertions(+), 377 deletions(-)
  12. diff --git a/Makefile b/Makefile
  13. index a03a95c..4046899 100644
  14. --- a/Makefile
  15. +++ b/Makefile
  16. @@ -3,7 +3,7 @@
  17. include config.mk
  18. -SRC = drw.c dmenu.c stest.c util.c
  19. +SRC = drw.c dmenu.c stest.c panel-protocol.c util.c
  20. OBJ = $(SRC:.c=.o)
  21. all: options dmenu stest
  22. @@ -20,10 +20,18 @@ options:
  23. config.h:
  24. cp config.def.h $@
  25. -$(OBJ): arg.h config.h config.mk drw.h
  26. +swc-protocol.c: $(SWCPROTO)
  27. + @echo GEN $@
  28. + @wayland-scanner code < $< > $@
  29. -dmenu: dmenu.o drw.o util.o
  30. - $(CC) -o $@ dmenu.o drw.o util.o $(LDFLAGS)
  31. +swc-client-protocol.h: $(SWCPROTO)
  32. + @echo GEN $@
  33. + @wayland-scanner client-header < $< > $@
  34. +
  35. +$(OBJ): arg.h config.h config.mk drw.h swc-client-protocol.h
  36. +
  37. +dmenu: dmenu.o drw.o swc-protocol.o util.o
  38. + $(CC) -o $@ dmenu.o drw.o swc-protocol.o util.o $(LDFLAGS)
  39. stest: stest.o
  40. $(CC) -o $@ stest.o $(LDFLAGS)
  41. diff --git a/config.mk b/config.mk
  42. index 0929b4a..7e747ff 100644
  43. --- a/config.mk
  44. +++ b/config.mk
  45. @@ -5,25 +5,15 @@ VERSION = 4.9
  46. PREFIX = /usr/local
  47. MANPREFIX = $(PREFIX)/share/man
  48. -X11INC = /usr/X11R6/include
  49. -X11LIB = /usr/X11R6/lib
  50. -
  51. -# Xinerama, comment if you don't want it
  52. -XINERAMALIBS = -lXinerama
  53. -XINERAMAFLAGS = -DXINERAMA
  54. -
  55. -# freetype
  56. -FREETYPELIBS = -lfontconfig -lXft
  57. -FREETYPEINC = /usr/include/freetype2
  58. -# OpenBSD (uncomment)
  59. -#FREETYPEINC = $(X11INC)/freetype2
  60. +PIXMANINC = /usr/include/pixman-1
  61. +SWCPROTO = /usr/share/swc/swc.xml
  62. # includes and libs
  63. -INCS = -I$(X11INC) -I$(FREETYPEINC)
  64. -LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS)
  65. +INCS = -I$(PIXMANINC)
  66. +LIBS = -lwayland-client -lxkbcommon -lwld
  67. # flags
  68. -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS)
  69. +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\"
  70. CFLAGS = -std=c99 -pedantic -Wall -Os $(INCS) $(CPPFLAGS)
  71. LDFLAGS = $(LIBS)
  72. diff --git a/dmenu.c b/dmenu.c
  73. index 6b8f51b..877c459 100644
  74. --- a/dmenu.c
  75. +++ b/dmenu.c
  76. @@ -5,19 +5,18 @@
  77. #include <stdlib.h>
  78. #include <string.h>
  79. #include <strings.h>
  80. +#include <sys/mman.h>
  81. #include <time.h>
  82. #include <unistd.h>
  83. -#include <X11/Xlib.h>
  84. -#include <X11/Xatom.h>
  85. -#include <X11/Xutil.h>
  86. -#ifdef XINERAMA
  87. -#include <X11/extensions/Xinerama.h>
  88. -#endif
  89. -#include <X11/Xft/Xft.h>
  90. +#include <wayland-client.h>
  91. +#include <wld/wayland.h>
  92. +#include <wld/wld.h>
  93. +#include <xkbcommon/xkbcommon.h>
  94. #include "drw.h"
  95. #include "util.h"
  96. +#include "swc-client-protocol.h"
  97. /* macros */
  98. #define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \
  99. @@ -34,8 +33,16 @@ struct item {
  100. int out;
  101. };
  102. +struct xkb {
  103. + struct xkb_context *context;
  104. + struct xkb_state *state;
  105. + struct xkb_keymap *keymap;
  106. + xkb_mod_index_t ctrl, alt, shift;
  107. +};
  108. +
  109. +static void paste(void);
  110. +
  111. static char text[BUFSIZ] = "";
  112. -static char *embed;
  113. static int bh, mw, mh;
  114. static int inputw = 0, promptw;
  115. static int lrpad; /* sum of left and right padding */
  116. @@ -43,12 +50,21 @@ static size_t cursor;
  117. static struct item *items = NULL;
  118. static struct item *matches, *matchend;
  119. static struct item *prev, *curr, *next, *sel;
  120. -static int mon = -1, screen;
  121. -
  122. -static Atom clip, utf8;
  123. -static Display *dpy;
  124. -static Window root, parentwin, win;
  125. -static XIC xic;
  126. +static int mon = -1;
  127. +
  128. +static struct wl_display *dpy;
  129. +static struct wl_compositor *compositor;
  130. +static struct wl_keyboard *kbd;
  131. +static struct wl_seat *seat;
  132. +static struct wl_shell *shell;
  133. +static struct wl_surface *surface;
  134. +static struct wl_data_device_manager *datadevman;
  135. +static struct wl_data_device *datadev;
  136. +static struct wl_data_offer *seloffer;
  137. +static struct swc_screen *screen;
  138. +static struct swc_panel_manager *panelman;
  139. +static struct swc_panel *panel;
  140. +static struct xkb xkb;
  141. static Drw *drw;
  142. static Clr *scheme[SchemeLast];
  143. @@ -94,12 +110,10 @@ cleanup(void)
  144. {
  145. size_t i;
  146. - XUngrabKey(dpy, AnyKey, AnyModifier, root);
  147. for (i = 0; i < SchemeLast; i++)
  148. free(scheme[i]);
  149. drw_free(drw);
  150. - XSync(dpy, False);
  151. - XCloseDisplay(dpy);
  152. + wl_display_disconnect(dpy);
  153. }
  154. static char *
  155. @@ -133,6 +147,7 @@ drawmenu(void)
  156. struct item *item;
  157. int x = 0, y = 0, w;
  158. + wld_set_target_surface(drw->renderer, drw->surface);
  159. drw_setscheme(drw, scheme[SchemeNorm]);
  160. drw_rect(drw, 0, 0, mw, mh, 1, 1);
  161. @@ -172,42 +187,7 @@ drawmenu(void)
  162. drw_text(drw, mw - w, 0, w, bh, lrpad / 2, ">", 0);
  163. }
  164. }
  165. - drw_map(drw, win, 0, 0, mw, mh);
  166. -}
  167. -
  168. -static void
  169. -grabfocus(void)
  170. -{
  171. - struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 };
  172. - Window focuswin;
  173. - int i, revertwin;
  174. -
  175. - for (i = 0; i < 100; ++i) {
  176. - XGetInputFocus(dpy, &focuswin, &revertwin);
  177. - if (focuswin == win)
  178. - return;
  179. - XSetInputFocus(dpy, win, RevertToParent, CurrentTime);
  180. - nanosleep(&ts, NULL);
  181. - }
  182. - die("cannot grab focus");
  183. -}
  184. -
  185. -static void
  186. -grabkeyboard(void)
  187. -{
  188. - struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 };
  189. - int i;
  190. -
  191. - if (embed)
  192. - return;
  193. - /* try to grab keyboard, we may have to wait for another process to ungrab */
  194. - for (i = 0; i < 1000; i++) {
  195. - if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync,
  196. - GrabModeAsync, CurrentTime) == GrabSuccess)
  197. - return;
  198. - nanosleep(&ts, NULL);
  199. - }
  200. - die("cannot grab keyboard");
  201. + drw_map(drw, surface, 0, 0, mw, mh);
  202. }
  203. static void
  204. @@ -305,111 +285,105 @@ movewordedge(int dir)
  205. }
  206. static void
  207. -keypress(XKeyEvent *ev)
  208. +kbdkey(void *d, struct wl_keyboard *kbd, uint32_t serial, uint32_t time,
  209. + uint32_t key, uint32_t state)
  210. {
  211. char buf[32];
  212. int len;
  213. - KeySym ksym;
  214. - Status status;
  215. + xkb_keysym_t ksym = XKB_KEY_NoSymbol;
  216. + int ctrl = xkb_state_mod_index_is_active(xkb.state, xkb.ctrl, XKB_STATE_MODS_EFFECTIVE);
  217. + int shift = xkb_state_mod_index_is_active(xkb.state, xkb.shift, XKB_STATE_MODS_EFFECTIVE);
  218. + int alt = xkb_state_mod_index_is_active(xkb.state, xkb.alt, XKB_STATE_MODS_EFFECTIVE);
  219. - len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status);
  220. - switch (status) {
  221. - default: /* XLookupNone, XBufferOverflow */
  222. - return;
  223. - case XLookupChars:
  224. - goto insert;
  225. - case XLookupKeySym:
  226. - case XLookupBoth:
  227. - break;
  228. - }
  229. + if (state == WL_KEYBOARD_KEY_STATE_RELEASED)
  230. + goto update_state;
  231. - if (ev->state & ControlMask) {
  232. + ksym = xkb_state_key_get_one_sym(xkb.state, key + 8);
  233. + if (ctrl) {
  234. switch(ksym) {
  235. - case XK_a: ksym = XK_Home; break;
  236. - case XK_b: ksym = XK_Left; break;
  237. - case XK_c: ksym = XK_Escape; break;
  238. - case XK_d: ksym = XK_Delete; break;
  239. - case XK_e: ksym = XK_End; break;
  240. - case XK_f: ksym = XK_Right; break;
  241. - case XK_g: ksym = XK_Escape; break;
  242. - case XK_h: ksym = XK_BackSpace; break;
  243. - case XK_i: ksym = XK_Tab; break;
  244. - case XK_j: /* fallthrough */
  245. - case XK_J: /* fallthrough */
  246. - case XK_m: /* fallthrough */
  247. - case XK_M: ksym = XK_Return; ev->state &= ~ControlMask; break;
  248. - case XK_n: ksym = XK_Down; break;
  249. - case XK_p: ksym = XK_Up; break;
  250. -
  251. - case XK_k: /* delete right */
  252. + case XKB_KEY_a: ksym = XKB_KEY_Home; break;
  253. + case XKB_KEY_b: ksym = XKB_KEY_Left; break;
  254. + case XKB_KEY_c: ksym = XKB_KEY_Escape; break;
  255. + case XKB_KEY_d: ksym = XKB_KEY_Delete; break;
  256. + case XKB_KEY_e: ksym = XKB_KEY_End; break;
  257. + case XKB_KEY_f: ksym = XKB_KEY_Right; break;
  258. + case XKB_KEY_g: ksym = XKB_KEY_Escape; break;
  259. + case XKB_KEY_h: ksym = XKB_KEY_BackSpace; break;
  260. + case XKB_KEY_i: ksym = XKB_KEY_Tab; break;
  261. + case XKB_KEY_j: /* fallthrough */
  262. + case XKB_KEY_J: /* fallthrough */
  263. + case XKB_KEY_m: /* fallthrough */
  264. + case XKB_KEY_M: ksym = XKB_KEY_Return; ctrl = 0; break;
  265. + case XKB_KEY_n: ksym = XKB_KEY_Down; break;
  266. + case XKB_KEY_p: ksym = XKB_KEY_Up; break;
  267. +
  268. + case XKB_KEY_k: /* delete right */
  269. text[cursor] = '\0';
  270. match();
  271. break;
  272. - case XK_u: /* delete left */
  273. + case XKB_KEY_u: /* delete left */
  274. insert(NULL, 0 - cursor);
  275. break;
  276. - case XK_w: /* delete word */
  277. + case XKB_KEY_w: /* delete word */
  278. while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)]))
  279. insert(NULL, nextrune(-1) - cursor);
  280. while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)]))
  281. insert(NULL, nextrune(-1) - cursor);
  282. break;
  283. - case XK_y: /* paste selection */
  284. - case XK_Y:
  285. - XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
  286. - utf8, utf8, win, CurrentTime);
  287. + case XKB_KEY_y: /* paste selection */
  288. + case XKB_KEY_Y:
  289. + paste();
  290. return;
  291. - case XK_Left:
  292. + case XKB_KEY_Left:
  293. movewordedge(-1);
  294. goto draw;
  295. - case XK_Right:
  296. + case XKB_KEY_Right:
  297. movewordedge(+1);
  298. goto draw;
  299. - case XK_Return:
  300. - case XK_KP_Enter:
  301. + case XKB_KEY_Return:
  302. + case XKB_KEY_KP_Enter:
  303. break;
  304. - case XK_bracketleft:
  305. + case XKB_KEY_bracketleft:
  306. cleanup();
  307. exit(1);
  308. default:
  309. return;
  310. }
  311. - } else if (ev->state & Mod1Mask) {
  312. + } else if (alt) {
  313. switch(ksym) {
  314. - case XK_b:
  315. + case XKB_KEY_b:
  316. movewordedge(-1);
  317. goto draw;
  318. - case XK_f:
  319. + case XKB_KEY_f:
  320. movewordedge(+1);
  321. goto draw;
  322. - case XK_g: ksym = XK_Home; break;
  323. - case XK_G: ksym = XK_End; break;
  324. - case XK_h: ksym = XK_Up; break;
  325. - case XK_j: ksym = XK_Next; break;
  326. - case XK_k: ksym = XK_Prior; break;
  327. - case XK_l: ksym = XK_Down; break;
  328. + case XKB_KEY_g: ksym = XKB_KEY_Home; break;
  329. + case XKB_KEY_G: ksym = XKB_KEY_End; break;
  330. + case XKB_KEY_h: ksym = XKB_KEY_Up; break;
  331. + case XKB_KEY_j: ksym = XKB_KEY_Next; break;
  332. + case XKB_KEY_k: ksym = XKB_KEY_Prior; break;
  333. + case XKB_KEY_l: ksym = XKB_KEY_Down; break;
  334. default:
  335. return;
  336. }
  337. }
  338. -
  339. - switch(ksym) {
  340. + switch (ksym) {
  341. default:
  342. -insert:
  343. + len = xkb_state_key_get_utf8(xkb.state, key + 8, buf, sizeof(buf));
  344. if (!iscntrl(*buf))
  345. insert(buf, len);
  346. break;
  347. - case XK_Delete:
  348. + case XKB_KEY_Delete:
  349. if (text[cursor] == '\0')
  350. return;
  351. cursor = nextrune(+1);
  352. /* fallthrough */
  353. - case XK_BackSpace:
  354. + case XKB_KEY_BackSpace:
  355. if (cursor == 0)
  356. return;
  357. insert(NULL, nextrune(-1) - cursor);
  358. break;
  359. - case XK_End:
  360. + case XKB_KEY_End:
  361. if (text[cursor] != '\0') {
  362. cursor = strlen(text);
  363. break;
  364. @@ -425,10 +399,10 @@ insert:
  365. }
  366. sel = matchend;
  367. break;
  368. - case XK_Escape:
  369. + case XKB_KEY_Escape:
  370. cleanup();
  371. exit(1);
  372. - case XK_Home:
  373. + case XKB_KEY_Home:
  374. if (sel == matches) {
  375. cursor = 0;
  376. break;
  377. @@ -436,7 +410,7 @@ insert:
  378. sel = curr = matches;
  379. calcoffsets();
  380. break;
  381. - case XK_Left:
  382. + case XKB_KEY_Left:
  383. if (cursor > 0 && (!sel || !sel->left || lines > 0)) {
  384. cursor = nextrune(-1);
  385. break;
  386. @@ -444,35 +418,35 @@ insert:
  387. if (lines > 0)
  388. return;
  389. /* fallthrough */
  390. - case XK_Up:
  391. + case XKB_KEY_Up:
  392. if (sel && sel->left && (sel = sel->left)->right == curr) {
  393. curr = prev;
  394. calcoffsets();
  395. }
  396. break;
  397. - case XK_Next:
  398. + case XKB_KEY_Next:
  399. if (!next)
  400. return;
  401. sel = curr = next;
  402. calcoffsets();
  403. break;
  404. - case XK_Prior:
  405. + case XKB_KEY_Prior:
  406. if (!prev)
  407. return;
  408. sel = curr = prev;
  409. calcoffsets();
  410. break;
  411. - case XK_Return:
  412. - case XK_KP_Enter:
  413. - puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
  414. - if (!(ev->state & ControlMask)) {
  415. + case XKB_KEY_Return:
  416. + case XKB_KEY_KP_Enter:
  417. + puts((sel && !shift) ? sel->text : text);
  418. + if (!ctrl) {
  419. cleanup();
  420. exit(0);
  421. }
  422. - if (sel)
  423. + if(sel)
  424. sel->out = 1;
  425. break;
  426. - case XK_Right:
  427. + case XKB_KEY_Right:
  428. if (text[cursor] != '\0') {
  429. cursor = nextrune(+1);
  430. break;
  431. @@ -480,13 +454,13 @@ insert:
  432. if (lines > 0)
  433. return;
  434. /* fallthrough */
  435. - case XK_Down:
  436. + case XKB_KEY_Down:
  437. if (sel && sel->right && (sel = sel->right) == next) {
  438. curr = next;
  439. calcoffsets();
  440. }
  441. break;
  442. - case XK_Tab:
  443. + case XKB_KEY_Tab:
  444. if (!sel)
  445. return;
  446. strncpy(text, sel->text, sizeof text - 1);
  447. @@ -498,24 +472,28 @@ insert:
  448. draw:
  449. drawmenu();
  450. +
  451. +update_state:
  452. + xkb_state_update_key(xkb.state, key + 8,
  453. + state == WL_KEYBOARD_KEY_STATE_PRESSED ? XKB_KEY_DOWN : XKB_KEY_UP);
  454. }
  455. static void
  456. paste(void)
  457. {
  458. - char *p, *q;
  459. - int di;
  460. - unsigned long dl;
  461. - Atom da;
  462. -
  463. - /* we have been given the current selection, now insert it into input */
  464. - if (XGetWindowProperty(dpy, win, utf8, 0, (sizeof text / 4) + 1, False,
  465. - utf8, &da, &di, &dl, &dl, (unsigned char **)&p)
  466. - == Success && p) {
  467. - insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p));
  468. - XFree(p);
  469. + int fds[2], len;
  470. + char buf[BUFSIZ], *nl;
  471. +
  472. + if (seloffer) {
  473. + pipe(fds);
  474. + wl_data_offer_receive(seloffer, "text/plain", fds[1]);
  475. + wl_display_flush(dpy);
  476. + close(fds[1]);
  477. + while((len = read(fds[0], buf, sizeof buf)) > 0)
  478. + insert(buf, (nl = strchr(buf, '\n')) ? nl - buf : len);
  479. + close(fds[0]);
  480. + drawmenu();
  481. }
  482. - drawmenu();
  483. }
  484. static void
  485. @@ -550,148 +528,207 @@ readstdin(void)
  486. static void
  487. run(void)
  488. {
  489. - XEvent ev;
  490. + while (wl_display_dispatch(dpy) != -1)
  491. + ;
  492. +}
  493. - while (!XNextEvent(dpy, &ev)) {
  494. - if (XFilterEvent(&ev, None))
  495. - continue;
  496. - switch(ev.type) {
  497. - case Expose:
  498. - if (ev.xexpose.count == 0)
  499. - drw_map(drw, win, 0, 0, mw, mh);
  500. - break;
  501. - case FocusIn:
  502. - /* regrab focus from parent window */
  503. - if (ev.xfocus.window != win)
  504. - grabfocus();
  505. - break;
  506. - case KeyPress:
  507. - keypress(&ev.xkey);
  508. - break;
  509. - case SelectionNotify:
  510. - if (ev.xselection.property == utf8)
  511. - paste();
  512. - break;
  513. - case VisibilityNotify:
  514. - if (ev.xvisibility.state != VisibilityUnobscured)
  515. - XRaiseWindow(dpy, win);
  516. - break;
  517. - }
  518. +/* wayland event handlers */
  519. +static void
  520. +regglobal(void *d, struct wl_registry *r, uint32_t name, const char *interface, uint32_t version)
  521. +{
  522. + if(strcmp(interface, "wl_compositor") == 0)
  523. + compositor = wl_registry_bind(r, name, &wl_compositor_interface, 1);
  524. + else if(strcmp(interface, "wl_shell") == 0)
  525. + shell = wl_registry_bind(r, name, &wl_shell_interface, 1);
  526. + else if(strcmp(interface, "wl_seat") == 0)
  527. + seat = wl_registry_bind(r, name, &wl_seat_interface, 1);
  528. + else if(strcmp(interface, "wl_data_device_manager") == 0)
  529. + datadevman = wl_registry_bind(r, name, &wl_data_device_manager_interface, 1);
  530. + else if(strcmp(interface, "swc_panel_manager") == 0)
  531. + panelman = wl_registry_bind(r, name, &swc_panel_manager_interface, 1);
  532. + else if (strcmp(interface, "swc_screen") == 0) {
  533. + if (mon != -1 && mon-- == 0)
  534. + screen = wl_registry_bind(r, name, &swc_screen_interface, 1);
  535. }
  536. }
  537. +static void
  538. +regglobalremove(void *d, struct wl_registry *reg, uint32_t name)
  539. +{
  540. +}
  541. +
  542. +static const struct wl_registry_listener reglistener = { regglobal, regglobalremove };
  543. +
  544. +static void
  545. +kbdenter(void *data, struct wl_keyboard *kbd, uint32_t serial,
  546. + struct wl_surface *surface, struct wl_array *keys)
  547. +{
  548. +}
  549. +
  550. +static void
  551. +kbdleave(void *d, struct wl_keyboard *kbd, uint32_t serial,
  552. + struct wl_surface *surface)
  553. +{
  554. + /* XXX: swc doesn't handle refocusing panels, so just exit for now */
  555. + cleanup();
  556. + exit(1);
  557. +}
  558. +
  559. +/* kbdkey is defined above to reduce merge conflicts */
  560. +
  561. +static void
  562. +kbdkeymap(void *d, struct wl_keyboard *kbd, uint32_t format, int32_t fd, uint32_t size)
  563. +{
  564. + char *string;
  565. +
  566. + if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
  567. + close(fd);
  568. + return;
  569. + }
  570. +
  571. + string = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
  572. +
  573. + if (string == MAP_FAILED) {
  574. + close(fd);
  575. + return;
  576. + }
  577. +
  578. + xkb.keymap = xkb_keymap_new_from_string(xkb.context, string,
  579. + XKB_KEYMAP_FORMAT_TEXT_V1, 0);
  580. + munmap(string, size);
  581. + close(fd);
  582. + xkb.state = xkb_state_new(xkb.keymap);
  583. +
  584. + xkb.ctrl = xkb_keymap_mod_get_index(xkb.keymap, XKB_MOD_NAME_CTRL);
  585. + xkb.alt = xkb_keymap_mod_get_index(xkb.keymap, XKB_MOD_NAME_ALT);
  586. + xkb.shift = xkb_keymap_mod_get_index(xkb.keymap, XKB_MOD_NAME_SHIFT);
  587. +}
  588. +
  589. +static void
  590. +kbdmodifiers(void *d, struct wl_keyboard *kbd, uint32_t serial, uint32_t dep,
  591. + uint32_t lat, uint32_t lck, uint32_t grp)
  592. +{
  593. + xkb_state_update_mask(xkb.state, dep, lat, lck, grp, 0, 0);
  594. +}
  595. +
  596. +static const struct wl_keyboard_listener kbdlistener = {
  597. + kbdkeymap, kbdenter, kbdleave, kbdkey, kbdmodifiers,
  598. +};
  599. +
  600. +static void
  601. +dataofferoffer(void *d, struct wl_data_offer *offer, const char *mimetype)
  602. +{
  603. + if (strncmp(mimetype, "text/plain", 10) == 0)
  604. + wl_data_offer_set_user_data(offer, (void *)(uintptr_t) 1);
  605. +}
  606. +
  607. +static const struct wl_data_offer_listener dataofferlistener = { dataofferoffer };
  608. +
  609. +static void
  610. +datadevoffer(void *d, struct wl_data_device *datadev, struct wl_data_offer *offer)
  611. +{
  612. + wl_data_offer_add_listener(offer, &dataofferlistener, NULL);
  613. +}
  614. +
  615. +static void
  616. +datadeventer(void *d, struct wl_data_device *datadev, uint32_t serial,
  617. + struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y,
  618. + struct wl_data_offer *offer)
  619. +{
  620. +}
  621. +
  622. +static void
  623. +datadevleave(void *d, struct wl_data_device *datadev)
  624. +{
  625. +}
  626. +
  627. +static void
  628. +datadevmotion(void *d, struct wl_data_device *datadev, uint32_t time,
  629. + wl_fixed_t x, wl_fixed_t y)
  630. +{
  631. +}
  632. +
  633. +static void
  634. +datadevdrop(void *d, struct wl_data_device *datadev)
  635. +{
  636. +}
  637. +
  638. +static void
  639. +datadevselection(void *d, struct wl_data_device *datadev, struct wl_data_offer *offer)
  640. +{
  641. + if (offer && (uintptr_t) wl_data_offer_get_user_data(offer) == 1)
  642. + seloffer = offer;
  643. +}
  644. +
  645. +static const struct wl_data_device_listener datadevlistener = {
  646. + datadevoffer, datadeventer, datadevleave, datadevmotion, datadevdrop,
  647. + datadevselection,
  648. +};
  649. +
  650. +static void
  651. +paneldocked(void *d, struct swc_panel *panel, uint32_t length)
  652. +{
  653. + mw = length;
  654. +}
  655. +
  656. +static const struct swc_panel_listener panellistener = { paneldocked };
  657. +
  658. static void
  659. setup(void)
  660. {
  661. - int x, y, i, j;
  662. - unsigned int du;
  663. - XSetWindowAttributes swa;
  664. - XIM xim;
  665. - Window w, dw, *dws;
  666. - XWindowAttributes wa;
  667. - XClassHint ch = {"dmenu", "dmenu"};
  668. -#ifdef XINERAMA
  669. - XineramaScreenInfo *info;
  670. - Window pw;
  671. - int a, di, n, area = 0;
  672. -#endif
  673. + int j;
  674. +
  675. + if (!compositor || !seat || !panelman)
  676. + exit(1);
  677. +
  678. + kbd = wl_seat_get_keyboard(seat);
  679. + wl_keyboard_add_listener(kbd, &kbdlistener, NULL);
  680. + datadev = wl_data_device_manager_get_data_device(datadevman, seat);
  681. + wl_data_device_add_listener(datadev, &datadevlistener, NULL);
  682. +
  683. + xkb.context = xkb_context_new(0);
  684. +
  685. /* init appearance */
  686. for (j = 0; j < SchemeLast; j++)
  687. scheme[j] = drw_scm_create(drw, colors[j], 2);
  688. - clip = XInternAtom(dpy, "CLIPBOARD", False);
  689. - utf8 = XInternAtom(dpy, "UTF8_STRING", False);
  690. -
  691. /* calculate menu geometry */
  692. - bh = drw->fonts->h + 2;
  693. + bh = drw->fonts->wld->height + 2;
  694. lines = MAX(lines, 0);
  695. mh = (lines + 1) * bh;
  696. -#ifdef XINERAMA
  697. - i = 0;
  698. - if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) {
  699. - XGetInputFocus(dpy, &w, &di);
  700. - if (mon >= 0 && mon < n)
  701. - i = mon;
  702. - else if (w != root && w != PointerRoot && w != None) {
  703. - /* find top-level window containing current input focus */
  704. - do {
  705. - if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws)
  706. - XFree(dws);
  707. - } while (w != root && w != pw);
  708. - /* find xinerama screen with which the window intersects most */
  709. - if (XGetWindowAttributes(dpy, pw, &wa))
  710. - for (j = 0; j < n; j++)
  711. - if ((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) {
  712. - area = a;
  713. - i = j;
  714. - }
  715. - }
  716. - /* no focused window is on screen, so use pointer location instead */
  717. - if (mon < 0 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du))
  718. - for (i = 0; i < n; i++)
  719. - if (INTERSECT(x, y, 1, 1, info[i]))
  720. - break;
  721. -
  722. - x = info[i].x_org;
  723. - y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
  724. - mw = info[i].width;
  725. - XFree(info);
  726. - } else
  727. -#endif
  728. - {
  729. - if (!XGetWindowAttributes(dpy, parentwin, &wa))
  730. - die("could not get embedding window attributes: 0x%lx",
  731. - parentwin);
  732. - x = 0;
  733. - y = topbar ? 0 : wa.height - mh;
  734. - mw = wa.width;
  735. - }
  736. +
  737. + /* create menu surface */
  738. + surface = wl_compositor_create_surface(compositor);
  739. +
  740. + panel = swc_panel_manager_create_panel(panelman, surface);
  741. + swc_panel_add_listener(panel, &panellistener, NULL);
  742. + swc_panel_dock(panel, topbar ? SWC_PANEL_EDGE_TOP : SWC_PANEL_EDGE_BOTTOM, screen, 1);
  743. +
  744. + wl_display_roundtrip(dpy);
  745. + if (!mw)
  746. + exit(1);
  747. +
  748. promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
  749. inputw = MIN(inputw, mw/3);
  750. match();
  751. - /* create menu window */
  752. - swa.override_redirect = True;
  753. - swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
  754. - swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
  755. - win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
  756. - CopyFromParent, CopyFromParent, CopyFromParent,
  757. - CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
  758. - XSetClassHint(dpy, win, &ch);
  759. -
  760. - /* open input methods */
  761. - xim = XOpenIM(dpy, NULL, NULL, NULL);
  762. - xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
  763. - XNClientWindow, win, XNFocusWindow, win, NULL);
  764. -
  765. - XMapRaised(dpy, win);
  766. - XSetInputFocus(dpy, win, RevertToParent, CurrentTime);
  767. - if (embed) {
  768. - XSelectInput(dpy, parentwin, FocusChangeMask);
  769. - if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) {
  770. - for (i = 0; i < du && dws[i] != win; ++i)
  771. - XSelectInput(dpy, dws[i], FocusChangeMask);
  772. - XFree(dws);
  773. - }
  774. - grabfocus();
  775. - }
  776. - drw_resize(drw, mw, mh);
  777. + drw_resize(drw, surface, mw, mh);
  778. drawmenu();
  779. }
  780. static void
  781. usage(void)
  782. {
  783. - fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
  784. - " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr);
  785. + fputs("usage: dmenu [-biv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
  786. + " [-nb color] [-nf color] [-sb color] [-sf color]\n", stderr);
  787. exit(1);
  788. }
  789. int
  790. main(int argc, char *argv[])
  791. {
  792. - XWindowAttributes wa;
  793. - int i, fast = 0;
  794. + struct wl_registry *reg;
  795. + int i;
  796. for (i = 1; i < argc; i++)
  797. /* these options take no arguments */
  798. @@ -700,8 +737,6 @@ main(int argc, char *argv[])
  799. exit(0);
  800. } else if (!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */
  801. topbar = 0;
  802. - else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */
  803. - fast = 1;
  804. else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
  805. fstrncmp = strncasecmp;
  806. fstrstr = cistrstr;
  807. @@ -724,41 +759,28 @@ main(int argc, char *argv[])
  808. colors[SchemeSel][ColBg] = argv[++i];
  809. else if (!strcmp(argv[i], "-sf")) /* selected foreground color */
  810. colors[SchemeSel][ColFg] = argv[++i];
  811. - else if (!strcmp(argv[i], "-w")) /* embedding window id */
  812. - embed = argv[++i];
  813. else
  814. usage();
  815. - if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
  816. + if (!setlocale(LC_CTYPE, ""))
  817. fputs("warning: no locale support\n", stderr);
  818. - if (!XSetLocaleModifiers(""))
  819. - fputs("warning: no locale modifiers support\n", stderr);
  820. - if (!(dpy = XOpenDisplay(NULL)))
  821. + if (!(dpy = wl_display_connect(NULL)))
  822. die("cannot open display");
  823. - screen = DefaultScreen(dpy);
  824. - root = RootWindow(dpy, screen);
  825. - if (!embed || !(parentwin = strtol(embed, NULL, 0)))
  826. - parentwin = root;
  827. - if (!XGetWindowAttributes(dpy, parentwin, &wa))
  828. - die("could not get embedding window attributes: 0x%lx",
  829. - parentwin);
  830. - drw = drw_create(dpy, screen, root, wa.width, wa.height);
  831. + if (!(reg = wl_display_get_registry(dpy)))
  832. + die("cannot get registry");
  833. + wl_registry_add_listener(reg, &reglistener, NULL);
  834. + wl_display_roundtrip(dpy);
  835. + drw = drw_create(dpy);
  836. if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
  837. die("no fonts could be loaded.");
  838. - lrpad = drw->fonts->h;
  839. + lrpad = drw->fonts->wld->height;
  840. #ifdef __OpenBSD__
  841. if (pledge("stdio rpath", NULL) == -1)
  842. die("pledge");
  843. #endif
  844. - if (fast && !isatty(0)) {
  845. - grabkeyboard();
  846. - readstdin();
  847. - } else {
  848. - readstdin();
  849. - grabkeyboard();
  850. - }
  851. + readstdin();
  852. setup();
  853. run();
  854. diff --git a/drw.c b/drw.c
  855. index 8fd1ca4..e4995a6 100644
  856. --- a/drw.c
  857. +++ b/drw.c
  858. @@ -2,8 +2,9 @@
  859. #include <stdio.h>
  860. #include <stdlib.h>
  861. #include <string.h>
  862. -#include <X11/Xlib.h>
  863. -#include <X11/Xft/Xft.h>
  864. +#include <wayland-client.h>
  865. +#include <wld/wld.h>
  866. +#include <wld/wayland.h>
  867. #include "drw.h"
  868. #include "util.h"
  869. @@ -61,40 +62,33 @@ utf8decode(const char *c, long *u, size_t clen)
  870. }
  871. Drw *
  872. -drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
  873. +drw_create(struct wl_display *dpy)
  874. {
  875. Drw *drw = ecalloc(1, sizeof(Drw));
  876. drw->dpy = dpy;
  877. - drw->screen = screen;
  878. - drw->root = root;
  879. - drw->w = w;
  880. - drw->h = h;
  881. - drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
  882. - drw->gc = XCreateGC(dpy, root, 0, NULL);
  883. - XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
  884. + drw->ctx = wld_wayland_create_context(dpy, WLD_ANY);
  885. + drw->renderer = wld_create_renderer(drw->ctx);
  886. + drw->fontctx = wld_font_create_context();
  887. return drw;
  888. }
  889. void
  890. -drw_resize(Drw *drw, unsigned int w, unsigned int h)
  891. +drw_resize(Drw *drw, struct wl_surface *surface, unsigned int w, unsigned int h)
  892. {
  893. - if (!drw)
  894. - return;
  895. -
  896. - drw->w = w;
  897. - drw->h = h;
  898. - if (drw->drawable)
  899. - XFreePixmap(drw->dpy, drw->drawable);
  900. - drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
  901. + if (drw->surface)
  902. + wld_destroy_surface(drw->surface);
  903. + drw->surface = wld_wayland_create_surface(drw->ctx, w, h, WLD_FORMAT_XRGB8888, 0, surface);
  904. }
  905. void
  906. drw_free(Drw *drw)
  907. {
  908. - XFreePixmap(drw->dpy, drw->drawable);
  909. - XFreeGC(drw->dpy, drw->gc);
  910. + wld_destroy_surface(drw->surface);
  911. + wld_destroy_renderer(drw->renderer);
  912. + wld_destroy_context(drw->ctx);
  913. + wld_font_destroy_context(drw->fontctx);
  914. free(drw);
  915. }
  916. @@ -102,11 +96,10 @@ drw_free(Drw *drw)
  917. * drw_fontset_create instead.
  918. */
  919. static Fnt *
  920. -xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
  921. +wldfont_create(Drw *drw, const char *fontname, FcPattern *pattern)
  922. {
  923. Fnt *font;
  924. - XftFont *xfont = NULL;
  925. - FcPattern *pattern = NULL;
  926. + struct wld_font *wld = NULL;
  927. if (fontname) {
  928. /* Using the pattern found at font->xfont->pattern does not yield the
  929. @@ -114,17 +107,17 @@ xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
  930. * FcNameParse; using the latter results in the desired fallback
  931. * behaviour whereas the former just results in missing-character
  932. * rectangles being drawn, at least with some fonts. */
  933. - if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
  934. + if (!(wld = wld_font_open_name(drw->fontctx, fontname))) {
  935. fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
  936. return NULL;
  937. }
  938. if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
  939. fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
  940. - XftFontClose(drw->dpy, xfont);
  941. + wld_font_close(wld);
  942. return NULL;
  943. }
  944. - } else if (fontpattern) {
  945. - if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {
  946. + } else if (pattern) {
  947. + if (!(wld = wld_font_open_pattern(drw->fontctx, pattern))) {
  948. fprintf(stderr, "error, cannot load font from pattern.\n");
  949. return NULL;
  950. }
  951. @@ -140,28 +133,26 @@ xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
  952. * and lots more all over the internet.
  953. */
  954. FcBool iscol;
  955. - if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) {
  956. - XftFontClose(drw->dpy, xfont);
  957. + if(FcPatternGetBool(pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) {
  958. + wld_font_close(wld);
  959. return NULL;
  960. }
  961. font = ecalloc(1, sizeof(Fnt));
  962. - font->xfont = xfont;
  963. + font->wld = wld;
  964. font->pattern = pattern;
  965. - font->h = xfont->ascent + xfont->descent;
  966. - font->dpy = drw->dpy;
  967. return font;
  968. }
  969. static void
  970. -xfont_free(Fnt *font)
  971. +wldfont_free(Fnt *font)
  972. {
  973. if (!font)
  974. return;
  975. if (font->pattern)
  976. FcPatternDestroy(font->pattern);
  977. - XftFontClose(font->dpy, font->xfont);
  978. + wld_font_close(font->wld);
  979. free(font);
  980. }
  981. @@ -175,7 +166,7 @@ drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
  982. return NULL;
  983. for (i = 1; i <= fontcount; i++) {
  984. - if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) {
  985. + if ((cur = wldfont_create(drw, fonts[fontcount - i], NULL))) {
  986. cur->next = ret;
  987. ret = cur;
  988. }
  989. @@ -188,7 +179,7 @@ drw_fontset_free(Fnt *font)
  990. {
  991. if (font) {
  992. drw_fontset_free(font->next);
  993. - xfont_free(font);
  994. + wldfont_free(font);
  995. }
  996. }
  997. @@ -197,10 +188,7 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
  998. {
  999. if (!drw || !dest || !clrname)
  1000. return;
  1001. -
  1002. - if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
  1003. - DefaultColormap(drw->dpy, drw->screen),
  1004. - clrname, dest))
  1005. + if (!(wld_lookup_named_color(clrname, dest)))
  1006. die("error, cannot allocate color '%s'", clrname);
  1007. }
  1008. @@ -213,7 +201,7 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
  1009. Clr *ret;
  1010. /* need at least two colors for a scheme */
  1011. - if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
  1012. + if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(*ret))))
  1013. return NULL;
  1014. for (i = 0; i < clrcount; i++)
  1015. @@ -240,11 +228,15 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int
  1016. {
  1017. if (!drw || !drw->scheme)
  1018. return;
  1019. - XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
  1020. + Clr color = invert ? drw->scheme[ColBg] : drw->scheme[ColFg];
  1021. if (filled)
  1022. - XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
  1023. - else
  1024. - XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
  1025. + wld_fill_rectangle(drw->renderer, color, x, y, w, h);
  1026. + else {
  1027. + wld_fill_rectangle(drw->renderer, color, x, y, w, 1);
  1028. + wld_fill_rectangle(drw->renderer, color, x + w - 1, y + 1, 1, h - 2);
  1029. + wld_fill_rectangle(drw->renderer, color, x, y + 1, 1, h - 2);
  1030. + wld_fill_rectangle(drw->renderer, color, x, y + h - 1, w, 1);
  1031. + }
  1032. }
  1033. int
  1034. @@ -253,7 +245,6 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
  1035. char buf[1024];
  1036. int ty;
  1037. unsigned int ew;
  1038. - XftDraw *d = NULL;
  1039. Fnt *usedfont, *curfont, *nextfont;
  1040. size_t i, len;
  1041. int utf8strlen, utf8charlen, render = x || y || w || h;
  1042. @@ -262,7 +253,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
  1043. FcCharSet *fccharset;
  1044. FcPattern *fcpattern;
  1045. FcPattern *match;
  1046. - XftResult result;
  1047. + FcResult result;
  1048. int charexists = 0;
  1049. if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
  1050. @@ -271,11 +262,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
  1051. if (!render) {
  1052. w = ~w;
  1053. } else {
  1054. - XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
  1055. - XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
  1056. - d = XftDrawCreate(drw->dpy, drw->drawable,
  1057. - DefaultVisual(drw->dpy, drw->screen),
  1058. - DefaultColormap(drw->dpy, drw->screen));
  1059. + wld_fill_rectangle(drw->renderer, drw->scheme[invert ? ColFg : ColBg], x, y, w, h);
  1060. x += lpad;
  1061. w -= lpad;
  1062. }
  1063. @@ -288,7 +275,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
  1064. while (*text) {
  1065. utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
  1066. for (curfont = drw->fonts; curfont; curfont = curfont->next) {
  1067. - charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
  1068. + charexists = charexists || wld_font_ensure_char(curfont->wld, utf8codepoint);
  1069. if (charexists) {
  1070. if (curfont == usedfont) {
  1071. utf8strlen += utf8charlen;
  1072. @@ -320,9 +307,9 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
  1073. ; /* NOP */
  1074. if (render) {
  1075. - ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
  1076. - XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
  1077. - usedfont->xfont, x, ty, (XftChar8 *)buf, len);
  1078. + ty = y + (h - usedfont->wld->height) / 2 + usedfont->wld->ascent;
  1079. + wld_draw_text(drw->renderer, usedfont->wld, drw->scheme[invert ? ColBg : ColFg],
  1080. + x, ty, buf, len, NULL);
  1081. }
  1082. x += ew;
  1083. w -= ew;
  1084. @@ -343,7 +330,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
  1085. FcCharSetAddChar(fccharset, utf8codepoint);
  1086. if (!drw->fonts->pattern) {
  1087. - /* Refer to the comment in xfont_create for more information. */
  1088. + /* Refer to the comment in wldfont_create for more information. */
  1089. die("the first font in the cache must be loaded from a font string.");
  1090. }
  1091. @@ -354,38 +341,37 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
  1092. FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
  1093. FcDefaultSubstitute(fcpattern);
  1094. - match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result);
  1095. + match = FcFontMatch(NULL, fcpattern, &result);
  1096. FcCharSetDestroy(fccharset);
  1097. FcPatternDestroy(fcpattern);
  1098. if (match) {
  1099. - usedfont = xfont_create(drw, NULL, match);
  1100. - if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
  1101. + usedfont = wldfont_create(drw, NULL, match);
  1102. + if (usedfont && wld_font_ensure_char(usedfont->wld, utf8codepoint)) {
  1103. for (curfont = drw->fonts; curfont->next; curfont = curfont->next)
  1104. ; /* NOP */
  1105. curfont->next = usedfont;
  1106. } else {
  1107. - xfont_free(usedfont);
  1108. + wldfont_free(usedfont);
  1109. usedfont = drw->fonts;
  1110. }
  1111. }
  1112. }
  1113. }
  1114. - if (d)
  1115. - XftDrawDestroy(d);
  1116. return x + (render ? w : 0);
  1117. }
  1118. void
  1119. -drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
  1120. +drw_map(Drw *drw, struct wl_surface *surface, int x, int y, unsigned int w, unsigned int h)
  1121. {
  1122. if (!drw)
  1123. return;
  1124. - XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
  1125. - XSync(drw->dpy, False);
  1126. + wl_surface_damage(surface, x, y, w, h);
  1127. + wld_flush(drw->renderer);
  1128. + wld_swap(drw->surface);
  1129. }
  1130. unsigned int
  1131. @@ -399,18 +385,19 @@ drw_fontset_getwidth(Drw *drw, const char *text)
  1132. void
  1133. drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
  1134. {
  1135. - XGlyphInfo ext;
  1136. + struct wld_extents ext;
  1137. if (!font || !text)
  1138. return;
  1139. - XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext);
  1140. + wld_font_text_extents_n(font->wld, text, len, &ext);
  1141. if (w)
  1142. - *w = ext.xOff;
  1143. + *w = ext.advance;
  1144. if (h)
  1145. - *h = font->h;
  1146. + *h = font->wld->height;
  1147. }
  1148. +#if 0
  1149. Cur *
  1150. drw_cur_create(Drw *drw, int shape)
  1151. {
  1152. @@ -433,3 +420,4 @@ drw_cur_free(Drw *drw, Cur *cursor)
  1153. XFreeCursor(drw->dpy, cursor->cursor);
  1154. free(cursor);
  1155. }
  1156. +#endif
  1157. diff --git a/drw.h b/drw.h
  1158. index 4c67419..1f1967e 100644
  1159. --- a/drw.h
  1160. +++ b/drw.h
  1161. @@ -1,34 +1,30 @@
  1162. /* See LICENSE file for copyright and license details. */
  1163. -typedef struct {
  1164. - Cursor cursor;
  1165. -} Cur;
  1166. +typedef void Cur;
  1167. typedef struct Fnt {
  1168. - Display *dpy;
  1169. - unsigned int h;
  1170. - XftFont *xfont;
  1171. + struct wld_font *wld;
  1172. FcPattern *pattern;
  1173. struct Fnt *next;
  1174. } Fnt;
  1175. enum { ColFg, ColBg }; /* Clr scheme index */
  1176. -typedef XftColor Clr;
  1177. +typedef uint32_t Clr;
  1178. typedef struct {
  1179. unsigned int w, h;
  1180. - Display *dpy;
  1181. - int screen;
  1182. - Window root;
  1183. - Drawable drawable;
  1184. - GC gc;
  1185. + struct wl_display *dpy;
  1186. + struct wld_context *ctx;
  1187. + struct wld_renderer *renderer;
  1188. + struct wld_surface *surface;
  1189. + struct wld_font_context *fontctx;
  1190. Clr *scheme;
  1191. Fnt *fonts;
  1192. } Drw;
  1193. /* Drawable abstraction */
  1194. -Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
  1195. -void drw_resize(Drw *drw, unsigned int w, unsigned int h);
  1196. +Drw *drw_create(struct wl_display *dpy);
  1197. +void drw_resize(Drw *drw, struct wl_surface *surface, unsigned int w, unsigned int h);
  1198. void drw_free(Drw *drw);
  1199. /* Fnt abstraction */
  1200. @@ -54,4 +50,4 @@ void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled
  1201. int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert);
  1202. /* Map functions */
  1203. -void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
  1204. +void drw_map(Drw *drw, struct wl_surface *surface, int x, int y, unsigned int w, unsigned int h);
  1205. --
  1206. 2.30.1