My dmenu build
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

14 роки тому
13 роки тому
13 роки тому
14 роки тому
13 роки тому
14 роки тому
13 роки тому
13 роки тому
14 роки тому
13 роки тому
14 роки тому
13 роки тому
14 роки тому
13 роки тому
13 роки тому
13 роки тому
14 роки тому
13 роки тому
13 роки тому
13 роки тому
14 роки тому
13 роки тому
14 роки тому
13 роки тому
13 роки тому
14 роки тому
13 роки тому
14 роки тому
13 роки тому
14 роки тому
13 роки тому
14 роки тому
13 роки тому
14 роки тому
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /* See LICENSE file for copyright and license details. */
  2. #include <locale.h>
  3. #include <stdarg.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <X11/Xlib.h>
  8. #include "draw.h"
  9. #define MAX(a, b) ((a) > (b) ? (a) : (b))
  10. #define MIN(a, b) ((a) < (b) ? (a) : (b))
  11. #define DEFAULTFN "fixed"
  12. static Bool loadfont(DC *dc, const char *fontstr);
  13. void
  14. drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color) {
  15. XSetForeground(dc->dpy, dc->gc, color);
  16. if(fill)
  17. XFillRectangle(dc->dpy, dc->canvas, dc->gc, dc->x + x, dc->y + y, w, h);
  18. else
  19. XDrawRectangle(dc->dpy, dc->canvas, dc->gc, dc->x + x, dc->y + y, w-1, h-1);
  20. }
  21. void
  22. drawtext(DC *dc, const char *text, unsigned long col[ColLast]) {
  23. char buf[BUFSIZ];
  24. size_t mn, n = strlen(text);
  25. /* shorten text if necessary */
  26. for(mn = MIN(n, sizeof buf); textnw(dc, text, mn) + dc->font.height/2 > dc->w; mn--)
  27. if(mn == 0)
  28. return;
  29. memcpy(buf, text, mn);
  30. if(mn < n)
  31. for(n = MAX(mn-3, 0); n < mn; buf[n++] = '.');
  32. drawrect(dc, 0, 0, dc->w, dc->h, True, BG(dc, col));
  33. drawtextn(dc, buf, mn, col);
  34. }
  35. void
  36. drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]) {
  37. int x = dc->x + dc->font.height/2;
  38. int y = dc->y + dc->font.ascent+1;
  39. XSetForeground(dc->dpy, dc->gc, FG(dc, col));
  40. if(dc->font.set)
  41. XmbDrawString(dc->dpy, dc->canvas, dc->font.set, dc->gc, x, y, text, n);
  42. else {
  43. XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid);
  44. XDrawString(dc->dpy, dc->canvas, dc->gc, x, y, text, n);
  45. }
  46. }
  47. void
  48. eprintf(const char *fmt, ...) {
  49. va_list ap;
  50. va_start(ap, fmt);
  51. vfprintf(stderr, fmt, ap);
  52. va_end(ap);
  53. if(fmt[0] != '\0' && fmt[strlen(fmt)-1] == ':') {
  54. fputc(' ', stderr);
  55. perror(NULL);
  56. }
  57. exit(EXIT_FAILURE);
  58. }
  59. void
  60. freedc(DC *dc) {
  61. if(dc->font.set)
  62. XFreeFontSet(dc->dpy, dc->font.set);
  63. if(dc->font.xfont)
  64. XFreeFont(dc->dpy, dc->font.xfont);
  65. if(dc->canvas)
  66. XFreePixmap(dc->dpy, dc->canvas);
  67. XFreeGC(dc->dpy, dc->gc);
  68. XCloseDisplay(dc->dpy);
  69. free(dc);
  70. }
  71. unsigned long
  72. getcolor(DC *dc, const char *colstr) {
  73. Colormap cmap = DefaultColormap(dc->dpy, DefaultScreen(dc->dpy));
  74. XColor color;
  75. if(!XAllocNamedColor(dc->dpy, cmap, colstr, &color, &color))
  76. eprintf("cannot allocate color '%s'\n", colstr);
  77. return color.pixel;
  78. }
  79. DC *
  80. initdc(void) {
  81. DC *dc;
  82. if(!setlocale(LC_CTYPE, "") || !XSupportsLocale())
  83. fprintf(stderr, "no locale support\n");
  84. if(!(dc = calloc(1, sizeof *dc)))
  85. eprintf("cannot malloc %u bytes:", sizeof *dc);
  86. if(!(dc->dpy = XOpenDisplay(NULL)))
  87. eprintf("cannot open display\n");
  88. dc->gc = XCreateGC(dc->dpy, DefaultRootWindow(dc->dpy), 0, NULL);
  89. XSetLineAttributes(dc->dpy, dc->gc, 1, LineSolid, CapButt, JoinMiter);
  90. return dc;
  91. }
  92. void
  93. initfont(DC *dc, const char *fontstr) {
  94. if(!loadfont(dc, fontstr ? fontstr : DEFAULTFN)) {
  95. if(fontstr != NULL)
  96. fprintf(stderr, "cannot load font '%s'\n", fontstr);
  97. if(fontstr == NULL || !loadfont(dc, DEFAULTFN))
  98. eprintf("cannot load font '%s'\n", DEFAULTFN);
  99. }
  100. dc->font.height = dc->font.ascent + dc->font.descent;
  101. }
  102. Bool
  103. loadfont(DC *dc, const char *fontstr) {
  104. char *def, **missing, **names;
  105. int i, n = 1;
  106. XFontStruct **xfonts;
  107. if(!*fontstr)
  108. return False;
  109. if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def)))
  110. n = XFontsOfFontSet(dc->font.set, &xfonts, &names);
  111. else if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr)))
  112. xfonts = &dc->font.xfont;
  113. else
  114. n = 0;
  115. for(i = 0; i < n; i++) {
  116. dc->font.ascent = MAX(dc->font.ascent, xfonts[i]->ascent);
  117. dc->font.descent = MAX(dc->font.descent, xfonts[i]->descent);
  118. dc->font.width = MAX(dc->font.width, xfonts[i]->max_bounds.width);
  119. }
  120. if(missing)
  121. XFreeStringList(missing);
  122. return (dc->font.set || dc->font.xfont);
  123. }
  124. void
  125. mapdc(DC *dc, Window win, unsigned int w, unsigned int h) {
  126. XCopyArea(dc->dpy, dc->canvas, win, dc->gc, 0, 0, w, h, 0, 0);
  127. }
  128. void
  129. resizedc(DC *dc, unsigned int w, unsigned int h) {
  130. if(dc->canvas)
  131. XFreePixmap(dc->dpy, dc->canvas);
  132. dc->canvas = XCreatePixmap(dc->dpy, DefaultRootWindow(dc->dpy), w, h,
  133. DefaultDepth(dc->dpy, DefaultScreen(dc->dpy)));
  134. dc->w = w;
  135. dc->h = h;
  136. }
  137. int
  138. textnw(DC *dc, const char *text, size_t len) {
  139. if(dc->font.set) {
  140. XRectangle r;
  141. XmbTextExtents(dc->font.set, text, len, NULL, &r);
  142. return r.width;
  143. }
  144. return XTextWidth(dc->font.xfont, text, len);
  145. }
  146. int
  147. textw(DC *dc, const char *text) {
  148. return textnw(dc, text, strlen(text)) + dc->font.height;
  149. }