CTWM
Loading...
Searching...
No Matches
/usr/src/RPM/BUILD/ctwm-4.1.0/util.c
Go to the documentation of this file.
1/*
2 * Copyright 1988 by Evans & Sutherland Computer Corporation,
3 * Salt Lake City, Utah
4 * Portions Copyright 1989 by the Massachusetts Institute of Technology
5 * Cambridge, Massachusetts
6 *
7 * Copyright 1992 Claude Lecommandeur.
8 */
9
10/***********************************************************************
11 *
12 * $XConsortium: util.c,v 1.47 91/07/14 13:40:37 rws Exp $
13 *
14 * utility routines for twm
15 *
16 * 28-Oct-87 Thomas E. LaStrange File created
17 *
18 * Do the necessary modification to be integrated in ctwm.
19 * Can no longer be used for the standard twm.
20 *
21 * 22-April-92 Claude Lecommandeur.
22 *
23 * Changed behavior of DontMoveOff/MoveOffResistance to allow
24 * moving a window off screen less than #MoveOffResistance pixels.
25 * New code will no longer "snap" windows to #MoveOffResistance
26 * pixels off screen and instead movements will just be stopped and
27 * then resume once movement of #MoveOffResistance have been attempted.
28 *
29 * 15-December-02 Bjorn Knutsson
30 *
31 ***********************************************************************/
32
33#include "ctwm.h"
34
35#include <stdio.h>
36#include <stdlib.h>
37#include <string.h>
38#include <strings.h>
39
40#include <signal.h>
41#include <sys/time.h>
42
43#include "animate.h"
44#include "add_window.h"
45#include "cursor.h"
46#include "drawing.h"
47#include "gram.tab.h"
48#include "iconmgr.h"
49#include "icons.h"
50#include "image.h"
51#include "screen.h"
52#include "util.h"
53#include "vscreen.h"
54#include "win_decorations.h"
55#include "win_resize.h"
56
57
58/* Handle for debug tracing */
60
61
62/*
63 * Rewrite this, possibly in terms of replace_substr(). Alternately, the
64 * places it's being used might be better served by being preprocessed
65 * into arrays anyway.
66 */
67char *ExpandFilePath(char *path)
68{
69 char *ret, *colon, *p;
70 int len;
71
72 len = 0;
73 p = path;
74 while((colon = strchr(p, ':'))) {
75 len += colon - p + 1;
76 if(*p == '~') {
77 len += HomeLen - 1;
78 }
79 p = colon + 1;
80 }
81 if(*p == '~') {
82 len += HomeLen - 1;
83 }
84 len += strlen(p);
85 ret = malloc(len + 1);
86 *ret = 0;
87
88 p = path;
89 while((colon = strchr(p, ':'))) {
90 *colon = '\0';
91 if(*p == '~') {
92 strcat(ret, Home);
93 strcat(ret, p + 1);
94 }
95 else {
96 strcat(ret, p);
97 }
98 *colon = ':';
99 strcat(ret, ":");
100 p = colon + 1;
101 }
102 if(*p == '~') {
103 strcat(ret, Home);
104 strcat(ret, p + 1);
105 }
106 else {
107 strcat(ret, p);
108 }
109 return ret;
110}
111
112/***********************************************************************
113 *
114 * Procedure:
115 * ExpandFilename - expand the tilde character to HOME
116 * if it is the first character of the filename
117 *
118 * Returned Value:
119 * a pointer to the new name
120 *
121 * Inputs:
122 * name - the filename to expand
123 *
124 ***********************************************************************
125 *
126 * Currently only used in one place in image_bitmap.c. I've left this
127 * here instead of moving it into images at the moment on the assumption
128 * that there might be other places in the codebase where it's useful.
129 */
130char *
131ExpandFilename(const char *name)
132{
133 char *newname;
134
135 /* If it doesn't start with ~/ then it's not our concern */
136 if(name[0] != '~' || name[1] != '/') {
137 return strdup(name);
138 }
139
140 asprintf(&newname, "%s/%s", Home, &name[1]);
141
142 return newname;
143}
144
145
146
147/*
148 * Some color utils
149 */
150/**
151 * Get info from the server about a given color.
152 */
153void
154GetColor(int kind, Pixel *what, const char *name)
155{
156 XColor color;
157 Colormap cmap = Scr->RootColormaps.cwins[0]->colormap->c;
158
159 // If we have no valid X connection (generally means a --cfgchk or
160 // similar run; wont' happen in normal operations), just stub out.
161 if(dpy == NULL) {
162 *what = 0;
163 return;
164 }
165
166#ifndef TOM
167 if(!Scr->FirstTime) {
168 return;
169 }
170#endif
171
172 if(Scr->Monochrome != kind) {
173 return;
174 }
175
176 if(! XParseColor(dpy, cmap, name, &color)) {
177 fprintf(stderr, "%s: invalid color name \"%s\"\n", ProgramName, name);
178 return;
179 }
180 if(! XAllocColor(dpy, cmap, &color)) {
181 /* if we could not allocate the color, let's see if this is a
182 * standard colormap
183 */
185
186 if(! XParseColor(dpy, cmap, name, &color)) {
187 fprintf(stderr, "%s: invalid color name \"%s\"\n", ProgramName, name);
188 return;
189 }
190
191 /*
192 * look through the list of standard colormaps (check cache first)
193 */
194 if(Scr->StdCmapInfo.mru && Scr->StdCmapInfo.mru->maps &&
195 (Scr->StdCmapInfo.mru->maps[Scr->StdCmapInfo.mruindex].colormap ==
196 cmap)) {
197 stdcmap = &(Scr->StdCmapInfo.mru->maps[Scr->StdCmapInfo.mruindex]);
198 }
199 else {
200 StdCmap *sc;
201
202 for(sc = Scr->StdCmapInfo.head; sc; sc = sc->next) {
203 int i;
204
205 for(i = 0; i < sc->nmaps; i++) {
206 if(sc->maps[i].colormap == cmap) {
207 Scr->StdCmapInfo.mru = sc;
208 Scr->StdCmapInfo.mruindex = i;
209 stdcmap = &(sc->maps[i]);
210 goto gotit;
211 }
212 }
213 }
214 }
215
216gotit:
217 if(stdcmap) {
218 color.pixel = (stdcmap->base_pixel +
219 ((Pixel)(((float)color.red / 65535.0) *
220 stdcmap->red_max + 0.5) *
221 stdcmap->red_mult) +
222 ((Pixel)(((float)color.green / 65535.0) *
223 stdcmap->green_max + 0.5) *
224 stdcmap->green_mult) +
225 ((Pixel)(((float)color.blue / 65535.0) *
226 stdcmap->blue_max + 0.5) *
227 stdcmap->blue_mult));
228 }
229 else {
230 fprintf(stderr, "%s: unable to allocate color \"%s\"\n",
231 ProgramName, name);
232 return;
233 }
234 }
235
236 *what = color.pixel;
237 return;
238}
239
240
241/**
242 * Try and create a 'shaded' version of a color for prettier UI.
243 */
244void
246{
247 XColor xcol;
248 Colormap cmap = Scr->RootColormaps.cwins[0]->colormap->c;
249 bool save;
250 float clearfactor;
251 float darkfactor;
252 char clearcol [32], darkcol [32];
253
254 // If we have no valid X connection (generally means a --cfgchk or
255 // similar run; wont' happen in normal operations), just stub out.
256 if(dpy == NULL) {
257 cp->shadc = 0;
258 cp->shadd = 0;
259 return;
260 }
261
262 clearfactor = (float) Scr->ClearShadowContrast / 100.0;
263 darkfactor = (100.0 - (float) Scr->DarkShadowContrast) / 100.0;
264 xcol.pixel = cp->back;
266
267 sprintf(clearcol, "#%04x%04x%04x",
268 xcol.red + (unsigned short)((65535 - xcol.red) * clearfactor),
269 xcol.green + (unsigned short)((65535 - xcol.green) * clearfactor),
270 xcol.blue + (unsigned short)((65535 - xcol.blue) * clearfactor));
271 sprintf(darkcol, "#%04x%04x%04x",
272 (unsigned short)(xcol.red * darkfactor),
273 (unsigned short)(xcol.green * darkfactor),
274 (unsigned short)(xcol.blue * darkfactor));
275
276 save = Scr->FirstTime;
277 Scr->FirstTime = true;
278 GetColor(Scr->Monochrome, &cp->shadc, clearcol);
279 GetColor(Scr->Monochrome, &cp->shadd, darkcol);
280 Scr->FirstTime = save;
281}
282
283
284
285/*
286 * Various font utils
287 */
288/**
289 * Try adjusting a font's height. Used in drawing the icon manager.
290 */
291bool
292UpdateFont(MyFont *font, int height)
293{
294 int prev = font->avg_height;
295 font->avg_fheight = (font->avg_fheight * font->avg_count + height)
296 / (font->avg_count + 1);
297 font->avg_count++;
298 /* Arbitrary limit. */
299 if(font->avg_count >= 256) {
300 font->avg_count = 256;
301 }
302 font->avg_height = (int)(font->avg_fheight + 0.5);
303 /* fprintf (stderr, "Updating avg with %d(%d) + %d -> %d(%f)\n",
304 * prev, font->avg_count, height,
305 * font->avg_height, font->avg_fheight); */
306 return (prev != font->avg_height);
307}
308
309
310/**
311 * Load up fontsets from the X server. Only used by CreateFonts() below.
312 */
313static void
315{
316 char *deffontname = "fixed,*";
319 char *def_string_return;
322 char **font_names;
323 int i;
324 int ascent;
325 int descent;
326 int fnum;
327 char *basename2;
328
329 // In special cases where we have no dpy, I don't think we're going
330 // to need details here, so just leave things untouched. We may need
331 // to stub in some magic values; deal with that when we run into the
332 // case.
333 if(dpy == NULL) {
334 return;
335 }
336
337 if(font->font_set != NULL) {
338 XFreeFontSet(dpy, font->font_set);
339 }
340
341 asprintf(&basename2, "%s,*", font->basename);
345 &def_string_return)) == NULL) {
346 fprintf(stderr, "Failed to get fontset %s\n", basename2);
347 if(Scr->DefaultFont.basename) {
348 deffontname = Scr->DefaultFont.basename;
349 }
353 &def_string_return)) == NULL) {
354 fprintf(stderr, "%s: unable to open fonts \"%s\" or \"%s\"\n",
356 exit(1);
357 }
358 }
361
363 for(i = 0, ascent = 0, descent = 0; i < fnum; i++) {
364 ascent = MaxSize(ascent, (*xfonts)->ascent);
365 descent = MaxSize(descent, (*xfonts)->descent);
366 xfonts++;
367 }
368
369 font->height = font_extents->max_logical_extent.height;
370 font->y = ascent;
371 font->ascent = ascent;
372 font->descent = descent;
373 font->avg_height = 0;
374 font->avg_fheight = 0.0;
375 font->avg_count = 0;
376}
377
378
379/**
380 * Load up our various defined fonts
381 */
382void
384{
385#define LOADFONT(fld) (GetFont(&scr->fld##Font))
387 LOADFONT(Menu);
388 LOADFONT(Icon);
389 LOADFONT(Size);
392 LOADFONT(workSpaceMgr.window);
393#undef LOADFONT
394
395 scr->HaveFonts = true;
396}
397
398
399
400#if 0
401static void move_to_head(TwmWindow *t)
402{
403 if(t == NULL) {
404 return;
405 }
406 if(Scr->FirstWindow == t) {
407 return;
408 }
409
410 /* Unlink t from current position */
411 if(t->prev) {
412 t->prev->next = t->next;
413 }
414 if(t->next) {
415 t->next->prev = t->prev;
416 }
417
418 /* Re-link t at head */
419 t->next = Scr->FirstWindow;
420 if(Scr->FirstWindow != NULL) {
421 Scr->FirstWindow->prev = t;
422 }
423 t->prev = NULL;
424 Scr->FirstWindow = t;
425}
426
427/*
428 * Moves window 't' after window 'after'.
429 *
430 * If 'after' == NULL, puts it at the head.
431 * If 't' == NULL, does nothing.
432 * If the 't' is already after 'after', does nothing.
433 */
434
436{
437 if(after == NULL) {
439 return;
440 }
441 if(t == NULL) {
442 return;
443 }
444 if(after->next == t) {
445 return;
446 }
447
448 /* Unlink t from current position */
449 if(t->prev) {
450 t->prev->next = t->next;
451 }
452 if(t->next) {
453 t->next->prev = t->prev;
454 }
455
456 /* Re-link t after 'after' */
457 t->next = after->next;
458 if(after->next) {
459 after->next->prev = t;
460 }
461 t->prev = after;
462 after->next = t;
463}
464#endif
465
466
467
468/**
469 * Backend for f.rescuewindows
470 */
472{
473 TwmWindow *twm_win = Scr->FirstWindow;
474
475 while(twm_win) {
476 VirtualScreen *vs = twm_win->vs;
477 if(vs) {
478 /*
479 * Check if this window seems completely out of sight.
480 */
481 int x = twm_win->frame_x;
482 int y = twm_win->frame_y;
483 int w = twm_win->frame_width;
484 int h = twm_win->frame_height;
485 int bw = twm_win->frame_bw;
486 int fullw = w + 2 * bw;
487 int fullh = h + 2 * bw;
488 int old_x = x, old_y = y;
489 struct Icon *i;
490
491#define MARGIN 20
492
493 if(x >= vs->w - MARGIN) {
494 x = vs->w - fullw;
495 }
496 if(y >= vs->h - MARGIN) {
497 y = vs->h - fullh;
498 }
499 if((x + fullw <= MARGIN)) {
500 x = 0;
501 }
502 if((y + fullh <= MARGIN)) {
503 y = 0;
504 }
505
506 if(x != old_x || y != old_y) {
507 SetupWindow(twm_win, x, y, w, h, -1);
508 }
509
510 /*
511 * If there is an icon, check it too.
512 */
513 i = twm_win->icon;
514 if(i != NULL) {
515 x = i->w_x;
516 y = i->w_y;
517 w = i->w_width;
518 h = i->w_height;
519 old_x = x;
520 old_y = y;
521
522 if(x >= vs->w - MARGIN) {
523 x = vs->w - w;
524 }
525 if(y >= vs->h - MARGIN) {
526 y = vs->h - h;
527 }
528 if((x + w <= MARGIN)) {
529 x = 0;
530 }
531 if((y + h <= MARGIN)) {
532 y = 0;
533 }
534
535 if(x != old_x || y != old_y) {
536 XMoveWindow(dpy, i->w, x, y);
537 i->w_x = x;
538 i->w_y = y;
539 }
540 }
541#undef MARGIN
542 }
543 twm_win = twm_win->next;
544 }
545}
546
547
548
549/**
550 * Backend for f.trace
551 */
552void
554{
555 if(!file) {
556 return;
557 }
558 if(tracefile) {
559 fprintf(stderr, "stop logging events\n");
560 if(tracefile != stderr) {
562 }
563 tracefile = NULL;
564 }
565 else {
566 if(strcmp(file, "stderr")) {
567 tracefile = fopen(file, "w");
568 }
569 else {
571 }
572 fprintf(stderr, "logging events to : %s\n", file);
573 }
574}
575
576
577
578/*
579 * A safe strncpy(), which always ensures NUL-termination.
580 *
581 * XXX This is really just a slightly pessimized implementation of
582 * strlcpy(). Maybe we should use that instead, with a local
583 * implementation for systems like glibc-users that lack it?
584 */
585void
586safe_strncpy(char *dest, const char *src, size_t size)
587{
588 strncpy(dest, src, size - 1);
589 dest[size - 1] = '\0';
590}
static int PlaceX
Definition add_window.c:82
char * ProgramName
Definition ctwm_main.c:146
char * Home
Definition ctwm_main.c:128
Display * dpy
Definition ctwm_main.c:84
int HomeLen
Definition ctwm_main.c:129
#define MaxSize(a, b)
Definition ctwm.h:124
#define Scr
int frame_x
X position on screen of frame.
int frame_y
Y position on screen of frame.
int frame_bw
2d border width.
unsigned int frame_width
Width of frame.
unsigned int frame_height
Height of frame.
int y
Definition menus.c:70
int x
Definition menus.c:69
static int len
Definition parse.c:75
Pixel back
Definition ctwm.h:141
Pixel shadd
Definition ctwm.h:141
Pixel shadc
Definition ctwm.h:141
Definition icons.h:26
int w_y
Definition icons.h:35
int w_width
Definition icons.h:36
int w_height
Definition icons.h:37
Window w
Definition icons.h:28
int w_x
Definition icons.h:34
Definition ctwm.h:127
int descent
Definition ctwm.h:131
unsigned int avg_height
Definition ctwm.h:135
int height
Definition ctwm.h:132
XFontSet font_set
Definition ctwm.h:129
int y
Definition ctwm.h:133
float avg_fheight
Definition ctwm.h:136
int ascent
Definition ctwm.h:130
char * basename
Definition ctwm.h:128
unsigned int avg_count
Definition ctwm.h:137
Info and control for each X Screen we control.
Definition screen.h:96
bool HaveFonts
Whether fonts have been loaded yet in the startup process.
Definition screen.h:908
Information about some XStandardColormap we're using.
Definition screen.h:46
Info and control for every X Window we take over.
struct TwmWindow * next
Next TwmWindow on the Screen.
struct Icon * icon
The current icon.
struct VirtualScreen * vs
Where the window is currently mapped (may be NULL)
void safe_strncpy(char *dest, const char *src, size_t size)
Definition util.c:586
#define LOADFONT(fld)
void GetColor(int kind, Pixel *what, const char *name)
Get info from the server about a given color.
Definition util.c:154
FILE * tracefile
Definition util.c:59
char * ExpandFilename(const char *name)
Definition util.c:131
bool UpdateFont(MyFont *font, int height)
Try adjusting a font's height.
Definition util.c:292
void GetShadeColors(ColorPair *cp)
Try and create a 'shaded' version of a color for prettier UI.
Definition util.c:245
void RescueWindows(void)
Backend for f.rescuewindows.
Definition util.c:471
#define MARGIN
static void GetFont(MyFont *font)
Load up fontsets from the X server.
Definition util.c:314
char * ExpandFilePath(char *path)
Definition util.c:67
void DebugTrace(char *file)
Backend for f.trace.
Definition util.c:553
void CreateFonts(ScreenInfo *scr)
Load up our various defined fonts.
Definition util.c:383
void SetupWindow(TwmWindow *tmp_win, int x, int y, int w, int h, int bw)