You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

234 lines
4.8 KiB

19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
  1. /*
  2. * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
  3. * See LICENSE file for license details.
  4. */
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <X11/Xlocale.h>
  8. #include "dwm.h"
  9. void
  10. drawall()
  11. {
  12. Client *c;
  13. for(c = clients; c; c = getnext(c->next))
  14. drawtitle(c);
  15. drawstatus();
  16. }
  17. void
  18. drawstatus()
  19. {
  20. int i;
  21. Bool istile = arrange == dotile;
  22. dc.x = dc.y = 0;
  23. dc.w = bw;
  24. drawtext(NULL, !istile, False);
  25. dc.w = 0;
  26. for(i = 0; i < TLast; i++) {
  27. dc.x += dc.w;
  28. dc.w = textw(tags[i]);
  29. if(istile)
  30. drawtext(tags[i], (i == tsel), True);
  31. else
  32. drawtext(tags[i], (i != tsel), True);
  33. }
  34. if(sel) {
  35. dc.x += dc.w;
  36. dc.w = textw(sel->name);
  37. drawtext(sel->name, istile, True);
  38. }
  39. dc.w = textw(stext);
  40. dc.x = bx + bw - dc.w;
  41. drawtext(stext, !istile, False);
  42. XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, bw, bh, 0, 0);
  43. XFlush(dpy);
  44. }
  45. void
  46. drawtitle(Client *c)
  47. {
  48. int i;
  49. Bool istile = arrange == dotile;
  50. if(c == sel) {
  51. drawstatus();
  52. XUnmapWindow(dpy, c->title);
  53. XSetWindowBorder(dpy, c->win, dc.fg);
  54. return;
  55. }
  56. XSetWindowBorder(dpy, c->win, dc.bg);
  57. XMapWindow(dpy, c->title);
  58. dc.x = dc.y = 0;
  59. dc.w = 0;
  60. for(i = 0; i < TLast; i++) {
  61. if(c->tags[i]) {
  62. dc.x += dc.w;
  63. dc.w = textw(c->tags[i]);
  64. drawtext(c->tags[i], !istile, True);
  65. }
  66. }
  67. dc.x += dc.w;
  68. dc.w = textw(c->name);
  69. drawtext(c->name, !istile, True);
  70. XCopyArea(dpy, dc.drawable, c->title, dc.gc,
  71. 0, 0, c->tw, c->th, 0, 0);
  72. XFlush(dpy);
  73. }
  74. static void
  75. drawborder(void)
  76. {
  77. XPoint points[5];
  78. XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
  79. XSetForeground(dpy, dc.gc, dc.border);
  80. points[0].x = dc.x;
  81. points[0].y = dc.y;
  82. points[1].x = dc.w - 1;
  83. points[1].y = 0;
  84. points[2].x = 0;
  85. points[2].y = dc.h - 1;
  86. points[3].x = -(dc.w - 1);
  87. points[3].y = 0;
  88. points[4].x = 0;
  89. points[4].y = -(dc.h - 1);
  90. XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious);
  91. }
  92. void
  93. drawtext(const char *text, Bool invert, Bool border)
  94. {
  95. int x, y, w, h;
  96. unsigned int len;
  97. static char buf[256];
  98. XGCValues gcv;
  99. XRectangle r = { dc.x, dc.y, dc.w, dc.h };
  100. XSetForeground(dpy, dc.gc, invert ? dc.fg : dc.bg);
  101. XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
  102. w = 0;
  103. if(border)
  104. drawborder();
  105. if(!text)
  106. return;
  107. len = strlen(text);
  108. if(len >= sizeof(buf))
  109. len = sizeof(buf) - 1;
  110. memcpy(buf, text, len);
  111. buf[len] = 0;
  112. h = dc.font.ascent + dc.font.descent;
  113. y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
  114. x = dc.x + (h / 2);
  115. /* shorten text if necessary */
  116. while(len && (w = textnw(buf, len)) > dc.w - h)
  117. buf[--len] = 0;
  118. if(w > dc.w)
  119. return; /* too long */
  120. gcv.foreground = invert ? dc.bg : dc.fg;
  121. gcv.background = invert ? dc.fg : dc.bg;
  122. if(dc.font.set) {
  123. XChangeGC(dpy, dc.gc, GCForeground | GCBackground, &gcv);
  124. XmbDrawImageString(dpy, dc.drawable, dc.font.set, dc.gc,
  125. x, y, buf, len);
  126. }
  127. else {
  128. gcv.font = dc.font.xfont->fid;
  129. XChangeGC(dpy, dc.gc, GCForeground | GCBackground | GCFont, &gcv);
  130. XDrawImageString(dpy, dc.drawable, dc.gc, x, y, buf, len);
  131. }
  132. }
  133. unsigned long
  134. getcolor(const char *colstr)
  135. {
  136. XColor color;
  137. Colormap cmap = DefaultColormap(dpy, screen);
  138. XAllocNamedColor(dpy, cmap, colstr, &color, &color);
  139. return color.pixel;
  140. }
  141. unsigned int
  142. textnw(char *text, unsigned int len)
  143. {
  144. XRectangle r;
  145. if(dc.font.set) {
  146. XmbTextExtents(dc.font.set, text, len, NULL, &r);
  147. return r.width;
  148. }
  149. return XTextWidth(dc.font.xfont, text, len);
  150. }
  151. unsigned int
  152. textw(char *text)
  153. {
  154. return textnw(text, strlen(text)) + dc.font.height;
  155. }
  156. void
  157. setfont(const char *fontstr)
  158. {
  159. char **missing, *def;
  160. int i, n;
  161. missing = NULL;
  162. setlocale(LC_ALL, "");
  163. if(dc.font.set)
  164. XFreeFontSet(dpy, dc.font.set);
  165. dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def);
  166. if(missing) {
  167. while(n--)
  168. fprintf(stderr, "missing fontset: %s\n", missing[n]);
  169. XFreeStringList(missing);
  170. if(dc.font.set) {
  171. XFreeFontSet(dpy, dc.font.set);
  172. dc.font.set = NULL;
  173. }
  174. }
  175. if(dc.font.set) {
  176. XFontSetExtents *font_extents;
  177. XFontStruct **xfonts;
  178. char **font_names;
  179. dc.font.ascent = dc.font.descent = 0;
  180. font_extents = XExtentsOfFontSet(dc.font.set);
  181. n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names);
  182. for(i = 0, dc.font.ascent = 0, dc.font.descent = 0; i < n; i++) {
  183. if(dc.font.ascent < (*xfonts)->ascent)
  184. dc.font.ascent = (*xfonts)->ascent;
  185. if(dc.font.descent < (*xfonts)->descent)
  186. dc.font.descent = (*xfonts)->descent;
  187. xfonts++;
  188. }
  189. }
  190. else {
  191. if(dc.font.xfont)
  192. XFreeFont(dpy, dc.font.xfont);
  193. dc.font.xfont = NULL;
  194. dc.font.xfont = XLoadQueryFont(dpy, fontstr);
  195. if (!dc.font.xfont)
  196. dc.font.xfont = XLoadQueryFont(dpy, "fixed");
  197. if (!dc.font.xfont)
  198. eprint("error, cannot init 'fixed' font\n");
  199. dc.font.ascent = dc.font.xfont->ascent;
  200. dc.font.descent = dc.font.xfont->descent;
  201. }
  202. dc.font.height = dc.font.ascent + dc.font.descent;
  203. }