aboutsummaryrefslogtreecommitdiff
path: root/src/misc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/misc.cc')
-rw-r--r--src/misc.cc481
1 files changed, 0 insertions, 481 deletions
diff --git a/src/misc.cc b/src/misc.cc
deleted file mode 100644
index 809dc24..0000000
--- a/src/misc.cc
+++ /dev/null
@@ -1,481 +0,0 @@
1// misc.hh for fluxbox
2// Copyright (c) 2001 Henrik Kinnunen (fluxgen@linuxmail.org)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22#include "misc.hh"
23#include "i18n.hh"
24
25#include <stdlib.h>
26#include <string.h>
27#include <stdio.h>
28#include <iostream>
29#include <X11/Xutil.h>
30
31using namespace std;
32
33//------- strdup ------------------------
34//TODO: comment this
35//----------------------------------------
36char *Misc::strdup(const char *s) {
37 int l = strlen(s) + 1;
38 char *n = new char[l];
39 strncpy(n, s, l);
40 return n;
41}
42
43//------------- expandFilename ----------------------
44// if ~ then expand it to home of user
45// returns expanded filename
46// (note: the function creates new memory for the string)
47//---------------------------------------------------
48char *Misc::expandFilename(const char *filename) {
49 char retval[strlen(filename)+strlen(getenv("HOME"))+2]; //2 extra byte just to be safe
50 retval[0]=0; //mark end
51 if (filename[0]=='~') {
52 strcat(retval, getenv("HOME"));
53 strcat(retval, &filename[1]);
54 } else
55 return Misc::strdup(filename); //return unmodified value
56
57 return Misc::strdup(retval); //return modified value
58}
59
60// ----------------------------------------------------------------------
61// xvertext, Copyright (c) 1992 Alan Richardson (mppa3@uk.ac.sussex.syma)
62// ----------------------------------------------------------------------
63
64//------- XRotLoadFont -------------------
65// Load the rotated version of a given font
66//----------------------------------------
67Misc::XRotFontStruct *Misc::XRotLoadFont(Display *dpy, char *fontname, float angle) {
68 char val;
69 XImage *I1, *I2;
70 Pixmap canvas;
71 Window root;
72 int screen;
73 GC font_gc;
74 char text[3];/*, errstr[300];*/
75 XFontStruct *fontstruct;
76 XRotFontStruct *rotfont;
77 int ichar, i, j, index, boxlen = 60, dir;
78 int vert_w, vert_h, vert_len, bit_w, bit_h, bit_len;
79 int min_char, max_char;
80 unsigned char *vertdata, *bitdata;
81 int ascent, descent, lbearing, rbearing;
82 int on = 1, off = 0;
83
84 /* make angle positive ... */
85 if (angle < 0) do angle += 360; while (angle < 0);
86
87 /* get nearest vertical or horizontal direction ... */
88 dir = (int)((angle+45.)/90.)%4;
89
90 /* useful macros ... */
91 screen = DefaultScreen(dpy);
92 root = DefaultRootWindow(dpy);
93
94 /* create the depth 1 canvas bitmap ... */
95 canvas = XCreatePixmap(dpy, root, boxlen, boxlen, 1);
96
97 /* create a GC ... */
98 font_gc = XCreateGC(dpy, canvas, 0, 0);
99 XSetBackground(dpy, font_gc, off);
100
101 /* load the font ... */
102 fontstruct = XLoadQueryFont(dpy, fontname);
103 if (fontstruct == NULL) {
104 cerr<<"Fluxbox::Misc: No font"<<endl;
105 return 0;
106 }
107
108 XSetFont(dpy, font_gc, fontstruct->fid);
109
110 /* allocate space for rotated font ... */
111 rotfont = (XRotFontStruct *)malloc((unsigned)sizeof(XRotFontStruct));
112
113 if (rotfont == 0) {
114 cerr<<"Fluxbox::Misc: out of memory"<<endl;
115 return 0;
116 }
117
118 /* determine which characters are defined in font ... */
119 min_char = fontstruct->min_char_or_byte2;
120 max_char = fontstruct->max_char_or_byte2;
121
122 /* we only want printing characters ... */
123 if (min_char<32) min_char = 32;
124 if (max_char>126) max_char = 126;
125
126 /* some overall font data ... */
127 rotfont->name = Misc::strdup(fontname);
128 rotfont->dir = dir;
129 rotfont->min_char = min_char;
130 rotfont->max_char = max_char;
131 rotfont->max_ascent = fontstruct->max_bounds.ascent;
132 rotfont->max_descent = fontstruct->max_bounds.descent;
133 rotfont->height = rotfont->max_ascent+rotfont->max_descent;
134
135 /* remember xfontstruct for `normal' text ... */
136 if (dir == 0)
137 rotfont->xfontstruct = fontstruct;
138 else {
139 /* font needs rotation ... */
140 /* loop through each character ... */
141 for (ichar = min_char; ichar <= max_char; ichar++) {
142 index = ichar-fontstruct->min_char_or_byte2;
143
144 /* per char dimensions ... */
145 ascent = rotfont->per_char[ichar-32].ascent =
146 fontstruct->per_char[index].ascent;
147 descent = rotfont->per_char[ichar-32].descent =
148 fontstruct->per_char[index].descent;
149 lbearing = rotfont->per_char[ichar-32].lbearing =
150 fontstruct->per_char[index].lbearing;
151 rbearing = rotfont->per_char[ichar-32].rbearing =
152 fontstruct->per_char[index].rbearing;
153 rotfont->per_char[ichar-32].width =
154 fontstruct->per_char[index].width;
155
156 /* some space chars have zero body, but a bitmap can't have ... */
157 if (!ascent && !descent)
158 ascent = rotfont->per_char[ichar-32].ascent = 1;
159 if (!lbearing && !rbearing)
160 rbearing = rotfont->per_char[ichar-32].rbearing = 1;
161
162 /* glyph width and height when vertical ... */
163 vert_w = rbearing-lbearing;
164 vert_h = ascent+descent;
165
166 /* width in bytes ... */
167 vert_len = (vert_w-1)/8+1;
168
169 XSetForeground(dpy, font_gc, off);
170 XFillRectangle(dpy, canvas, font_gc, 0, 0, boxlen, boxlen);
171
172 /* draw the character centre top right on canvas ... */
173 sprintf(text, "%c", ichar);
174 XSetForeground(dpy, font_gc, on);
175 XDrawImageString(dpy, canvas, font_gc, boxlen/2 - lbearing,
176 boxlen/2 - descent, text, 1);
177
178 /* reserve memory for first XImage ... */
179 vertdata = (unsigned char *) malloc((unsigned)(vert_len*vert_h));
180
181 /* create the XImage ... */
182 I1 = XCreateImage(dpy, DefaultVisual(dpy, screen), 1, XYBitmap,
183 0, (char *)vertdata, vert_w, vert_h, 8, 0);
184
185 if (I1 == NULL) {
186 cerr<<"Fluxbox::Misc: Cant create ximage."<<endl;
187 return NULL;
188 }
189
190 I1->byte_order = I1->bitmap_bit_order = MSBFirst;
191
192 /* extract character from canvas ... */
193 XGetSubImage(dpy, canvas, boxlen/2, boxlen/2-vert_h,
194 vert_w, vert_h, 1, XYPixmap, I1, 0, 0);
195 I1->format = XYBitmap;
196
197 /* width, height of rotated character ... */
198 if (dir == 2) {
199 bit_w = vert_w;
200 bit_h = vert_h;
201 } else {
202 bit_w = vert_h;
203 bit_h = vert_w;
204 }
205
206 /* width in bytes ... */
207 bit_len = (bit_w-1)/8 + 1;
208
209 rotfont->per_char[ichar-32].glyph.bit_w = bit_w;
210 rotfont->per_char[ichar-32].glyph.bit_h = bit_h;
211
212 /* reserve memory for the rotated image ... */
213 bitdata = (unsigned char *)calloc((unsigned)(bit_h*bit_len), 1);
214
215 /* create the image ... */
216 I2 = XCreateImage(dpy, DefaultVisual(dpy, screen), 1, XYBitmap, 0,
217 (char *)bitdata, bit_w, bit_h, 8, 0);
218
219 if (I2 == NULL) {
220 cerr<<"Font::Misc: Cant create ximage!"<<endl;
221 return 0;
222 }
223
224 I2->byte_order = I2->bitmap_bit_order = MSBFirst;
225
226 /* map vertical data to rotated character ... */
227 for (j = 0; j < bit_h; j++) {
228 for (i = 0; i < bit_w; i++) {
229 /* map bits ... */
230 if (dir == 1) {
231 val = vertdata[i*vert_len + (vert_w-j-1)/8] &
232 (128>>((vert_w-j-1)%8));
233 } else if (dir == 2) {
234 val = vertdata[(vert_h-j-1)*vert_len +
235 (vert_w-i-1)/8] & (128>>((vert_w-i-1)%8));
236 } else {
237 val = vertdata[(vert_h-i-1)*vert_len + j/8] &
238 (128>>(j%8));
239 }
240 if (val) {
241 bitdata[j*bit_len + i/8] = bitdata[j*bit_len + i/8] |
242 (128>>(i%8));
243 }
244 }
245 }
246
247 /* create this character's bitmap ... */
248 rotfont->per_char[ichar-32].glyph.bm =
249 XCreatePixmap(dpy, root, bit_w, bit_h, 1);
250
251 /* put the image into the bitmap ... */
252 XPutImage(dpy, rotfont->per_char[ichar-32].glyph.bm,
253 font_gc, I2, 0, 0, 0, 0, bit_w, bit_h);
254
255 /* free the image and data ... */
256 XDestroyImage(I1);
257 XDestroyImage(I2);
258 /* free((char *)bitdata); -- XDestroyImage does this
259 free((char *)vertdata);*/
260 }
261 XFreeFont(dpy, fontstruct);
262 }
263
264 /* free pixmap and GC ... */
265 XFreePixmap(dpy, canvas);
266 XFreeGC(dpy, font_gc);
267
268 return rotfont;
269}
270
271//------- XRotUnloadFont -----------------
272// Free the resources associated with a
273// rotated font
274//----------------------------------------
275void Misc::XRotUnloadFont(Display *dpy, XRotFontStruct *rotfont)
276{
277 int ichar;
278
279 if (rotfont->dir == 0)
280 XFreeFont(dpy, rotfont->xfontstruct);
281 else {
282 /* loop through each character, freeing its pixmap ... */
283 for (ichar = rotfont->min_char-32; ichar <= rotfont->max_char-32;
284 ichar++)
285 XFreePixmap(dpy, rotfont->per_char[ichar].glyph.bm);
286 }
287
288 free((char *)rotfont->name);
289 free((char *)rotfont);
290}
291
292//------- XRotTextWidth ------------------
293// Returns the width of a rotated string
294//----------------------------------------
295unsigned int Misc::XRotTextWidth(XRotFontStruct *rotfont, char *str, int len)
296{
297 int i, width = 0, ichar;
298
299 if (str == NULL)
300 return 0;
301
302 if (rotfont->dir == 0)
303 width = XTextWidth(rotfont->xfontstruct, str, strlen(str));
304 else {
305 for (i = 0; i<len; i++) {
306 ichar = str[i]-32;
307
308 /* make sure it's a printing character ... */
309 if (ichar >= 0 && ichar<95)
310 width += rotfont->per_char[ichar].width;
311 }
312 }
313 return width;
314}
315
316
317//------- XRotDrawString -----------------
318// A front end to XRotDrawString : mimics XDrawString
319//----------------------------------------
320void Misc::XRotDrawString(Display *dpy, XRotFontStruct *rotfont, Drawable drawable,
321 GC gc, int x, int y, char *str, int len)
322{
323 static GC my_gc = 0;
324 int i, xp, yp, dir, ichar;
325
326 if (str == NULL || len<1)
327 return;
328
329 dir = rotfont->dir;
330 if (my_gc == 0)
331 my_gc = XCreateGC(dpy, drawable, 0, 0);
332
333 XCopyGC(dpy, gc, GCForeground|GCBackground, my_gc);
334
335 /* a horizontal string is easy ... */
336 if (dir == 0) {
337 XSetFillStyle(dpy, my_gc, FillSolid);
338 XSetFont(dpy, my_gc, rotfont->xfontstruct->fid);
339 XDrawString(dpy, drawable, my_gc, x, y, str, len);
340 return;
341 }
342
343 /* vertical or upside down ... */
344
345 XSetFillStyle(dpy, my_gc, FillStippled);
346
347 /* loop through each character in string ... */
348 for (i = 0; i<len; i++) {
349 ichar = str[i]-32;
350
351 /* make sure it's a printing character ... */
352 if (ichar >= 0 && ichar<95) {
353 /* suitable offset ... */
354 if (dir == 1) {
355 xp = x-rotfont->per_char[ichar].ascent;
356 yp = y-rotfont->per_char[ichar].rbearing;
357 } else if (dir == 2) {
358 xp = x-rotfont->per_char[ichar].rbearing;
359 yp = y-rotfont->per_char[ichar].descent+1;
360 } else {
361 xp = x-rotfont->per_char[ichar].descent+1;
362 yp = y+rotfont->per_char[ichar].lbearing;
363 }
364
365 /* draw the glyph ... */
366 XSetStipple(dpy, my_gc, rotfont->per_char[ichar].glyph.bm);
367
368 XSetTSOrigin(dpy, my_gc, xp, yp);
369
370 XFillRectangle(dpy, drawable, my_gc, xp, yp,
371 rotfont->per_char[ichar].glyph.bit_w,
372 rotfont->per_char[ichar].glyph.bit_h);
373
374 /* advance position ... */
375 if (dir == 1)
376 y -= rotfont->per_char[ichar].width;
377 else if (dir == 2)
378 x -= rotfont->per_char[ichar].width;
379 else
380 y += rotfont->per_char[ichar].width;
381 }
382 }
383}
384
385
386//Draw title string
387void Misc::DrawString(Display *display, Window w, GC gc, Misc::Font *font,
388 unsigned int text_w, unsigned int size_w,
389 unsigned int bevel_w, char *text) {
390
391 if (!text || text_w<1 || size_w < 1 || !font || !display)
392 return;
393
394 unsigned int l = text_w;
395 int dlen=strlen(text);
396 int dx=bevel_w*2;
397
398
399 if (text_w > size_w) {
400 for (; dlen >= 0; dlen--) {
401 if (I18n::instance()->multibyte()) {
402 XRectangle ink, logical;
403 XmbTextExtents(font->set, text, dlen,
404 &ink, &logical);
405 l = logical.width;
406 } else
407 l = XTextWidth(font->fontstruct, text, dlen);
408
409 l += (dx * 4);
410
411 if (l < size_w)
412 break;
413 }
414 }
415
416 switch (font->justify) {
417 case Misc::Font::RIGHT:
418 dx += size_w - l;
419 break;
420
421 case Misc::Font::CENTER:
422 dx += (size_w - l) / 2;
423 break;
424 default:
425 break;
426 }
427
428 //Draw title to m_tabwin
429
430 XClearWindow(display, w);
431
432 if (I18n::instance()->multibyte()) {
433 XmbDrawString(display, w,
434 font->set, gc, dx, 1 - font->set_extents->max_ink_extent.y,
435 text, dlen);
436 } else {
437 XDrawString(display, w,
438 gc, dx, font->fontstruct->ascent + 1,
439 text, dlen);
440 }
441
442}
443
444
445void Misc::DrawRotString(Display *display, Window w, GC gc, XRotFontStruct *font,
446 unsigned int align, unsigned int text_w,
447 unsigned int size_w, unsigned int size_h,
448 unsigned int bevel_w, char *text) {
449
450 if (!text || text_w<1 || size_w < 1 || !font || !display)
451 return;
452
453 unsigned int l = text_w;
454 int dlen = strlen(text);
455 int dx = bevel_w * 2;
456
457 if (text_w > size_w) {
458 for (; dlen >= 0; dlen--) {
459 l = XRotTextWidth(font, text, dlen);
460
461 l += (dx * 4);
462
463 if (l < size_h)
464 break;
465 }
466 }
467
468 if (align == Misc::Font::RIGHT)
469 size_h = l;
470 else if (align == Misc::Font::CENTER)
471 size_h = (size_h + l) / 2;
472 else //LEFT
473 size_h -= (dx * 4);
474
475 // To get it in the "center" of the tab
476 size_w = (size_w + XRotTextWidth(font, "/", 1)) / 2;
477
478 //Draw title to m_tabwin
479 XClearWindow(display, w);
480 XRotDrawString(display, font, w, gc, size_w, size_h, text, dlen);
481}