CTWM
Loading...
Searching...
No Matches
/usr/src/RPM/BUILD/ctwm-4.1.0/iconmgr.c
Go to the documentation of this file.
1/*
2 * Copyright 1989 Massachusetts Institute of Technology
3 * Copyright 1992 Claude Lecommandeur.
4 */
5
6/***********************************************************************
7 *
8 * $XConsortium: iconmgr.c,v 1.48 91/09/10 15:27:07 dave Exp $
9 *
10 * Icon Manager routines
11 *
12 * 09-Mar-89 Tom LaStrange File Created
13 *
14 * Do the necessary modification to be integrated in ctwm.
15 * Can no longer be used for the standard twm.
16 *
17 * 22-April-92 Claude Lecommandeur.
18 *
19 *
20 ***********************************************************************/
21
22#include "ctwm.h"
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <strings.h>
28
29#include <X11/Xatom.h>
30
31#include "util.h"
32#include "iconmgr.h"
33#include "icons_builtin.h"
34#include "screen.h"
35#include "drawing.h"
36#include "functions_defs.h"
37#include "list.h"
38#include "occupation.h"
39#include "otp.h"
40#include "add_window.h"
41#include "gram.tab.h"
42#include "vscreen.h"
43#include "win_decorations.h"
44#include "win_resize.h"
45#include "win_utils.h"
46#include "xparsegeometry.h"
47
48
49/* Where we start drawing the name in the icon manager */
50static int iconmgr_textx;
51
52static WList *Active = NULL;
53static WList *Current = NULL;
55
56/***********************************************************************
57 *
58 * Procedure:
59 * CreateIconManagers - creat all the icon manager windows
60 * for this screen.
61 *
62 * Returned Value:
63 * none
64 *
65 * Inputs:
66 * none
67 *
68 ***********************************************************************
69 */
70
72{
74
75 if(Scr->NoIconManagers) {
76 return;
77 }
78
79 /*
80 * Move past the iconified icon to start the text.
81 * XXX Semi-arbitrary magic add'l padding, to deal with various inner
82 * positioning of the icon subwindow. Be smarter (or at least
83 * clearer) about this...
84 */
86 if(Scr->use3Diconmanagers) {
87 iconmgr_textx += Scr->IconManagerShadowDepth;
88 }
89
90 if(Scr->siconifyPm == None) {
91 Scr->siconifyPm = Create2DIconManagerIcon();
92 }
93
94 // This loop is confusing. The inner for() loops p over the ->next
95 // elements in the list, which is all the iconmgr's in the workspace.
96 // The outer for() loops q over the ->nextv (<-- extra 'v' on the
97 // end), which is a link to the head of the iconmgr list for the
98 // _next_ workspace.
99 ws = Scr->workSpaceMgr.workSpaceList;
100 for(IconMgr *q = Scr->iconmgr; q != NULL; q = q->nextv) {
101 for(IconMgr *p = q; p != NULL; p = p->next) {
102 int gx, gy;
103 char imname[100];
104 int mask;
105 int gravity;
106 int bw;
108
109 snprintf(imname, sizeof(imname), "%s Icon Manager", p->name);
110
111 if(!p->geometry || !strlen(p->geometry)) {
112 p->geometry = "+0+0";
113 }
114 mask = RLayoutXParseGeometry(Scr->Layout, p->geometry,
115 &gx, &gy,
116 (unsigned int *) &p->width, (unsigned int *)&p->height);
117
118 bw = LookInList(Scr->NoBorder, imname, NULL) ? 0 :
119 (Scr->ThreeDBorderWidth ? Scr->ThreeDBorderWidth : Scr->BorderWidth);
120
121 if(mask & XNegative) {
122 gx += Scr->rootw - p->width - 2 * bw;
124 }
125 else {
127 }
128 if(mask & YNegative) {
129 gy += Scr->rooth - p->height - 2 * bw;
130 }
131
132 background = Scr->IconManagerC.back;
133 GetColorFromList(Scr->IconManagerBL, p->name, NULL,
134 &background);
135
136 if(p->width < 1) {
137 p->width = 1;
138 }
139 if(p->height < 1) {
140 p->height = 1;
141 }
142 p->w = XCreateSimpleWindow(dpy, Scr->Root,
143 gx, gy, p->width, p->height, 1,
144 Scr->Black, background);
145
146
147 /* Scr->workSpaceMgr.activeWSPC = ws; */
148
149 /* Setup various WM properties on the iconmgr's window */
150 {
151 char *icon_name;
152 XWMHints wmhints;
154
155 if(p->icon_name) {
156 icon_name = strdup(p->icon_name);
157 }
158 else {
159 asprintf(&icon_name, "%s Icons", p->name);
160 }
161
162 wmhints.initial_state = NormalState;
163 wmhints.input = True;
164 wmhints.flags = InputHint | StateHint;
165
166 clhints.res_name = icon_name;
167 clhints.res_class = "TwmIconManager";
168
169 XmbSetWMProperties(dpy, p->w, imname, icon_name, NULL, 0, NULL,
170 &wmhints, &clhints);
171 free(icon_name);
172 }
173
174
175 p->twm_win = AddWindow(p->w, AWT_ICON_MANAGER, p, Scr->currentvs);
176
177 // SetupOccupation() called from AddWindow() doesn't setup
178 // occupation for icon managers, nor clear vs if occupation
179 // lacks. So make it occupy the one we're setting up, or the
180 // 1st if we ran out somehow...
181 if(ws) {
182 p->twm_win->occupation = 1 << ws->number;
183
184 // ConfigureWorkSpaceManager() ran before us, so we can
185 // tell whether we're in the ws to reveal this IM.
186 if(ws->number != Scr->currentvs->wsw->currentwspc->number) {
187 p->twm_win->vs = NULL;
188 }
189 }
190 else {
191 p->twm_win->occupation = 1;
192 }
193
194#ifdef DEBUG_ICONMGR
196 "CreateIconManagers: IconMgr %p: twm_win=%p win=0x%lx "
197 "name='%s' x=%d y=%d w=%d h=%d occupation=%x\n",
198 p, p->twm_win, p->twm_win->w, p->name,
199 gx, gy, p->width, p->height, p->twm_win->occupation);
200#endif
201
202 {
204
205 sizehints.flags = PWinGravity;
206 sizehints.win_gravity = gravity;
208 }
209
210 p->twm_win->mapped = false;
212 if(p->twm_win && (p->twm_win->wmhints->initial_state == IconicState)) {
213 p->twm_win->isicon = true;
214 }
215 else if(!Scr->NoIconManagers && Scr->ShowIconManager) {
216 p->twm_win->isicon = false;
217 }
218 else {
219 p->twm_win->isicon = true;
220 }
221 }
222 if(ws != NULL) {
223 ws = ws->next;
224 }
225 }
226
227 if(Scr->workSpaceManagerActive) {
228 Scr->workSpaceMgr.workSpaceList->iconmgr = Scr->iconmgr;
229 }
230
231
232 /*
233 * Grab buttons/keystrokes for icon managers appropriately.
234 * Normally, this is done in AddWindow(), but it explicitly skips it
235 * for icon managers. It's not at all clear why GrabButtons() would
236 * do so; I don't think it needs to. GrabKeys() does do some looping
237 * over the Scr->iconmgr list at the end though, so it's possible we
238 * need to delay calling it until now when the list is all filled up.
239 * This needs further investigation; it may be that the special case
240 * and this code can be removed. X-ref comments in add_window.c
241 * about it.
242 */
243 for(IconMgr *q = Scr->iconmgr; q != NULL; q = q->nextv) {
244 for(IconMgr *p = q; p != NULL; p = p->next) {
245 GrabButtons(p->twm_win);
246 GrabKeys(p->twm_win);
247 }
248 }
249
250}
251
252/***********************************************************************
253 *
254 * Procedure:
255 * AllocateIconManager - allocate a new icon manager
256 *
257 * Inputs:
258 * name - the name of this icon manager
259 * icon_name - the name of the associated icon
260 * geom - a geometry string to eventually parse
261 * columns - the number of columns this icon manager has
262 *
263 ***********************************************************************
264 */
265
266IconMgr *AllocateIconManager(char *name, char *icon_name, char *geom,
267 int columns)
268{
269 IconMgr *p;
270
271#ifdef DEBUG_ICONMGR
272 fprintf(stderr, "AllocateIconManager\n");
273 fprintf(stderr, " name=\"%s\" icon_name=\"%s\", geom=\"%s\", col=%d\n",
274 name, icon_name, geom, columns);
275#endif
276
277 if(Scr->NoIconManagers) {
278 return NULL;
279 }
280
281 if(columns < 1) {
282 columns = 1;
283 }
284 p = calloc(1, sizeof(IconMgr));
285 p->name = name;
286 p->icon_name = icon_name;
287 p->geometry = geom;
288 p->columns = columns;
289 p->scr = Scr;
290 p->width = 150;
291 p->height = 10;
292
293 if(Scr->iconmgr == NULL) {
294 Scr->iconmgr = p;
295 Scr->iconmgr->lasti = p;
296 }
297 else {
298 Scr->iconmgr->lasti->next = p;
299 p->prev = Scr->iconmgr->lasti;
300 Scr->iconmgr->lasti = p;
301 }
302 return(p);
303}
304
305
306/*
307 * Each workspace has its own [set of] icon manager[s]. The initial main
308 * one was setup via AllocateIconManager() early in startup. The others
309 * were setup during parsing the config file. Then this gets called late
310 * in startup, after all the workspaces are setup, to copy them all into
311 * each one.
312 *
313 * Note this is distinct from CreateIconManagers(); that creates and
314 * draws the windows, this creates and connects up the data structures.
315 */
317{
318 IconMgr *imfirst; // First IM on each workspace
319 WorkSpace *ws;
320
321 /* No defined workspaces? Nothing to do. */
322 if(! Scr->workSpaceManagerActive) {
323 return;
324 }
325
326 /* The first workspace just gets the ones we already have */
327 ws = Scr->workSpaceMgr.workSpaceList;
328 ws->iconmgr = Scr->iconmgr;
329
330 /* From the second on, we start copying */
331 imfirst = ws->iconmgr;
332 for(ws = ws->next; ws != NULL; ws = ws->next) {
333 IconMgr *ip, *previ, *p = NULL;
334
335 /* Copy in the first iconmgr */
336 ws->iconmgr = malloc(sizeof(IconMgr));
337 *ws->iconmgr = *imfirst;
338
339 /*
340 * This first is now the nextv to the first in the previous WS,
341 * and we don't [yet] have a nextv of our own.
342 * */
343 imfirst->nextv = ws->iconmgr;
344 ws->iconmgr->nextv = NULL;
345
346 /*
347 * Start from the second, and copy them each from the prior
348 * workspace we just went through.
349 * */
350 previ = ws->iconmgr;
351 for(ip = imfirst->next; ip != NULL; ip = ip->next) {
352 /* Copy the base bits */
353 p = malloc(sizeof(IconMgr));
354 *p = *ip;
355
356 /* Link up the double-links, and there's no nextv [yet] */
357 previ->next = p;
358 p->prev = previ;
359 p->next = NULL;
360 p->nextv = NULL;
361
362 /* We're now the nextv to that one in the old workspace */
363 ip->nextv = p;
364
365 /* And back around to the next one to copy into this WS */
366 previ = p;
367 }
368
369 /* Each one has a pointer to the last IM in this WS, so save those */
370 for(ip = ws->iconmgr; ip != NULL; ip = ip->next) {
371 ip->lasti = p;
372 }
373
374 /*
375 * And back around to the next workspace, which works from those
376 * we made for this WS. We go from imfirst rather than
377 * Scr->iconmgr so the ip->nextv rewrites are correct above; we
378 * have to fill them in on the next loop.
379 */
380 imfirst = ws->iconmgr;
381 }
382}
383
384
385/***********************************************************************
386 *
387 * Procedure:
388 * MoveIconManager - move the pointer around in an icon manager
389 *
390 * Inputs:
391 * dir - one of the following:
392 * F_FORWICONMGR - forward in the window list
393 * F_BACKICONMGR - backward in the window list
394 * F_UPICONMGR - up one row
395 * F_DOWNICONMGR - down one row
396 * F_LEFTICONMGR - left one column
397 * F_RIGHTICONMGR - right one column
398 *
399 * Special Considerations:
400 * none
401 *
402 ***********************************************************************
403 */
404
406{
407 IconMgr *ip;
408 WList *tmp = NULL;
410 int row_inc, col_inc;
411 bool got_it;
412
413 if(!Current) {
414 return;
415 }
416
419 ip = Current->iconmgr;
420
421 row_inc = 0;
422 col_inc = 0;
423 got_it = false;
424
425 switch(dir) {
426 case F_FORWICONMGR:
427 if((tmp = Current->next) == NULL) {
428 tmp = ip->first;
429 }
430 got_it = true;
431 break;
432
433 case F_BACKICONMGR:
434 if((tmp = Current->prev) == NULL) {
435 tmp = ip->last;
436 }
437 got_it = true;
438 break;
439
440 case F_UPICONMGR:
441 row_inc = -1;
442 break;
443
444 case F_DOWNICONMGR:
445 row_inc = 1;
446 break;
447
448 case F_LEFTICONMGR:
449 col_inc = -1;
450 break;
451
452 case F_RIGHTICONMGR:
453 col_inc = 1;
454 break;
455 }
456
457 /* If got_it is false ast this point then we got a left, right,
458 * up, or down, command. We will enter this loop until we find
459 * a window to warp to.
460 */
463
464 while(!got_it) {
465 new_row += row_inc;
466 new_col += col_inc;
467 if(new_row < 0) {
468 new_row = ip->cur_rows - 1;
469 }
470 if(new_col < 0) {
471 new_col = ip->cur_columns - 1;
472 }
473 if(new_row >= ip->cur_rows) {
474 new_row = 0;
475 }
476 if(new_col >= ip->cur_columns) {
477 new_col = 0;
478 }
479
480 /* Now let's go through the list to see if there is an entry with this
481 * new position
482 */
483 for(tmp = ip->first; tmp != NULL; tmp = tmp->next) {
484 if(tmp->row == new_row && tmp->col == new_col) {
485 got_it = true;
486 break;
487 }
488 }
489 }
490
491 if(!got_it) {
493 "%s: unable to find window (%d, %d) in icon manager\n",
495 return;
496 }
497
498 if(tmp == NULL) {
499 return;
500 }
501
502 /* raise the frame so the icon manager is visible */
503 if(ip->twm_win->mapped) {
504 OtpRaise(ip->twm_win, WinWin);
505 XWarpPointer(dpy, None, tmp->icon, 0, 0, 0, 0, 5, 5);
506 }
507 else {
508 if(tmp->twm->title_height) {
509 int tbx = Scr->TBInfo.titlex;
510 int x = tmp->twm->highlightxr;
511 XWarpPointer(dpy, None, tmp->twm->title_w, 0, 0, 0, 0,
512 tbx + (x - tbx) / 2,
513 Scr->TitleHeight / 4);
514 }
515 else {
516 XWarpPointer(dpy, None, tmp->twm->w, 0, 0, 0, 0, 5, 5);
517 }
518 }
519}
520
521/***********************************************************************
522 *
523 * Procedure:
524 * MoveMappedIconManager - move the pointer around in an icon manager
525 *
526 * Inputs:
527 * dir - one of the following:
528 * F_FORWMAPICONMGR - forward in the window list
529 * F_BACKMAPICONMGR - backward in the window list
530 *
531 * Special Considerations:
532 * none
533 *
534 ***********************************************************************
535 */
536
538{
539 IconMgr *ip;
540 WList *tmp = NULL;
541 WList *orig = NULL;
542 bool got_it;
543
544 if(!Current) {
545 Current = Active;
546 }
547 if(!Current) {
548 return;
549 }
550
551 ip = Current->iconmgr;
552
553 got_it = false;
554 tmp = Current;
555 orig = Current;
556
557 while(!got_it) {
558 switch(dir) {
559 case F_FORWMAPICONMGR:
560 if((tmp = tmp->next) == NULL) {
561 tmp = ip->first;
562 }
563 break;
564
565 case F_BACKMAPICONMGR:
566 if((tmp = tmp->prev) == NULL) {
567 tmp = ip->last;
568 }
569 break;
570 }
571 if(tmp->twm->mapped) {
572 got_it = true;
573 break;
574 }
575 if(tmp == orig) {
576 break;
577 }
578 }
579
580 if(!got_it) {
581 fprintf(stderr, "%s: unable to find open window in icon manager\n",
583 return;
584 }
585
586 if(tmp == NULL) {
587 return;
588 }
589
590 /* raise the frame so the icon manager is visible */
591 if(ip->twm_win->mapped) {
592 OtpRaise(ip->twm_win, WinWin);
593 XWarpPointer(dpy, None, tmp->icon, 0, 0, 0, 0, 5, 5);
594 }
595 else {
596 if(tmp->twm->title_height) {
597 XWarpPointer(dpy, None, tmp->twm->title_w, 0, 0, 0, 0,
598 tmp->twm->title_width / 2,
599 Scr->TitleHeight / 4);
600 }
601 else {
602 XWarpPointer(dpy, None, tmp->twm->w, 0, 0, 0, 0, 5, 5);
603 }
604 }
605}
606
607/***********************************************************************
608 *
609 * Procedure:
610 * JumpIconManager - jump from one icon manager to another,
611 * possibly even on another screen
612 *
613 * Inputs:
614 * dir - one of the following:
615 * F_NEXTICONMGR - go to the next icon manager
616 * F_PREVICONMGR - go to the previous one
617 *
618 ***********************************************************************
619 */
620
622{
623 IconMgr *ip, *tmp_ip = NULL;
624 bool got_it = false;
625 ScreenInfo *sp;
626 int screen;
627
628 if(!Current) {
629 return;
630 }
631
632
633#define ITER(i) (dir == F_NEXTICONMGR ? (i)->next : (i)->prev)
634#define IPOFSP(sp) (dir == F_NEXTICONMGR ? sp->iconmgr : sp->iconmgr->lasti)
635#define TEST(ip) if ((ip)->count != 0 && (ip)->twm_win->mapped) \
636 { got_it = true; break; }
637
638 ip = Current->iconmgr;
639 for(tmp_ip = ITER(ip); tmp_ip; tmp_ip = ITER(tmp_ip)) {
640 TEST(tmp_ip);
641 }
642
643 if(!got_it) {
644 int origscreen = ip->scr->screen;
645 int inc = (dir == F_NEXTICONMGR ? 1 : -1);
646
647 for(screen = origscreen + inc; ; screen += inc) {
648 if(screen >= NumScreens) {
649 screen = 0;
650 }
651 else if(screen < 0) {
652 screen = NumScreens - 1;
653 }
654
655 sp = ScreenList[screen];
656 if(sp) {
657 for(tmp_ip = IPOFSP(sp); tmp_ip; tmp_ip = ITER(tmp_ip)) {
658 TEST(tmp_ip);
659 }
660 }
661 if(got_it || screen == origscreen) {
662 break;
663 }
664 }
665 }
666
667#undef ITER
668#undef IPOFSP
669#undef TEST
670
671 if(!got_it) {
672 XBell(dpy, 0);
673 return;
674 }
675
676 /* raise the frame so it is visible */
677 OtpRaise(tmp_ip->twm_win, WinWin);
678 if(tmp_ip->active) {
679 XWarpPointer(dpy, None, tmp_ip->active->icon, 0, 0, 0, 0, 5, 5);
680 }
681 else {
682 XWarpPointer(dpy, None, tmp_ip->w, 0, 0, 0, 0, 5, 5);
683 }
684}
685
686/***********************************************************************
687 *
688 * Procedure:
689 * AddIconManager - add a window to an icon manager
690 *
691 * Inputs:
692 * tmp_win - the TwmWindow structure
693 *
694 ***********************************************************************
695 */
696
698{
699 WList *tmp, *old;
700 IconMgr *ip;
701
702 /* Some window types don't wind up in icon managers ever */
703 if(tmp_win->isiconmgr || tmp_win->istransient || tmp_win->iswspmgr
704 || tmp_win->w == Scr->workSpaceMgr.occupyWindow->w) {
705 return NULL;
706 }
707
708 /* Icon managers can be shut off wholesale in the config */
709 if(Scr->NoIconManagers) {
710 return NULL;
711 }
712
713 /* Config could declare not to IMify this type of window in two ways */
714 if(LookInList(Scr->IconMgrNoShow, tmp_win->name, &tmp_win->class)) {
715 return NULL;
716 }
717 if(Scr->IconManagerDontShow
718 && !LookInList(Scr->IconMgrShow, tmp_win->name, &tmp_win->class)) {
719 return NULL;
720 }
721
722 /* Dredge up the appropriate IM */
723 if((ip = (IconMgr *)LookInList(Scr->IconMgrs, tmp_win->name,
724 &tmp_win->class)) == NULL) {
725 if(Scr->workSpaceManagerActive) {
726 ip = Scr->workSpaceMgr.workSpaceList->iconmgr;
727 }
728 else {
729 ip = Scr->iconmgr;
730 }
731 }
732
733 /* IM's exist in all workspaces, so loop through WSen */
734 tmp = NULL;
735 old = tmp_win->iconmanagerlist;
736 while(ip != NULL) {
737 int h;
738 unsigned long valuemask; /* mask for create windows */
739 XSetWindowAttributes attributes; /* attributes for create windows */
740
741 /* Is the window in this workspace? */
742 if((tmp_win->occupation & ip->twm_win->occupation) == 0) {
743 /* Nope, skip onward */
744 ip = ip->nextv;
745 continue;
746 }
747
748 /* Yep, create entry and stick it in */
749 tmp = calloc(1, sizeof(WList));
750 tmp->iconmgr = ip;
751 tmp->twm = tmp_win;
752
754
755 /* IM color settings, shared worldwide */
756 tmp->cp.fore = Scr->IconManagerC.fore;
757 tmp->cp.back = Scr->IconManagerC.back;
758 tmp->highlight = Scr->IconManagerHighlight;
759
760 GetColorFromList(Scr->IconManagerFL, tmp_win->name,
761 &tmp_win->class, &tmp->cp.fore);
762 GetColorFromList(Scr->IconManagerBL, tmp_win->name,
763 &tmp_win->class, &tmp->cp.back);
764 GetColorFromList(Scr->IconManagerHighlightL, tmp_win->name,
765 &tmp_win->class, &tmp->highlight);
766
767 /*
768 * If we're using 3d icon managers, each line item has its own
769 * icon; see comment on creation function for details. With 2d
770 * icon managers, it's the same for all of them, so it's stored
771 * screen-wide.
772 */
773 if(Scr->use3Diconmanagers) {
774 if(!Scr->BeNiceToColormap) {
775 GetShadeColors(&tmp->cp);
776 }
777 tmp->iconifypm = Create3DIconManagerIcon(tmp->cp);
778 }
779
780 /* Refigure the height of the whole IM */
781 h = Scr->IconManagerFont.avg_height
783 if(h < (im_iconified_icon_height + 4)) {
785 }
786
787 ip->height = h * ip->count;
788 tmp->me = ip->count;
789 tmp->x = -1;
790 tmp->y = -1;
791 tmp->height = -1;
792 tmp->width = -1;
793
794
795 /* Make a window for this row in the IM */
797 attributes.background_pixel = tmp->cp.back;
798 attributes.border_pixel = tmp->cp.back;
799 attributes.event_mask = (KeyPressMask | ButtonPressMask |
801 if(Scr->IconManagerFocus) {
803 }
804 attributes.cursor = Scr->IconMgrCursor;
805 tmp->w = XCreateWindow(dpy, ip->w, 0, 0, 1,
806 h, 0,
810
811
812 /* Setup the icon for it too */
814 attributes.background_pixel = tmp->cp.back;
815 attributes.border_pixel = Scr->Black;
817 | ExposureMask);
818 attributes.cursor = Scr->ButtonCursor;
819 /* The precise location will be set it in PackIconManager. */
820 tmp->icon = XCreateWindow(dpy, tmp->w, 0, 0,
827
828
829 /* Bump housekeeping for the IM */
830 ip->count += 1;
832 if(Scr->WindowMask) {
833 XRaiseWindow(dpy, Scr->WindowMask);
834 }
835 XMapWindow(dpy, tmp->w);
836
841
842 if(!ip->twm_win->isicon) {
843 if(visible(ip->twm_win)) {
844 SetMapStateProp(ip->twm_win, NormalState);
845 XMapWindow(dpy, ip->w);
846 XMapWindow(dpy, ip->twm_win->frame);
847 }
848 ip->twm_win->mapped = true;
849 }
850
851
852 /*
853 * Stick this entry on the head of our list of "IM entries we
854 * created", and loop around to the next WS for this IM.
855 */
856 tmp->nextv = old;
857 old = tmp;
858 ip = ip->nextv;
859 }
860
861 /* If we didn't create at least one thing, we're done here */
862 if(tmp == NULL) {
863 return NULL;
864 }
865
866 /* Stash where the window is IM-listed */
867 tmp_win->iconmanagerlist = tmp;
868
869 /* ??? */
870 if(! visible(tmp->iconmgr->twm_win)) {
871 old = tmp;
872 tmp = tmp->nextv;
873 while(tmp != NULL) {
874 if(visible(tmp->iconmgr->twm_win)) {
875 break;
876 }
877 old = tmp;
878 tmp = tmp->nextv;
879 }
880 if(tmp != NULL) {
881 old->nextv = tmp->nextv;
882 tmp->nextv = tmp_win->iconmanagerlist;
883 tmp_win->iconmanagerlist = tmp;
884 }
885 }
886
887 /* Hand back the list places we added */
888 return tmp_win->iconmanagerlist;
889}
890
891/***********************************************************************
892 *
893 * Procedure:
894 * InsertInIconManager - put an allocated entry into an icon
895 * manager
896 *
897 * Inputs:
898 * ip - the icon manager pointer
899 * tmp - the entry to insert
900 *
901 ***********************************************************************
902 */
903
905{
906 WList *tmp1;
907 bool added;
908
909 added = false;
910 if(ip->first == NULL) {
911 ip->first = tmp;
912 tmp->prev = NULL;
913 ip->last = tmp;
914 added = true;
915 }
916 else if(Scr->SortIconMgr) {
917 for(tmp1 = ip->first; tmp1 != NULL; tmp1 = tmp1->next) {
918 int compresult;
919 if(Scr->CaseSensitive) {
920 compresult = strcmp(tmp_win->icon_name, tmp1->twm->icon_name);
921 }
922 else {
923 compresult = strcasecmp(tmp_win->icon_name, tmp1->twm->icon_name);
924 }
925 if(compresult < 0) {
926 tmp->next = tmp1;
927 tmp->prev = tmp1->prev;
928 tmp1->prev = tmp;
929 if(tmp->prev == NULL) {
930 ip->first = tmp;
931 }
932 else {
933 tmp->prev->next = tmp;
934 }
935 added = true;
936 break;
937 }
938 }
939 }
940
941 if(!added) {
942 ip->last->next = tmp;
943 tmp->prev = ip->last;
944 ip->last = tmp;
945 }
946}
947
949{
950 if(tmp->prev == NULL) {
951 ip->first = tmp->next;
952 }
953 else {
954 tmp->prev->next = tmp->next;
955 }
956
957 if(tmp->next == NULL) {
958 ip->last = tmp->prev;
959 }
960 else {
961 tmp->next->prev = tmp->prev;
962 }
963
964 /* pebl: If the list was the current and tmp was the last in the list
965 reset current list */
966 if(Current == tmp) {
967 Current = ip->first;
968 }
969}
970
971/***********************************************************************
972 *
973 * Procedure:
974 * RemoveIconManager - remove a window from the icon manager
975 *
976 * Inputs:
977 * tmp_win - the TwmWindow structure
978 *
979 ***********************************************************************
980 */
981
983{
984 IconMgr *ip;
985 WList *tmp, *tmp1, *save;
986
987 if(tmp_win->iconmanagerlist == NULL) {
988 return;
989 }
990
991 tmp = tmp_win->iconmanagerlist;
992 tmp1 = NULL;
993
994 while(tmp != NULL) {
995 ip = tmp->iconmgr;
996 if((tmp_win->occupation & ip->twm_win->occupation) != 0) {
997 tmp1 = tmp;
998 tmp = tmp->nextv;
999 continue;
1000 }
1002
1005 XDestroyWindow(dpy, tmp->icon);
1008 XDestroyWindow(dpy, tmp->w);
1009 ip->count -= 1;
1010
1012
1013 if(ip->count == 0) {
1014 XUnmapWindow(dpy, ip->twm_win->frame);
1015 ip->twm_win->mapped = false;
1016 }
1017 if(tmp1 == NULL) {
1018 tmp_win->iconmanagerlist = tmp_win->iconmanagerlist->nextv;
1019 }
1020 else {
1021 tmp1->nextv = tmp->nextv;
1022 }
1023
1024 save = tmp;
1025 tmp = tmp->nextv;
1026 free(save);
1027 }
1028}
1029
1034
1036{
1037 active->active = true;
1038 Active = active;
1039 Active->iconmgr->active = active;
1040 Current = Active;
1041 DrawIconManagerBorder(active, false);
1042}
1043
1045{
1046 active->active = false;
1047 DrawIconManagerBorder(active, false);
1048}
1049
1051{
1052 if(Scr->use3Diconmanagers) {
1053 Draw3DBorder(tmp->w, 0, 0, tmp->width, tmp->height,
1054 Scr->IconManagerShadowDepth, tmp->cp,
1055 (tmp->active && Scr->Highlight ? on : off),
1056 fill, false);
1057 }
1058 else {
1059 XSetForeground(dpy, Scr->NormalGC, tmp->cp.fore);
1060 XDrawRectangle(dpy, tmp->w, Scr->NormalGC, 2, 2, tmp->width - 5,
1061 tmp->height - 5);
1062
1063 XSetForeground(dpy, Scr->NormalGC,
1064 (tmp->active && Scr->Highlight
1065 ? tmp->highlight : tmp->cp.back));
1066
1067 XDrawRectangle(dpy, tmp->w, Scr->NormalGC, 0, 0, tmp->width - 1,
1068 tmp->height - 1);
1069 XDrawRectangle(dpy, tmp->w, Scr->NormalGC, 1, 1, tmp->width - 3,
1070 tmp->height - 3);
1071 }
1072}
1073
1074/***********************************************************************
1075 *
1076 * Procedure:
1077 * SortIconManager - sort the dude
1078 *
1079 * Inputs:
1080 * ip - a pointer to the icon manager struture
1081 *
1082 ***********************************************************************
1083 */
1084
1086{
1087 WList *tmp1, *tmp2;
1088 int done;
1089
1090 if(ip == NULL) {
1091 ip = Active->iconmgr;
1092 }
1093
1094 done = false;
1095 do {
1096 for(tmp1 = ip->first; tmp1 != NULL; tmp1 = tmp1->next) {
1097 int compresult;
1098 if((tmp2 = tmp1->next) == NULL) {
1099 done = true;
1100 break;
1101 }
1102 if(Scr->CaseSensitive) {
1103 compresult = strcmp(tmp1->twm->icon_name, tmp2->twm->icon_name);
1104 }
1105 else {
1106 compresult = strcasecmp(tmp1->twm->icon_name, tmp2->twm->icon_name);
1107 }
1108 if(compresult > 0) {
1109 /* take it out and put it back in */
1112 break;
1113 }
1114 }
1115 }
1116 while(!done);
1118}
1119
1120/***********************************************************************
1121 *
1122 * Procedure:
1123 * PackIconManager - pack the icon manager windows following
1124 * an addition or deletion
1125 *
1126 * Inputs:
1127 * ip - a pointer to the icon manager struture
1128 *
1129 ***********************************************************************
1130 */
1131
1133{
1134 TwmWindow *twm_win;
1135
1136 for(twm_win = Scr->FirstWindow; twm_win != NULL; twm_win = twm_win->next) {
1137 if(twm_win->iconmgrp) {
1138 PackIconManager(twm_win->iconmgrp);
1139 }
1140 }
1141}
1142
1144{
1145 int newwidth, i, row, col, maxcol, colinc, rowinc, wheight, wwidth;
1146 int new_x, new_y;
1147 int savewidth;
1148 WList *tmp;
1149 int mask;
1150
1151 wheight = Scr->IconManagerFont.avg_height
1153 if(wheight < (im_iconified_icon_height + 4)) {
1154 wheight = im_iconified_icon_height + 4;
1155 }
1156
1157 wwidth = ip->width / ip->columns;
1158
1159 rowinc = wheight;
1160 colinc = wwidth;
1161
1162 row = 0;
1163 col = ip->columns;
1164 maxcol = 0;
1165 for(i = 0, tmp = ip->first; tmp != NULL; i++, tmp = tmp->next) {
1166 tmp->me = i;
1167 if(++col >= ip->columns) {
1168 col = 0;
1169 row += 1;
1170 }
1171 if(col > maxcol) {
1172 maxcol = col;
1173 }
1174
1175 new_x = col * colinc;
1176 new_y = (row - 1) * rowinc;
1177
1178 /* if the position or size has not changed, don't touch it */
1179 if(tmp->x != new_x || tmp->y != new_y ||
1180 tmp->width != wwidth || tmp->height != wheight) {
1181 XMoveResizeWindow(dpy, tmp->w, new_x, new_y, wwidth, wheight);
1182 if(tmp->height != wheight)
1184 (wheight - im_iconified_icon_height) / 2);
1185
1186 tmp->row = row - 1;
1187 tmp->col = col;
1188 tmp->x = new_x;
1189 tmp->y = new_y;
1190 tmp->width = wwidth;
1191 tmp->height = wheight;
1192 }
1193 }
1194 maxcol += 1;
1195
1196 ip->cur_rows = row;
1197 ip->cur_columns = maxcol;
1198 ip->height = row * rowinc;
1199 if(ip->height == 0) {
1200 ip->height = rowinc;
1201 }
1203 if(newwidth == 0) {
1204 newwidth = colinc;
1205 }
1206
1207 XResizeWindow(dpy, ip->w, newwidth, ip->height);
1208
1209 mask = RLayoutXParseGeometry(Scr->Layout, ip->geometry, &JunkX, &JunkY,
1211 if(mask & XNegative) {
1212 ip->twm_win->frame_x += ip->twm_win->frame_width - newwidth -
1213 2 * ip->twm_win->frame_bw3D;
1214 }
1215 if(mask & YNegative) {
1216 ip->twm_win->frame_y += ip->twm_win->frame_height - ip->height -
1217 2 * ip->twm_win->frame_bw3D - ip->twm_win->title_height;
1218 }
1219 savewidth = ip->width;
1220 if(ip->twm_win)
1221 SetupWindow(ip->twm_win,
1222 ip->twm_win->frame_x, ip->twm_win->frame_y,
1223 newwidth + 2 * ip->twm_win->frame_bw3D,
1224 ip->height + ip->twm_win->title_height + 2 * ip->twm_win->frame_bw3D, -1);
1225 ip->width = savewidth;
1226}
1227
1228void dump_iconmanager(IconMgr *mgr, char *label)
1229{
1230 fprintf(stderr, "IconMgr %s %p name='%s' geom='%s'\n",
1231 label,
1232 mgr,
1233 mgr->name,
1234 mgr->geometry);
1235 fprintf(stderr, "next = %p, prev = %p, lasti = %p, nextv = %p\n",
1236 mgr->next,
1237 mgr->prev,
1238 mgr->lasti,
1239 mgr->nextv);
1240}
1241
1242
1243/*
1244 * Draw the window name into the icon manager line
1245 */
1246void
1248{
1249 WList *iconmanagerlist = tmp_win->iconmanagerlist;
1251
1252 XmbTextExtents(Scr->IconManagerFont.font_set,
1253 tmp_win->icon_name, strlen(tmp_win->icon_name),
1255
1256 if(UpdateFont(&Scr->IconManagerFont, logical_rect.height)) {
1258 }
1259
1260 // Write in the title
1261 FB(iconmanagerlist->cp.fore, iconmanagerlist->cp.back);
1262
1263 /* XXX This is a completely absurd way of writing this */
1264 ((Scr->use3Diconmanagers && (Scr->Monochrome != COLOR)) ?
1266 (dpy,
1267 iconmanagerlist->w,
1268 Scr->IconManagerFont.font_set,
1269 Scr->NormalGC,
1271 (Scr->IconManagerFont.avg_height - logical_rect.height) / 2
1272 + (- logical_rect.y)
1275 tmp_win->icon_name,
1276 strlen(tmp_win->icon_name));
1277
1278 // Draw the border around it. Our "border" isn't an X border, it's
1279 // just our own drawing inside the X window. Since XmbDrawString()
1280 // believes it has all the space in the window to fill, it might
1281 // scribble into the space where we're drawing the border, so draw
1282 // the border after the text to cover it up.
1283 DrawIconManagerBorder(iconmanagerlist, false);
1284}
1285
1286
1287/*
1288 * Copy the icon into the icon manager for a window that's iconified.
1289 * This is slightly different for the 3d vs 2d case, since the 3d is just
1290 * copying a pixmap in, while the 2d is drawing a bitmap in with the
1291 * fg/bg colors appropriate to the line.
1292 */
1293void
1295{
1296 WList *iconmanagerlist = tmp_win->iconmanagerlist;
1297
1298 if(Scr->use3Diconmanagers && iconmanagerlist->iconifypm) {
1299 XCopyArea(dpy, iconmanagerlist->iconifypm,
1300 iconmanagerlist->icon,
1301 Scr->NormalGC, 0, 0,
1303 }
1304 else {
1305 FB(iconmanagerlist->cp.fore, iconmanagerlist->cp.back);
1306 XCopyPlane(dpy, Scr->siconifyPm, iconmanagerlist->icon,
1307 Scr->NormalGC, 0, 0,
1309 }
1310}
void GrabButtons(TwmWindow *tmp_win)
static int PlaceX
Definition add_window.c:82
void GrabKeys(TwmWindow *tmp_win)
TwmWindow * AddWindow(Window w, AWType wtype, IconMgr *iconp, VirtualScreen *vs)
Definition add_window.c:113
@ AWT_ICON_MANAGER
Definition add_window.h:25
int JunkY
Definition ctwm.h:358
char * ProgramName
Definition ctwm_main.c:146
unsigned int JunkWidth
Definition ctwm_main.c:144
XContext ScreenContext
Definition ctwm_main.c:121
int JunkX
Definition ctwm_main.c:143
Display * dpy
Definition ctwm_main.c:84
XContext TwmContext
Definition ctwm_main.c:119
#define FB(fix_fore, fix_back)
Definition ctwm.h:119
unsigned int JunkHeight
Definition ctwm.h:359
int NumScreens
How many Screens are on our display.
Definition ctwm_main.c:89
#define Scr
ScreenInfo ** ScreenList
List of ScreenInfo structs for each Screen.
Definition ctwm_main.c:92
void Draw3DBorder(Window w, int x, int y, int width, int height, int bw, ColorPair cp, ButtonState state, bool fill, bool forcebw)
Definition drawing.c:34
@ off
Definition drawing.h:8
@ on
Definition drawing.h:8
void NotActiveIconManager(WList *active)
Definition iconmgr.c:1044
IconMgr * AllocateIconManager(char *name, char *icon_name, char *geom, int columns)
Definition iconmgr.c:266
void JumpIconManager(int dir)
Definition iconmgr.c:621
static int iconmgr_textx
Definition iconmgr.c:50
void PackIconManagers(void)
Definition iconmgr.c:1132
void AllocateOtherIconManagers(void)
Definition iconmgr.c:316
WList * DownIconManager
Definition iconmgr.c:54
void MoveIconManager(int dir)
Definition iconmgr.c:405
void DrawIconManagerBorder(WList *tmp, bool fill)
Definition iconmgr.c:1050
void CreateIconManagers(void)
Definition iconmgr.c:71
void RemoveIconManager(TwmWindow *tmp_win)
Definition iconmgr.c:982
void ActiveIconManager(WList *active)
Definition iconmgr.c:1035
void InsertInIconManager(IconMgr *ip, WList *tmp, TwmWindow *tmp_win)
Definition iconmgr.c:904
#define IPOFSP(sp)
void RemoveFromIconManager(IconMgr *ip, WList *tmp)
Definition iconmgr.c:948
void dump_iconmanager(IconMgr *mgr, char *label)
Definition iconmgr.c:1228
void ShowIconifiedIcon(TwmWindow *tmp_win)
Definition iconmgr.c:1294
#define ITER(i)
void CurrentIconManagerEntry(WList *current)
Definition iconmgr.c:1030
void DrawIconManagerIconName(TwmWindow *tmp_win)
Definition iconmgr.c:1247
void SortIconManager(IconMgr *ip)
Definition iconmgr.c:1085
static WList * Active
Definition iconmgr.c:52
#define TEST(ip)
WList * AddIconManager(TwmWindow *tmp_win)
Definition iconmgr.c:697
void MoveMappedIconManager(int dir)
Definition iconmgr.c:537
void PackIconManager(IconMgr *ip)
Definition iconmgr.c:1143
static WList * Current
Definition iconmgr.c:53
#define ICON_MGR_IBORDER
Definition iconmgr.h:83
#define ICON_MGR_OBORDER
Definition iconmgr.h:85
const unsigned int im_iconified_icon_width
Pixmap Create2DIconManagerIcon(void)
Pixmap Create3DIconManagerIcon(ColorPair cp)
const unsigned int im_iconified_icon_height
bool GetColorFromList(name_list *list_head, char *name, XClassHint *class, Pixel *ptr)
Definition list.c:194
void * LookInList(name_list *list_head, const char *name, XClassHint *class)
Definition list.c:101
int x
Definition menus.c:69
void OtpRaise(TwmWindow *twm_win, WinType wintype)
Definition otp.c:763
@ WinWin
Definition otp.h:14
Pixel back
Definition ctwm.h:141
Pixel fore
Definition ctwm.h:141
struct IconMgr * nextv
Next workspace's icon manager head.
Definition iconmgr.h:40
struct WList * active
Definition iconmgr.h:44
struct WList * first
Definition iconmgr.h:42
struct IconMgr * next
Next iconmgr in this workspace.
Definition iconmgr.h:37
Info and control for each X Screen we control.
Definition screen.h:96
Info and control for every X Window we take over.
struct TwmWindow * next
Next TwmWindow on the Screen.
struct IconMgr * iconmgrp
Pointer to the icon manager structure, for windows that are icon managers.
bool active
Definition iconmgr.h:32
Pixmap iconifypm
Definition iconmgr.h:30
struct IconMgr * iconmgr
Definition iconmgr.h:22
Window icon
Definition iconmgr.h:24
struct WList * next
Definition iconmgr.h:18
int row
Definition iconmgr.h:26
int width
Definition iconmgr.h:25
struct WList * prev
Definition iconmgr.h:19
int col
Definition iconmgr.h:26
Window w
Definition iconmgr.h:23
ColorPair cp
Definition iconmgr.h:28
IconMgr * iconmgr
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 SetupWindow(TwmWindow *tmp_win, int x, int y, int w, int h, int bw)
bool visible(const TwmWindow *tmp_win)
Definition win_utils.c:341
void SetMapStateProp(TwmWindow *tmp_win, int state)
Definition win_utils.c:415
int RLayoutXParseGeometry(RLayout *layout, const char *geometry, int *x, int *y, unsigned int *width, unsigned int *height)
Parse an X Geometry out to get the positions and sizes.