-
-
Save Anskrevy/c33a4ea0455a592d04b8a917eaf6737c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <locale.h> | |
#include <stdio.h> | |
#include <X11/Xlib.h> | |
#include <X11/Xft/Xft.h> | |
#define LENGTH(arr) (sizeof((arr)) / sizeof((arr)[0])) | |
typedef struct Fnt { | |
Display *dpy; | |
unsigned int h; | |
XftFont *xfont; | |
FcPattern *pattern; | |
struct Fnt *next; | |
} Fnt; | |
typedef XftColor Clr; | |
typedef struct { | |
unsigned int w, h; | |
Display *dpy; | |
int screen; | |
Window root; | |
Drawable drawable; | |
GC gc; | |
Clr *scheme; | |
Fnt *fonts; | |
} Drw; | |
static Display *dpy; | |
static Window root, parentwin; | |
static Drw *drw; | |
static int screen; | |
static const char *fonts[] = { | |
"monospace:size=14", | |
}; | |
void | |
die(const char *fmt, ...) | |
{ | |
va_list ap; | |
va_start(ap, fmt); | |
vfprintf(stderr, fmt, ap); | |
va_end(ap); | |
if (fmt[0] && fmt[strlen(fmt)-1] == ':') { | |
fputc(' ', stderr); | |
perror(NULL); | |
} else { | |
fputc('\n', stderr); | |
} | |
exit(EXIT_FAILURE); | |
} | |
static Fnt * | |
xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) | |
{ | |
Fnt *font; | |
XftFont *xfont = NULL; | |
FcPattern *pattern = NULL; | |
if (fontname) { | |
if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) { | |
fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname); | |
return NULL; | |
} | |
if (!(pattern = FcNameParse((FcChar8 *) fontname))) { | |
fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname); | |
XftFontClose(drw->dpy, xfont); | |
return NULL; | |
} | |
} else if (fontpattern) { | |
if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { | |
fprintf(stderr, "error, cannot load font from pattern.\n"); | |
return NULL; | |
} | |
} else { | |
die("no font specified."); | |
} | |
font = calloc(1, sizeof(Fnt)); | |
font->xfont = xfont; | |
font->pattern = pattern; | |
font->h = xfont->ascent + xfont->descent; | |
font->dpy = drw->dpy; | |
return font; | |
} | |
Fnt* | |
drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount) | |
{ | |
Fnt *cur, *ret = NULL; | |
size_t i; | |
if (!drw || !fonts) | |
return NULL; | |
for (i = 1; i <= fontcount; i++) { | |
if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) { | |
cur->next = ret; | |
ret = cur; | |
} | |
} | |
return (drw->fonts = ret); | |
} | |
Drw * | |
drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) | |
{ | |
Drw *drw = calloc(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, screen)); | |
drw->gc = XCreateGC(dpy, root, 0, NULL); | |
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); | |
return drw; | |
} | |
static void | |
xfont_free(Fnt *font) | |
{ | |
if (!font) | |
return; | |
if (font->pattern) | |
FcPatternDestroy(font->pattern); | |
XftFontClose(font->dpy, font->xfont); | |
free(font); | |
} | |
void | |
drw_fontset_free(Fnt *font) | |
{ | |
if (font) { | |
drw_fontset_free(font->next); | |
xfont_free(font); | |
} | |
} | |
void | |
drw_free(Drw *drw) | |
{ | |
XFreePixmap(drw->dpy, drw->drawable); | |
XFreeGC(drw->dpy, drw->gc); | |
drw_fontset_free(drw->fonts); | |
free(drw); | |
} | |
void | |
x_cleanup(void) | |
{ | |
drw_free(drw); | |
XSync(dpy, False); | |
XCloseDisplay(dpy); | |
return; | |
} | |
int | |
main(void) | |
{ | |
XWindowAttributes wa; | |
if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) | |
exit(EXIT_FAILURE); | |
if (!(dpy = XOpenDisplay(NULL))) | |
exit(EXIT_FAILURE); | |
screen = DefaultScreen(dpy); | |
root = RootWindow(dpy, screen); | |
parentwin = root; | |
if (!XGetWindowAttributes(dpy, parentwin, &wa)) | |
exit(EXIT_FAILURE); | |
drw = drw_create(dpy, screen, root, wa.width, wa.height); | |
if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) | |
exit(EXIT_FAILURE); | |
x_cleanup(); | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment