My dmenu build
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
13 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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 DEFFONT "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. XRectangle r = { dc->x + x, dc->y + y, w, h };
  16. if(!fill) {
  17. r.width -= 1;
  18. r.height -= 1;
  19. }
  20. XSetForeground(dc->dpy, dc->gc, color);
  21. (fill ? XFillRectangles : XDrawRectangles)(dc->dpy, dc->canvas, dc->gc, &r, 1);
  22. }
  23. void
  24. drawtext(DC *dc, const char *text, unsigned long col[ColLast]) {
  25. char buf[256];
  26. size_t n, mn;
  27. /* shorten text if necessary */
  28. n = strlen(text);
  29. for(mn = MIN(n, sizeof buf); textnw(dc, text, mn) > dc->w - dc->font.height/2; mn--)
  30. if(mn == 0)
  31. return;
  32. memcpy(buf, text, mn);
  33. if(mn < n)
  34. for(n = MAX(mn-3, 0); n < mn; buf[n++] = '.');
  35. drawrect(dc, 0, 0, dc->w, dc->h, True, BG(dc, col));
  36. drawtextn(dc, buf, mn, col);
  37. }
  38. void
  39. drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]) {
  40. int x, y;
  41. x = dc->x + dc->font.height/2;
  42. y = dc->y + dc->font.ascent+1;
  43. XSetForeground(dc->dpy, dc->gc, FG(dc, col));
  44. if(dc->font.set)
  45. XmbDrawString(dc->dpy, dc->canvas, dc->font.set, dc->gc, x, y, text, n);
  46. else {
  47. XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid);
  48. XDrawString(dc->dpy, dc->canvas, dc->gc, x, y, text, n);
  49. }
  50. }
  51. void
  52. eprintf(const char *fmt, ...) {
  53. va_list ap;
  54. fprintf(stderr, "%s: ", progname);
  55. va_start(ap, fmt);
  56. vfprintf(stderr, fmt, ap);
  57. va_end(ap);
  58. if(fmt[strlen(fmt)-1] == ':') {
  59. fputc(' ', stderr);
  60. perror(NULL);
  61. }
  62. exit(EXIT_FAILURE);
  63. }
  64. void
  65. freedc(DC *dc) {
  66. if(dc->font.set)
  67. XFreeFontSet(dc->dpy, dc->font.set);
  68. if(dc->font.xfont)
  69. XFreeFont(dc->dpy, dc->font.xfont);
  70. if(dc->canvas)
  71. XFreePixmap(dc->dpy, dc->canvas);
  72. XFreeGC(dc->dpy, dc->gc);
  73. XCloseDisplay(dc->dpy);
  74. free(dc);
  75. }
  76. unsigned long
  77. getcolor(DC *dc, const char *colstr) {
  78. Colormap cmap = DefaultColormap(dc->dpy, DefaultScreen(dc->dpy));
  79. XColor color;
  80. if(!XAllocNamedColor(dc->dpy, cmap, colstr, &color, &color))
  81. eprintf("cannot allocate color '%s'\n", colstr);
  82. return color.pixel;
  83. }
  84. DC *
  85. initdc(void) {
  86. DC *dc;
  87. if(!setlocale(LC_CTYPE, "") || !XSupportsLocale())
  88. weprintf("no locale support\n");
  89. if(!(dc = calloc(1, sizeof *dc)))
  90. eprintf("cannot malloc %u bytes:", sizeof *dc);
  91. if(!(dc->dpy = XOpenDisplay(NULL)))
  92. eprintf("cannot open display\n");
  93. dc->gc = XCreateGC(dc->dpy, DefaultRootWindow(dc->dpy), 0, NULL);
  94. XSetLineAttributes(dc->dpy, dc->gc, 1, LineSolid, CapButt, JoinMiter);
  95. return dc;
  96. }
  97. void
  98. initfont(DC *dc, const char *fontstr) {
  99. if(!loadfont(dc, fontstr ? fontstr : DEFFONT)) {
  100. if(fontstr != NULL)
  101. weprintf("cannot load font '%s'\n", fontstr);
  102. if(fontstr == NULL || !loadfont(dc, DEFFONT))
  103. eprintf("cannot load font '%s'\n", DEFFONT);
  104. }
  105. dc->font.height = dc->font.ascent + dc->font.descent;
  106. }
  107. Bool
  108. loadfont(DC *dc, const char *fontstr) {
  109. char *def, **missing;
  110. int i, n;
  111. if(!*fontstr)
  112. return False;
  113. if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) {
  114. char **names;
  115. XFontStruct **xfonts;
  116. n = XFontsOfFontSet(dc->font.set, &xfonts, &names);
  117. for(i = dc->font.ascent = dc->font.descent = 0; i < n; i++) {
  118. dc->font.ascent = MAX(dc->font.ascent, xfonts[i]->ascent);
  119. dc->font.descent = MAX(dc->font.descent, xfonts[i]->descent);
  120. }
  121. }
  122. else if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) {
  123. dc->font.ascent = dc->font.xfont->ascent;
  124. dc->font.descent = dc->font.xfont->descent;
  125. }
  126. if(missing)
  127. XFreeStringList(missing);
  128. return (dc->font.set || dc->font.xfont);
  129. }
  130. void
  131. mapdc(DC *dc, Window win, unsigned int w, unsigned int h) {
  132. XCopyArea(dc->dpy, dc->canvas, win, dc->gc, 0, 0, w, h, 0, 0);
  133. }
  134. void
  135. resizedc(DC *dc, unsigned int w, unsigned int h) {
  136. if(dc->canvas)
  137. XFreePixmap(dc->dpy, dc->canvas);
  138. dc->canvas = XCreatePixmap(dc->dpy, DefaultRootWindow(dc->dpy), w, h,
  139. DefaultDepth(dc->dpy, DefaultScreen(dc->dpy)));
  140. dc->x = dc->y = 0;
  141. dc->w = w;
  142. dc->h = h;
  143. dc->invert = False;
  144. }
  145. int
  146. textnw(DC *dc, const char *text, size_t len) {
  147. if(dc->font.set) {
  148. XRectangle r;
  149. XmbTextExtents(dc->font.set, text, len, NULL, &r);
  150. return r.width;
  151. }
  152. return XTextWidth(dc->font.xfont, text, len);
  153. }
  154. int
  155. textw(DC *dc, const char *text) {
  156. return textnw(dc, text, strlen(text)) + dc->font.height;
  157. }
  158. void
  159. weprintf(const char *fmt, ...) {
  160. va_list ap;
  161. fprintf(stderr, "%s: ", progname);
  162. va_start(ap, fmt);
  163. vfprintf(stderr, fmt, ap);
  164. va_end(ap);
  165. }