add initial X11 version - libsl - draw back-ends for dwm, dmenu, etc | |
git clone git://git.codemadness.org/libsl | |
Log | |
Files | |
Refs | |
LICENSE | |
--- | |
commit b450cbeceb639c6372733d14d1a3af95550109d2 | |
parent 09ba5ebb3fb9c4b4766d7efb7a477a624734f135 | |
Author: Hiltjo Posthuma <[email protected]> | |
Date: Thu, 26 Sep 2019 23:03:21 +0200 | |
add initial X11 version | |
based on a combination of the current drw logic and the "old" X11 version code. | |
Diffstat: | |
A x11/drw.c | 254 +++++++++++++++++++++++++++++… | |
A x11/drw.h | 58 ++++++++++++++++++++++++++++++ | |
2 files changed, 312 insertions(+), 0 deletions(-) | |
--- | |
diff --git a/x11/drw.c b/x11/drw.c | |
@@ -0,0 +1,254 @@ | |
+/* See LICENSE file for copyright and license details. */ | |
+#include <stdio.h> | |
+#include <stdlib.h> | |
+#include <string.h> | |
+#include <X11/Xlib.h> | |
+ | |
+#include "drw.h" | |
+#include "util.h" | |
+ | |
+Drw * | |
+drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int… | |
+{ | |
+ Drw *drw; | |
+ | |
+ drw = ecalloc(1, sizeof(Drw)); | |
+ drw->dpy = dpy; | |
+ drw->screen = screen; | |
+ drw->root = root; | |
+ drw->w = w; | |
+ drw->h = h; | |
+ drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, scree… | |
+ drw->gc = XCreateGC(dpy, root, 0, NULL); | |
+ XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); | |
+ | |
+ return drw; | |
+} | |
+ | |
+void | |
+drw_resize(Drw *drw, unsigned int w, unsigned int h) | |
+{ | |
+ drw->w = w; | |
+ drw->h = h; | |
+ if (drw->drawable) | |
+ XFreePixmap(drw->dpy, drw->drawable); | |
+ drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(… | |
+} | |
+ | |
+void | |
+drw_free(Drw *drw) | |
+{ | |
+ XFreePixmap(drw->dpy, drw->drawable); | |
+ XFreeGC(drw->dpy, drw->gc); | |
+ free(drw); | |
+} | |
+ | |
+static Fnt * | |
+xfont_create(Display *dpy, const char *fontname) | |
+{ | |
+ Fnt *font; | |
+ XFontStruct **xfonts; | |
+ char **font_names; | |
+ char *def, **missing; | |
+ int n; | |
+ | |
+ font = ecalloc(1, sizeof(Fnt)); | |
+ font->dpy = dpy; | |
+ font->set = XCreateFontSet(dpy, fontname, &missing, &n, &def); | |
+ if (missing) { | |
+ while (n--) | |
+ fprintf(stderr, "drw: missing fontset: %s\n", missing[… | |
+ XFreeStringList(missing); | |
+ } | |
+ if (font->set) { | |
+ XExtentsOfFontSet(font->set); | |
+ n = XFontsOfFontSet(font->set, &xfonts, &font_names); | |
+ while (n--) { | |
+ font->ascent = MAX(font->ascent, (*xfonts)->ascent); | |
+ font->descent = MAX(font->descent,(*xfonts)->descent); | |
+ xfonts++; | |
+ } | |
+ } else { | |
+ if (!(font->xfont = XLoadQueryFont(dpy, fontname)) | |
+ && !(font->xfont = XLoadQueryFont(dpy, "fixed"))) | |
+ die("error, cannot load font: '%s'\n", fontname); | |
+ font->ascent = font->xfont->ascent; | |
+ font->descent = font->xfont->descent; | |
+ } | |
+ font->h = font->ascent + font->descent; | |
+ | |
+ return font; | |
+} | |
+ | |
+void | |
+xfont_free(Display *dpy, Fnt *font) | |
+{ | |
+ if (font->set) | |
+ XFreeFontSet(dpy, font->set); | |
+ else | |
+ XFreeFont(dpy, font->xfont); | |
+ free(font); | |
+} | |
+ | |
+Fnt * | |
+drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount) | |
+{ | |
+ /* just create using first font */ | |
+ /* TODO: more? */ | |
+ drw->fonts = xfont_create(drw->dpy, fonts[0]); | |
+ return drw->fonts; | |
+} | |
+ | |
+void | |
+drw_fontset_free(Fnt *font) | |
+{ | |
+ xfont_free(font->dpy, font); | |
+} | |
+ | |
+void | |
+drw_clr_create(Drw *drw, Clr *dest, const char *clrname) | |
+{ | |
+ Colormap cmap; | |
+ XColor ecolor; | |
+ | |
+ cmap = DefaultColormap(drw->dpy, drw->screen); | |
+ if (!XAllocNamedColor(drw->dpy, cmap, clrname, dest, &ecolor)) | |
+ die("error, cannot allocate color '%s'\n", clrname); | |
+} | |
+ | |
+/* Wrapper to create color schemes. The caller has to call free(3) on the | |
+ * returned color scheme when done using it. */ | |
+Clr * | |
+drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) | |
+{ | |
+ size_t i; | |
+ Clr *ret; | |
+ | |
+ ret = ecalloc(clrcount, sizeof(Clr)); | |
+ for (i = 0; i < clrcount; i++) | |
+ drw_clr_create(drw, &ret[i], clrnames[i]); | |
+ | |
+ return ret; | |
+} | |
+ | |
+void | |
+drw_setfontset(Drw *drw, Fnt *set) | |
+{ | |
+ drw->fonts = set; | |
+} | |
+ | |
+void | |
+drw_setscheme(Drw *drw, Clr *scheme) | |
+{ | |
+ drw->scheme = scheme; | |
+} | |
+ | |
+void | |
+drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, | |
+ int invert) | |
+{ | |
+ int dx; | |
+ | |
+ XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColBg : ColFg].… | |
+ dx = (drw->fonts->ascent + drw->fonts->descent + 2) / 4; | |
+ if (filled) | |
+ XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w + 1, … | |
+ else | |
+ XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); | |
+} | |
+ | |
+int | |
+drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int … | |
+ const char *text, int invert) | |
+{ | |
+ char buf[256]; | |
+ int i, tx, ty, th, len, olen; | |
+ unsigned int texw, texh; | |
+ | |
+ /* TODO: lpad */ | |
+ | |
+ XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].… | |
+ XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); | |
+ | |
+ olen = strlen(text); | |
+ drw_font_getexts(drw->fonts, text, olen, &texw, &texh); | |
+ th = drw->fonts->ascent + drw->fonts->descent; | |
+ ty = y + (h / 2) - (th / 2) + drw->fonts->ascent; | |
+ tx = x + (h / 2); | |
+ /* shorten text if necessary */ | |
+ for (len = MIN(olen, sizeof buf); len && (texw > w - texh || w < texh)… | |
+ drw_font_getexts(drw->fonts, text, len, &texw, &texh); | |
+ if (!len) | |
+ return x; | |
+ memcpy(buf, text, len); | |
+ if (len < olen) | |
+ for (i = len; i && i > len - 3; buf[--i] = '.') | |
+ ; | |
+ XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : … | |
+ if (drw->fonts->set) | |
+ XmbDrawString(drw->dpy, drw->drawable, drw->fonts->set, drw->g… | |
+ else | |
+ XDrawString(drw->dpy, drw->drawable, drw->gc, tx, ty, buf, len… | |
+ | |
+ return x + w; | |
+} | |
+ | |
+void | |
+drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) | |
+{ | |
+ XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y); | |
+ XSync(drw->dpy, False); | |
+} | |
+ | |
+static unsigned int | |
+drw_font_getexts_width(Fnt *font, const char *text, unsigned int len) | |
+{ | |
+ unsigned int w; | |
+ | |
+ drw_font_getexts(font, text, len, &w, NULL); | |
+ | |
+ return w; | |
+} | |
+ | |
+unsigned int | |
+drw_fontset_getwidth(Drw *drw, const char *text) | |
+{ | |
+ return drw_font_getexts_width(drw->fonts, text, strlen(text)); | |
+} | |
+ | |
+void | |
+drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *… | |
+{ | |
+ XRectangle r; | |
+ | |
+ if (font->set) { | |
+ XmbTextExtents(font->set, text, len, NULL, &r); | |
+ if (w) | |
+ *w = r.width; | |
+ if (h) | |
+ *h = r.height; | |
+ } else { | |
+ if (h) | |
+ *h = font->ascent + font->descent; | |
+ if (w) | |
+ *w = XTextWidth(font->xfont, text, len); | |
+ } | |
+} | |
+ | |
+Cur * | |
+drw_cur_create(Drw *drw, int shape) | |
+{ | |
+ Cur *cur; | |
+ | |
+ cur = ecalloc(1, sizeof(Cur)); | |
+ cur->cursor = XCreateFontCursor(drw->dpy, shape); | |
+ | |
+ return cur; | |
+} | |
+ | |
+void | |
+drw_cur_free(Drw *drw, Cur *cursor) | |
+{ | |
+ XFreeCursor(drw->dpy, cursor->cursor); | |
+ free(cursor); | |
+} | |
diff --git a/x11/drw.h b/x11/drw.h | |
@@ -0,0 +1,58 @@ | |
+/* See LICENSE file for copyright and license details. */ | |
+ | |
+typedef struct { | |
+ Cursor cursor; | |
+} Cur; | |
+ | |
+typedef struct { | |
+ Display *dpy; | |
+ int ascent; | |
+ int descent; | |
+ unsigned int h; | |
+ XFontSet set; | |
+ XFontStruct *xfont; | |
+} Fnt; | |
+ | |
+enum { ColFg, ColBg, ColBorder }; /* Clr scheme index */ | |
+typedef XColor Clr; | |
+ | |
+typedef struct { | |
+ unsigned int w, h; | |
+ Display *dpy; | |
+ int screen; | |
+ Window root; | |
+ Drawable drawable; | |
+ GC gc; | |
+ Clr *scheme; | |
+ Fnt *fonts; | |
+} Drw; | |
+ | |
+/* Drawable abstraction */ | |
+Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned… | |
+void drw_resize(Drw *drw, unsigned int w, unsigned int h); | |
+void drw_free(Drw *drw); | |
+ | |
+/* Fnt abstraction */ | |
+Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount); | |
+void drw_fontset_free(Fnt* set); | |
+unsigned int drw_fontset_getwidth(Drw *drw, const char *text); | |
+void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned … | |
+ | |
+/* Colorscheme abstraction */ | |
+void drw_clr_create(Drw *drw, Clr *dest, const char *clrname); | |
+Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount); | |
+ | |
+/* Cursor abstraction */ | |
+Cur *drw_cur_create(Drw *drw, int shape); | |
+void drw_cur_free(Drw *drw, Cur *cursor); | |
+ | |
+/* Drawing context manipulation */ | |
+void drw_setfontset(Drw *drw, Fnt *set); | |
+void drw_setscheme(Drw *drw, Clr *scm); | |
+ | |
+/* Drawing functions */ | |
+void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int fill… | |
+int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned … | |
+ | |
+/* Map functions */ | |
+void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int … |