iconmgr.c revision 0bbfda8a
1645f5050Syouri/* 2645f5050Syouri * Copyright 1989 Massachusetts Institute of Technology 30bbfda8aSnia * Copyright 1992 Claude Lecommandeur. 4645f5050Syouri */ 5645f5050Syouri 6645f5050Syouri/*********************************************************************** 7645f5050Syouri * 8645f5050Syouri * $XConsortium: iconmgr.c,v 1.48 91/09/10 15:27:07 dave Exp $ 9645f5050Syouri * 10645f5050Syouri * Icon Manager routines 11645f5050Syouri * 120bbfda8aSnia * 09-Mar-89 Tom LaStrange File Created 13645f5050Syouri * 14645f5050Syouri * Do the necessary modification to be integrated in ctwm. 15645f5050Syouri * Can no longer be used for the standard twm. 16645f5050Syouri * 17645f5050Syouri * 22-April-92 Claude Lecommandeur. 18645f5050Syouri * 19645f5050Syouri * 20645f5050Syouri ***********************************************************************/ 21645f5050Syouri 220bbfda8aSnia#include "ctwm.h" 230bbfda8aSnia 24645f5050Syouri#include <stdio.h> 250bbfda8aSnia#include <stdlib.h> 260bbfda8aSnia#include <string.h> 270bbfda8aSnia#include <strings.h> 280bbfda8aSnia 29645f5050Syouri#include <X11/Xatom.h> 300bbfda8aSnia 31645f5050Syouri#include "util.h" 320bbfda8aSnia#include "iconmgr.h" 330bbfda8aSnia#include "icons_builtin.h" 34645f5050Syouri#include "screen.h" 350bbfda8aSnia#include "drawing.h" 360bbfda8aSnia#include "functions_defs.h" 370bbfda8aSnia#include "list.h" 380bbfda8aSnia#include "occupation.h" 390bbfda8aSnia#include "otp.h" 40645f5050Syouri#include "add_window.h" 410bbfda8aSnia#include "gram.tab.h" 420bbfda8aSnia#include "win_decorations.h" 430bbfda8aSnia#include "win_resize.h" 440bbfda8aSnia#include "win_utils.h" 450bbfda8aSnia 460bbfda8aSnia 470bbfda8aSnia/* Where we start drawing the name in the icon manager */ 480bbfda8aSniastatic int iconmgr_textx; 49645f5050Syouri 500bbfda8aSniastatic WList *Active = NULL; 510bbfda8aSniastatic WList *Current = NULL; 52645f5050SyouriWList *DownIconManager = NULL; 53645f5050Syouri 54645f5050Syouri/*********************************************************************** 55645f5050Syouri * 56645f5050Syouri * Procedure: 570bbfda8aSnia * CreateIconManagers - creat all the icon manager windows 580bbfda8aSnia * for this screen. 59645f5050Syouri * 60645f5050Syouri * Returned Value: 610bbfda8aSnia * none 62645f5050Syouri * 63645f5050Syouri * Inputs: 640bbfda8aSnia * none 65645f5050Syouri * 66645f5050Syouri *********************************************************************** 67645f5050Syouri */ 68645f5050Syouri 69645f5050Syourivoid CreateIconManagers(void) 70645f5050Syouri{ 710bbfda8aSnia WorkSpace *ws; 720bbfda8aSnia 730bbfda8aSnia if(Scr->NoIconManagers) { 740bbfda8aSnia return; 750bbfda8aSnia } 760bbfda8aSnia 770bbfda8aSnia /* 780bbfda8aSnia * Move past the iconified icon to start the text. 790bbfda8aSnia * XXX Semi-arbitrary magic add'l padding, to deal with various inner 800bbfda8aSnia * positioning of the icon subwindow. Be smarter (or at least 810bbfda8aSnia * clearer) about this... 820bbfda8aSnia */ 830bbfda8aSnia iconmgr_textx = im_iconified_icon_width + 11; 840bbfda8aSnia if(Scr->use3Diconmanagers) { 850bbfda8aSnia iconmgr_textx += Scr->IconManagerShadowDepth; 860bbfda8aSnia } 870bbfda8aSnia 880bbfda8aSnia if(Scr->siconifyPm == None) { 890bbfda8aSnia Scr->siconifyPm = Create2DIconManagerIcon(); 900bbfda8aSnia } 910bbfda8aSnia 920bbfda8aSnia ws = Scr->workSpaceMgr.workSpaceList; 930bbfda8aSnia for(IconMgr *q = Scr->iconmgr; q != NULL; q = q->nextv) { 940bbfda8aSnia for(IconMgr *p = q; p != NULL; p = p->next) { 950bbfda8aSnia int gx, gy; 960bbfda8aSnia char imname[100]; 970bbfda8aSnia int mask; 980bbfda8aSnia int gravity; 990bbfda8aSnia int bw; 1000bbfda8aSnia Pixel background; 1010bbfda8aSnia 1020bbfda8aSnia snprintf(imname, sizeof(imname), "%s Icon Manager", p->name); 1030bbfda8aSnia 1040bbfda8aSnia if(!p->geometry || !strlen(p->geometry)) { 1050bbfda8aSnia p->geometry = "+0+0"; 1060bbfda8aSnia } 1070bbfda8aSnia mask = XParseGeometry(p->geometry, &gx, &gy, 1080bbfda8aSnia (unsigned int *) &p->width, (unsigned int *)&p->height); 1090bbfda8aSnia 1100bbfda8aSnia bw = LookInList(Scr->NoBorder, imname, NULL) ? 0 : 1110bbfda8aSnia (Scr->ThreeDBorderWidth ? Scr->ThreeDBorderWidth : Scr->BorderWidth); 1120bbfda8aSnia 1130bbfda8aSnia if(mask & XNegative) { 1140bbfda8aSnia gx += Scr->rootw - p->width - 2 * bw; 1150bbfda8aSnia gravity = (mask & YNegative) ? SouthEastGravity : NorthEastGravity; 1160bbfda8aSnia } 1170bbfda8aSnia else { 1180bbfda8aSnia gravity = (mask & YNegative) ? SouthWestGravity : NorthWestGravity; 1190bbfda8aSnia } 1200bbfda8aSnia if(mask & YNegative) { 1210bbfda8aSnia gy += Scr->rooth - p->height - 2 * bw; 1220bbfda8aSnia } 1230bbfda8aSnia 1240bbfda8aSnia background = Scr->IconManagerC.back; 1250bbfda8aSnia GetColorFromList(Scr->IconManagerBL, p->name, NULL, 1260bbfda8aSnia &background); 1270bbfda8aSnia 1280bbfda8aSnia if(p->width < 1) { 1290bbfda8aSnia p->width = 1; 1300bbfda8aSnia } 1310bbfda8aSnia if(p->height < 1) { 1320bbfda8aSnia p->height = 1; 1330bbfda8aSnia } 1340bbfda8aSnia p->w = XCreateSimpleWindow(dpy, Scr->Root, 1350bbfda8aSnia gx, gy, p->width, p->height, 1, 1360bbfda8aSnia Scr->Black, background); 1370bbfda8aSnia 1380bbfda8aSnia 1390bbfda8aSnia /* Scr->workSpaceMgr.activeWSPC = ws; */ 1400bbfda8aSnia 1410bbfda8aSnia /* Setup various WM properties on the iconmgr's window */ 1420bbfda8aSnia { 1430bbfda8aSnia char *icon_name; 1440bbfda8aSnia XWMHints wmhints; 1450bbfda8aSnia XClassHint clhints; 1460bbfda8aSnia 1470bbfda8aSnia if(p->icon_name) { 1480bbfda8aSnia icon_name = strdup(p->icon_name); 1490bbfda8aSnia } 1500bbfda8aSnia else { 1510bbfda8aSnia asprintf(&icon_name, "%s Icons", p->name); 1520bbfda8aSnia } 1530bbfda8aSnia 1540bbfda8aSnia wmhints.initial_state = NormalState; 1550bbfda8aSnia wmhints.input = True; 1560bbfda8aSnia wmhints.flags = InputHint | StateHint; 1570bbfda8aSnia 1580bbfda8aSnia clhints.res_name = icon_name; 1590bbfda8aSnia clhints.res_class = "TwmIconManager"; 1600bbfda8aSnia 1610bbfda8aSnia XmbSetWMProperties(dpy, p->w, imname, icon_name, NULL, 0, NULL, 1620bbfda8aSnia &wmhints, &clhints); 1630bbfda8aSnia free(icon_name); 1640bbfda8aSnia } 1650bbfda8aSnia 1660bbfda8aSnia 1670bbfda8aSnia p->twm_win = AddWindow(p->w, AWT_ICON_MANAGER, p, Scr->currentvs); 1680bbfda8aSnia /* 1690bbfda8aSnia * SetupOccupation() called from AddWindow() doesn't setup 1700bbfda8aSnia * occupation for icon managers, nor clear vs if occupation lacks. 1710bbfda8aSnia * 1720bbfda8aSnia * There is no Scr->currentvs->wsw->currentwspc set up this 1730bbfda8aSnia * early, so we can't check with that; the best check we can do 1740bbfda8aSnia * is use ws->number. This may be incorrect when re-starting 1750bbfda8aSnia * ctwm. 1760bbfda8aSnia */ 1770bbfda8aSnia if(ws) { 1780bbfda8aSnia p->twm_win->occupation = 1 << ws->number; 1790bbfda8aSnia if(ws->number > 0) { 1800bbfda8aSnia p->twm_win->vs = NULL; 1810bbfda8aSnia } 1820bbfda8aSnia } 1830bbfda8aSnia else { 1840bbfda8aSnia p->twm_win->occupation = 1; 1850bbfda8aSnia } 1860bbfda8aSnia#ifdef DEBUG_ICONMGR 1870bbfda8aSnia fprintf(stderr, 1880bbfda8aSnia "CreateIconManagers: IconMgr %p: x=%d y=%d w=%d h=%d occupation=%x\n", 1890bbfda8aSnia p, gx, gy, p->width, p->height, p->twm_win->occupation); 1900bbfda8aSnia#endif 1910bbfda8aSnia 1920bbfda8aSnia { 1930bbfda8aSnia XSizeHints sizehints; 1940bbfda8aSnia 1950bbfda8aSnia sizehints.flags = PWinGravity; 1960bbfda8aSnia sizehints.win_gravity = gravity; 1970bbfda8aSnia XSetWMSizeHints(dpy, p->w, &sizehints, XA_WM_NORMAL_HINTS); 1980bbfda8aSnia } 1990bbfda8aSnia 2000bbfda8aSnia p->twm_win->mapped = false; 2010bbfda8aSnia SetMapStateProp(p->twm_win, WithdrawnState); 2020bbfda8aSnia if(p->twm_win && (p->twm_win->wmhints->initial_state == IconicState)) { 2030bbfda8aSnia p->twm_win->isicon = true; 2040bbfda8aSnia } 2050bbfda8aSnia else if(!Scr->NoIconManagers && Scr->ShowIconManager) { 2060bbfda8aSnia p->twm_win->isicon = false; 2070bbfda8aSnia } 2080bbfda8aSnia else { 2090bbfda8aSnia p->twm_win->isicon = true; 2100bbfda8aSnia } 2110bbfda8aSnia } 2120bbfda8aSnia if(ws != NULL) { 2130bbfda8aSnia ws = ws->next; 2140bbfda8aSnia } 2150bbfda8aSnia } 2160bbfda8aSnia 2170bbfda8aSnia if(Scr->workSpaceManagerActive) { 2180bbfda8aSnia Scr->workSpaceMgr.workSpaceList->iconmgr = Scr->iconmgr; 2190bbfda8aSnia } 2200bbfda8aSnia 2210bbfda8aSnia 2220bbfda8aSnia /* 2230bbfda8aSnia * Grab buttons/keystrokes for icon managers appropriately. 2240bbfda8aSnia * Normally, this is done in AddWindow(), but it explicitly skips it 2250bbfda8aSnia * for icon managers. It's not at all clear why GrabButtons() would 2260bbfda8aSnia * do so; I don't think it needs to. GrabKeys() does do some looping 2270bbfda8aSnia * over the Scr->iconmgr list at the end though, so it's possible we 2280bbfda8aSnia * need to delay calling it until now when the list is all filled up. 2290bbfda8aSnia * This needs further investigation; it may be that the special case 2300bbfda8aSnia * and this code can be removed. X-ref comments in add_window.c 2310bbfda8aSnia * about it. 2320bbfda8aSnia */ 2330bbfda8aSnia for(IconMgr *q = Scr->iconmgr; q != NULL; q = q->nextv) { 2340bbfda8aSnia for(IconMgr *p = q; p != NULL; p = p->next) { 2350bbfda8aSnia GrabButtons(p->twm_win); 2360bbfda8aSnia GrabKeys(p->twm_win); 2370bbfda8aSnia } 238645f5050Syouri } 239645f5050Syouri 240645f5050Syouri} 241645f5050Syouri 242645f5050Syouri/*********************************************************************** 243645f5050Syouri * 244645f5050Syouri * Procedure: 2450bbfda8aSnia * AllocateIconManager - allocate a new icon manager 246645f5050Syouri * 247645f5050Syouri * Inputs: 2480bbfda8aSnia * name - the name of this icon manager 2490bbfda8aSnia * icon_name - the name of the associated icon 2500bbfda8aSnia * geom - a geometry string to eventually parse 2510bbfda8aSnia * columns - the number of columns this icon manager has 252645f5050Syouri * 253645f5050Syouri *********************************************************************** 254645f5050Syouri */ 255645f5050Syouri 256645f5050SyouriIconMgr *AllocateIconManager(char *name, char *icon_name, char *geom, 2570bbfda8aSnia int columns) 258645f5050Syouri{ 2590bbfda8aSnia IconMgr *p; 260645f5050Syouri 261645f5050Syouri#ifdef DEBUG_ICONMGR 2620bbfda8aSnia fprintf(stderr, "AllocateIconManager\n"); 2630bbfda8aSnia fprintf(stderr, " name=\"%s\" icon_name=\"%s\", geom=\"%s\", col=%d\n", 2640bbfda8aSnia name, icon_name, geom, columns); 265645f5050Syouri#endif 266645f5050Syouri 2670bbfda8aSnia if(Scr->NoIconManagers) { 2680bbfda8aSnia return NULL; 2690bbfda8aSnia } 2700bbfda8aSnia 2710bbfda8aSnia if(columns < 1) { 2720bbfda8aSnia columns = 1; 2730bbfda8aSnia } 2740bbfda8aSnia p = calloc(1, sizeof(IconMgr)); 2750bbfda8aSnia p->name = name; 2760bbfda8aSnia p->icon_name = icon_name; 2770bbfda8aSnia p->geometry = geom; 2780bbfda8aSnia p->columns = columns; 2790bbfda8aSnia p->scr = Scr; 2800bbfda8aSnia p->width = 150; 2810bbfda8aSnia p->height = 10; 2820bbfda8aSnia 2830bbfda8aSnia if(Scr->iconmgr == NULL) { 2840bbfda8aSnia Scr->iconmgr = p; 2850bbfda8aSnia Scr->iconmgr->lasti = p; 2860bbfda8aSnia } 2870bbfda8aSnia else { 2880bbfda8aSnia Scr->iconmgr->lasti->next = p; 2890bbfda8aSnia p->prev = Scr->iconmgr->lasti; 2900bbfda8aSnia Scr->iconmgr->lasti = p; 2910bbfda8aSnia } 2920bbfda8aSnia return(p); 2930bbfda8aSnia} 2940bbfda8aSnia 2950bbfda8aSnia 2960bbfda8aSnia/* 2970bbfda8aSnia * Each workspace has its own [set of] icon manager[s]. The initial main 2980bbfda8aSnia * one was setup via AllocateIconManager() early in startup. The others 2990bbfda8aSnia * were setup during parsing the config file. Then this gets called late 3000bbfda8aSnia * in startup, after all the workspaces are setup, to copy them all into 3010bbfda8aSnia * each one. 3020bbfda8aSnia * 3030bbfda8aSnia * Note this is distinct from CreateIconManagers(); that creates and 3040bbfda8aSnia * draws the windows, this creates and connects up the data structures. 3050bbfda8aSnia */ 3060bbfda8aSniavoid AllocateOtherIconManagers(void) 3070bbfda8aSnia{ 3080bbfda8aSnia IconMgr *imfirst; // First IM on each workspace 3090bbfda8aSnia WorkSpace *ws; 3100bbfda8aSnia 3110bbfda8aSnia /* No defined workspaces? Nothing to do. */ 3120bbfda8aSnia if(! Scr->workSpaceManagerActive) { 3130bbfda8aSnia return; 3140bbfda8aSnia } 3150bbfda8aSnia 3160bbfda8aSnia /* The first workspace just gets the ones we already have */ 3170bbfda8aSnia ws = Scr->workSpaceMgr.workSpaceList; 3180bbfda8aSnia ws->iconmgr = Scr->iconmgr; 3190bbfda8aSnia 3200bbfda8aSnia /* From the second on, we start copying */ 3210bbfda8aSnia imfirst = ws->iconmgr; 3220bbfda8aSnia for(ws = ws->next; ws != NULL; ws = ws->next) { 3230bbfda8aSnia IconMgr *ip, *previ, *p = NULL; 3240bbfda8aSnia 3250bbfda8aSnia /* Copy in the first iconmgr */ 3260bbfda8aSnia ws->iconmgr = malloc(sizeof(IconMgr)); 3270bbfda8aSnia *ws->iconmgr = *imfirst; 3280bbfda8aSnia 3290bbfda8aSnia /* 3300bbfda8aSnia * This first is now the nextv to the first in the previous WS, 3310bbfda8aSnia * and we don't [yet] have a nextv of our own. 3320bbfda8aSnia * */ 3330bbfda8aSnia imfirst->nextv = ws->iconmgr; 3340bbfda8aSnia ws->iconmgr->nextv = NULL; 3350bbfda8aSnia 3360bbfda8aSnia /* 3370bbfda8aSnia * Start from the second, and copy them each from the prior 3380bbfda8aSnia * workspace we just went through. 3390bbfda8aSnia * */ 3400bbfda8aSnia previ = ws->iconmgr; 3410bbfda8aSnia for(ip = imfirst->next; ip != NULL; ip = ip->next) { 3420bbfda8aSnia /* Copy the base bits */ 3430bbfda8aSnia p = malloc(sizeof(IconMgr)); 3440bbfda8aSnia *p = *ip; 3450bbfda8aSnia 3460bbfda8aSnia /* Link up the double-links, and there's no nextv [yet] */ 3470bbfda8aSnia previ->next = p; 3480bbfda8aSnia p->prev = previ; 3490bbfda8aSnia p->next = NULL; 3500bbfda8aSnia p->nextv = NULL; 3510bbfda8aSnia 3520bbfda8aSnia /* We're now the nextv to that one in the old workspace */ 3530bbfda8aSnia ip->nextv = p; 3540bbfda8aSnia 3550bbfda8aSnia /* And back around to the next one to copy into this WS */ 3560bbfda8aSnia previ = p; 3570bbfda8aSnia } 3580bbfda8aSnia 3590bbfda8aSnia /* Each one has a pointer to the last IM in this WS, so save those */ 3600bbfda8aSnia for(ip = ws->iconmgr; ip != NULL; ip = ip->next) { 3610bbfda8aSnia ip->lasti = p; 3620bbfda8aSnia } 3630bbfda8aSnia 3640bbfda8aSnia /* 3650bbfda8aSnia * And back around to the next workspace, which works from those 3660bbfda8aSnia * we made for this WS. We go from imfirst rather than 3670bbfda8aSnia * Scr->iconmgr so the ip->nextv rewrites are correct above; we 3680bbfda8aSnia * have to fill them in on the next loop. 3690bbfda8aSnia */ 3700bbfda8aSnia imfirst = ws->iconmgr; 3710bbfda8aSnia } 372645f5050Syouri} 373645f5050Syouri 3740bbfda8aSnia 375645f5050Syouri/*********************************************************************** 376645f5050Syouri * 377645f5050Syouri * Procedure: 3780bbfda8aSnia * MoveIconManager - move the pointer around in an icon manager 379645f5050Syouri * 380645f5050Syouri * Inputs: 3810bbfda8aSnia * dir - one of the following: 3820bbfda8aSnia * F_FORWICONMGR - forward in the window list 3830bbfda8aSnia * F_BACKICONMGR - backward in the window list 3840bbfda8aSnia * F_UPICONMGR - up one row 3850bbfda8aSnia * F_DOWNICONMGR - down one row 3860bbfda8aSnia * F_LEFTICONMGR - left one column 3870bbfda8aSnia * F_RIGHTICONMGR - right one column 388645f5050Syouri * 389645f5050Syouri * Special Considerations: 3900bbfda8aSnia * none 391645f5050Syouri * 392645f5050Syouri *********************************************************************** 393645f5050Syouri */ 394645f5050Syouri 395645f5050Syourivoid MoveIconManager(int dir) 396645f5050Syouri{ 3970bbfda8aSnia IconMgr *ip; 3980bbfda8aSnia WList *tmp = NULL; 3990bbfda8aSnia int cur_row, cur_col, new_row, new_col; 4000bbfda8aSnia int row_inc, col_inc; 4010bbfda8aSnia bool got_it; 4020bbfda8aSnia 4030bbfda8aSnia if(!Current) { 4040bbfda8aSnia return; 4050bbfda8aSnia } 4060bbfda8aSnia 4070bbfda8aSnia cur_row = Current->row; 4080bbfda8aSnia cur_col = Current->col; 4090bbfda8aSnia ip = Current->iconmgr; 4100bbfda8aSnia 4110bbfda8aSnia row_inc = 0; 4120bbfda8aSnia col_inc = 0; 4130bbfda8aSnia got_it = false; 4140bbfda8aSnia 4150bbfda8aSnia switch(dir) { 4160bbfda8aSnia case F_FORWICONMGR: 4170bbfda8aSnia if((tmp = Current->next) == NULL) { 4180bbfda8aSnia tmp = ip->first; 4190bbfda8aSnia } 4200bbfda8aSnia got_it = true; 4210bbfda8aSnia break; 4220bbfda8aSnia 4230bbfda8aSnia case F_BACKICONMGR: 4240bbfda8aSnia if((tmp = Current->prev) == NULL) { 4250bbfda8aSnia tmp = ip->last; 4260bbfda8aSnia } 4270bbfda8aSnia got_it = true; 4280bbfda8aSnia break; 4290bbfda8aSnia 4300bbfda8aSnia case F_UPICONMGR: 4310bbfda8aSnia row_inc = -1; 4320bbfda8aSnia break; 4330bbfda8aSnia 4340bbfda8aSnia case F_DOWNICONMGR: 4350bbfda8aSnia row_inc = 1; 4360bbfda8aSnia break; 4370bbfda8aSnia 4380bbfda8aSnia case F_LEFTICONMGR: 4390bbfda8aSnia col_inc = -1; 4400bbfda8aSnia break; 4410bbfda8aSnia 4420bbfda8aSnia case F_RIGHTICONMGR: 4430bbfda8aSnia col_inc = 1; 4440bbfda8aSnia break; 4450bbfda8aSnia } 4460bbfda8aSnia 4470bbfda8aSnia /* If got_it is false ast this point then we got a left, right, 4480bbfda8aSnia * up, or down, command. We will enter this loop until we find 4490bbfda8aSnia * a window to warp to. 450645f5050Syouri */ 4510bbfda8aSnia new_row = cur_row; 4520bbfda8aSnia new_col = cur_col; 4530bbfda8aSnia 4540bbfda8aSnia while(!got_it) { 4550bbfda8aSnia new_row += row_inc; 4560bbfda8aSnia new_col += col_inc; 4570bbfda8aSnia if(new_row < 0) { 4580bbfda8aSnia new_row = ip->cur_rows - 1; 4590bbfda8aSnia } 4600bbfda8aSnia if(new_col < 0) { 4610bbfda8aSnia new_col = ip->cur_columns - 1; 4620bbfda8aSnia } 4630bbfda8aSnia if(new_row >= ip->cur_rows) { 4640bbfda8aSnia new_row = 0; 4650bbfda8aSnia } 4660bbfda8aSnia if(new_col >= ip->cur_columns) { 4670bbfda8aSnia new_col = 0; 4680bbfda8aSnia } 4690bbfda8aSnia 4700bbfda8aSnia /* Now let's go through the list to see if there is an entry with this 4710bbfda8aSnia * new position 4720bbfda8aSnia */ 4730bbfda8aSnia for(tmp = ip->first; tmp != NULL; tmp = tmp->next) { 4740bbfda8aSnia if(tmp->row == new_row && tmp->col == new_col) { 4750bbfda8aSnia got_it = true; 4760bbfda8aSnia break; 4770bbfda8aSnia } 4780bbfda8aSnia } 4790bbfda8aSnia } 4800bbfda8aSnia 4810bbfda8aSnia if(!got_it) { 4820bbfda8aSnia fprintf(stderr, 4830bbfda8aSnia "%s: unable to find window (%d, %d) in icon manager\n", 4840bbfda8aSnia ProgramName, new_row, new_col); 4850bbfda8aSnia return; 4860bbfda8aSnia } 4870bbfda8aSnia 4880bbfda8aSnia if(tmp == NULL) { 4890bbfda8aSnia return; 4900bbfda8aSnia } 4910bbfda8aSnia 4920bbfda8aSnia /* raise the frame so the icon manager is visible */ 4930bbfda8aSnia if(ip->twm_win->mapped) { 4940bbfda8aSnia OtpRaise(ip->twm_win, WinWin); 4950bbfda8aSnia XWarpPointer(dpy, None, tmp->icon, 0, 0, 0, 0, 5, 5); 4960bbfda8aSnia } 4970bbfda8aSnia else { 4980bbfda8aSnia if(tmp->twm->title_height) { 4990bbfda8aSnia int tbx = Scr->TBInfo.titlex; 5000bbfda8aSnia int x = tmp->twm->highlightxr; 5010bbfda8aSnia XWarpPointer(dpy, None, tmp->twm->title_w, 0, 0, 0, 0, 5020bbfda8aSnia tbx + (x - tbx) / 2, 5030bbfda8aSnia Scr->TitleHeight / 4); 5040bbfda8aSnia } 5050bbfda8aSnia else { 5060bbfda8aSnia XWarpPointer(dpy, None, tmp->twm->w, 0, 0, 0, 0, 5, 5); 5070bbfda8aSnia } 5080bbfda8aSnia } 509645f5050Syouri} 510645f5050Syouri 511645f5050Syouri/*********************************************************************** 512645f5050Syouri * 513645f5050Syouri * Procedure: 5140bbfda8aSnia * MoveMappedIconManager - move the pointer around in an icon manager 515645f5050Syouri * 516645f5050Syouri * Inputs: 5170bbfda8aSnia * dir - one of the following: 5180bbfda8aSnia * F_FORWMAPICONMGR - forward in the window list 5190bbfda8aSnia * F_BACKMAPICONMGR - backward in the window list 520645f5050Syouri * 521645f5050Syouri * Special Considerations: 5220bbfda8aSnia * none 523645f5050Syouri * 524645f5050Syouri *********************************************************************** 525645f5050Syouri */ 526645f5050Syouri 527645f5050Syourivoid MoveMappedIconManager(int dir) 528645f5050Syouri{ 5290bbfda8aSnia IconMgr *ip; 5300bbfda8aSnia WList *tmp = NULL; 5310bbfda8aSnia WList *orig = NULL; 5320bbfda8aSnia bool got_it; 5330bbfda8aSnia 5340bbfda8aSnia if(!Current) { 5350bbfda8aSnia Current = Active; 5360bbfda8aSnia } 5370bbfda8aSnia if(!Current) { 5380bbfda8aSnia return; 5390bbfda8aSnia } 5400bbfda8aSnia 5410bbfda8aSnia ip = Current->iconmgr; 5420bbfda8aSnia 5430bbfda8aSnia got_it = false; 5440bbfda8aSnia tmp = Current; 5450bbfda8aSnia orig = Current; 5460bbfda8aSnia 5470bbfda8aSnia while(!got_it) { 5480bbfda8aSnia switch(dir) { 5490bbfda8aSnia case F_FORWMAPICONMGR: 5500bbfda8aSnia if((tmp = tmp->next) == NULL) { 5510bbfda8aSnia tmp = ip->first; 5520bbfda8aSnia } 5530bbfda8aSnia break; 5540bbfda8aSnia 5550bbfda8aSnia case F_BACKMAPICONMGR: 5560bbfda8aSnia if((tmp = tmp->prev) == NULL) { 5570bbfda8aSnia tmp = ip->last; 5580bbfda8aSnia } 5590bbfda8aSnia break; 5600bbfda8aSnia } 5610bbfda8aSnia if(tmp->twm->mapped) { 5620bbfda8aSnia got_it = true; 5630bbfda8aSnia break; 5640bbfda8aSnia } 5650bbfda8aSnia if(tmp == orig) { 5660bbfda8aSnia break; 5670bbfda8aSnia } 5680bbfda8aSnia } 5690bbfda8aSnia 5700bbfda8aSnia if(!got_it) { 5710bbfda8aSnia fprintf(stderr, "%s: unable to find open window in icon manager\n", 5720bbfda8aSnia ProgramName); 5730bbfda8aSnia return; 5740bbfda8aSnia } 5750bbfda8aSnia 5760bbfda8aSnia if(tmp == NULL) { 5770bbfda8aSnia return; 5780bbfda8aSnia } 5790bbfda8aSnia 5800bbfda8aSnia /* raise the frame so the icon manager is visible */ 5810bbfda8aSnia if(ip->twm_win->mapped) { 5820bbfda8aSnia OtpRaise(ip->twm_win, WinWin); 5830bbfda8aSnia XWarpPointer(dpy, None, tmp->icon, 0, 0, 0, 0, 5, 5); 5840bbfda8aSnia } 5850bbfda8aSnia else { 5860bbfda8aSnia if(tmp->twm->title_height) { 5870bbfda8aSnia XWarpPointer(dpy, None, tmp->twm->title_w, 0, 0, 0, 0, 5880bbfda8aSnia tmp->twm->title_width / 2, 5890bbfda8aSnia Scr->TitleHeight / 4); 5900bbfda8aSnia } 5910bbfda8aSnia else { 5920bbfda8aSnia XWarpPointer(dpy, None, tmp->twm->w, 0, 0, 0, 0, 5, 5); 5930bbfda8aSnia } 5940bbfda8aSnia } 595645f5050Syouri} 596645f5050Syouri 597645f5050Syouri/*********************************************************************** 598645f5050Syouri * 599645f5050Syouri * Procedure: 6000bbfda8aSnia * JumpIconManager - jump from one icon manager to another, 6010bbfda8aSnia * possibly even on another screen 602645f5050Syouri * 603645f5050Syouri * Inputs: 6040bbfda8aSnia * dir - one of the following: 6050bbfda8aSnia * F_NEXTICONMGR - go to the next icon manager 6060bbfda8aSnia * F_PREVICONMGR - go to the previous one 607645f5050Syouri * 608645f5050Syouri *********************************************************************** 609645f5050Syouri */ 610645f5050Syouri 6110bbfda8aSniavoid JumpIconManager(int dir) 612645f5050Syouri{ 6130bbfda8aSnia IconMgr *ip, *tmp_ip = NULL; 6140bbfda8aSnia bool got_it = false; 6150bbfda8aSnia ScreenInfo *sp; 6160bbfda8aSnia int screen; 617645f5050Syouri 6180bbfda8aSnia if(!Current) { 6190bbfda8aSnia return; 6200bbfda8aSnia } 621645f5050Syouri 622645f5050Syouri 623645f5050Syouri#define ITER(i) (dir == F_NEXTICONMGR ? (i)->next : (i)->prev) 624645f5050Syouri#define IPOFSP(sp) (dir == F_NEXTICONMGR ? sp->iconmgr : sp->iconmgr->lasti) 625645f5050Syouri#define TEST(ip) if ((ip)->count != 0 && (ip)->twm_win->mapped) \ 6260bbfda8aSnia { got_it = true; break; } 6270bbfda8aSnia 6280bbfda8aSnia ip = Current->iconmgr; 6290bbfda8aSnia for(tmp_ip = ITER(ip); tmp_ip; tmp_ip = ITER(tmp_ip)) { 6300bbfda8aSnia TEST(tmp_ip); 6310bbfda8aSnia } 6320bbfda8aSnia 6330bbfda8aSnia if(!got_it) { 6340bbfda8aSnia int origscreen = ip->scr->screen; 6350bbfda8aSnia int inc = (dir == F_NEXTICONMGR ? 1 : -1); 6360bbfda8aSnia 6370bbfda8aSnia for(screen = origscreen + inc; ; screen += inc) { 6380bbfda8aSnia if(screen >= NumScreens) { 6390bbfda8aSnia screen = 0; 6400bbfda8aSnia } 6410bbfda8aSnia else if(screen < 0) { 6420bbfda8aSnia screen = NumScreens - 1; 6430bbfda8aSnia } 6440bbfda8aSnia 6450bbfda8aSnia sp = ScreenList[screen]; 6460bbfda8aSnia if(sp) { 6470bbfda8aSnia for(tmp_ip = IPOFSP(sp); tmp_ip; tmp_ip = ITER(tmp_ip)) { 6480bbfda8aSnia TEST(tmp_ip); 6490bbfda8aSnia } 6500bbfda8aSnia } 6510bbfda8aSnia if(got_it || screen == origscreen) { 6520bbfda8aSnia break; 6530bbfda8aSnia } 654645f5050Syouri } 655645f5050Syouri } 656645f5050Syouri 657645f5050Syouri#undef ITER 658645f5050Syouri#undef IPOFSP 659645f5050Syouri#undef TEST 660645f5050Syouri 6610bbfda8aSnia if(!got_it) { 6620bbfda8aSnia XBell(dpy, 0); 6630bbfda8aSnia return; 6640bbfda8aSnia } 6650bbfda8aSnia 6660bbfda8aSnia /* raise the frame so it is visible */ 6670bbfda8aSnia OtpRaise(tmp_ip->twm_win, WinWin); 6680bbfda8aSnia if(tmp_ip->active) { 6690bbfda8aSnia XWarpPointer(dpy, None, tmp_ip->active->icon, 0, 0, 0, 0, 5, 5); 6700bbfda8aSnia } 6710bbfda8aSnia else { 6720bbfda8aSnia XWarpPointer(dpy, None, tmp_ip->w, 0, 0, 0, 0, 5, 5); 6730bbfda8aSnia } 674645f5050Syouri} 675645f5050Syouri 676645f5050Syouri/*********************************************************************** 677645f5050Syouri * 678645f5050Syouri * Procedure: 6790bbfda8aSnia * AddIconManager - add a window to an icon manager 680645f5050Syouri * 681645f5050Syouri * Inputs: 6820bbfda8aSnia * tmp_win - the TwmWindow structure 683645f5050Syouri * 684645f5050Syouri *********************************************************************** 685645f5050Syouri */ 686645f5050Syouri 687645f5050SyouriWList *AddIconManager(TwmWindow *tmp_win) 688645f5050Syouri{ 6890bbfda8aSnia WList *tmp, *old; 6900bbfda8aSnia IconMgr *ip; 6910bbfda8aSnia 6920bbfda8aSnia /* Some window types don't wind up in icon managers ever */ 6930bbfda8aSnia if(tmp_win->isiconmgr || tmp_win->istransient || tmp_win->iswspmgr 6940bbfda8aSnia || tmp_win->w == Scr->workSpaceMgr.occupyWindow->w) { 6950bbfda8aSnia return NULL; 6960bbfda8aSnia } 6970bbfda8aSnia 6980bbfda8aSnia /* Icon managers can be shut off wholesale in the config */ 6990bbfda8aSnia if(Scr->NoIconManagers) { 7000bbfda8aSnia return NULL; 7010bbfda8aSnia } 7020bbfda8aSnia 7030bbfda8aSnia /* Config could declare not to IMify this type of window in two ways */ 7040bbfda8aSnia if(LookInList(Scr->IconMgrNoShow, tmp_win->name, &tmp_win->class)) { 7050bbfda8aSnia return NULL; 7060bbfda8aSnia } 7070bbfda8aSnia if(Scr->IconManagerDontShow 7080bbfda8aSnia && !LookInList(Scr->IconMgrShow, tmp_win->name, &tmp_win->class)) { 7090bbfda8aSnia return NULL; 7100bbfda8aSnia } 7110bbfda8aSnia 7120bbfda8aSnia /* Dredge up the appropriate IM */ 7130bbfda8aSnia if((ip = (IconMgr *)LookInList(Scr->IconMgrs, tmp_win->name, 7140bbfda8aSnia &tmp_win->class)) == NULL) { 7150bbfda8aSnia if(Scr->workSpaceManagerActive) { 7160bbfda8aSnia ip = Scr->workSpaceMgr.workSpaceList->iconmgr; 7170bbfda8aSnia } 7180bbfda8aSnia else { 7190bbfda8aSnia ip = Scr->iconmgr; 7200bbfda8aSnia } 7210bbfda8aSnia } 7220bbfda8aSnia 7230bbfda8aSnia /* IM's exist in all workspaces, so loop through WSen */ 7240bbfda8aSnia tmp = NULL; 7250bbfda8aSnia old = tmp_win->iconmanagerlist; 7260bbfda8aSnia while(ip != NULL) { 7270bbfda8aSnia int h; 7280bbfda8aSnia unsigned long valuemask; /* mask for create windows */ 7290bbfda8aSnia XSetWindowAttributes attributes; /* attributes for create windows */ 7300bbfda8aSnia 7310bbfda8aSnia /* Is the window in this workspace? */ 7320bbfda8aSnia if((tmp_win->occupation & ip->twm_win->occupation) == 0) { 7330bbfda8aSnia /* Nope, skip onward */ 7340bbfda8aSnia ip = ip->nextv; 7350bbfda8aSnia continue; 7360bbfda8aSnia } 7370bbfda8aSnia 7380bbfda8aSnia /* Yep, create entry and stick it in */ 7390bbfda8aSnia tmp = calloc(1, sizeof(WList)); 7400bbfda8aSnia tmp->iconmgr = ip; 7410bbfda8aSnia tmp->twm = tmp_win; 7420bbfda8aSnia 7430bbfda8aSnia InsertInIconManager(ip, tmp, tmp_win); 7440bbfda8aSnia 7450bbfda8aSnia /* IM color settings, shared worldwide */ 7460bbfda8aSnia tmp->cp.fore = Scr->IconManagerC.fore; 7470bbfda8aSnia tmp->cp.back = Scr->IconManagerC.back; 7480bbfda8aSnia tmp->highlight = Scr->IconManagerHighlight; 7490bbfda8aSnia 7500bbfda8aSnia GetColorFromList(Scr->IconManagerFL, tmp_win->name, 7510bbfda8aSnia &tmp_win->class, &tmp->cp.fore); 7520bbfda8aSnia GetColorFromList(Scr->IconManagerBL, tmp_win->name, 7530bbfda8aSnia &tmp_win->class, &tmp->cp.back); 7540bbfda8aSnia GetColorFromList(Scr->IconManagerHighlightL, tmp_win->name, 7550bbfda8aSnia &tmp_win->class, &tmp->highlight); 7560bbfda8aSnia 7570bbfda8aSnia /* 7580bbfda8aSnia * If we're using 3d icon managers, each line item has its own 7590bbfda8aSnia * icon; see comment on creation function for details. With 2d 7600bbfda8aSnia * icon managers, it's the same for all of them, so it's stored 7610bbfda8aSnia * screen-wide. 7620bbfda8aSnia */ 7630bbfda8aSnia if(Scr->use3Diconmanagers) { 7640bbfda8aSnia if(!Scr->BeNiceToColormap) { 7650bbfda8aSnia GetShadeColors(&tmp->cp); 7660bbfda8aSnia } 7670bbfda8aSnia tmp->iconifypm = Create3DIconManagerIcon(tmp->cp); 7680bbfda8aSnia } 7690bbfda8aSnia 7700bbfda8aSnia /* Refigure the height of the whole IM */ 7710bbfda8aSnia h = Scr->IconManagerFont.avg_height 7720bbfda8aSnia + 2 * (ICON_MGR_OBORDER + ICON_MGR_OBORDER); 7730bbfda8aSnia if(h < (im_iconified_icon_height + 4)) { 7740bbfda8aSnia h = im_iconified_icon_height + 4; 7750bbfda8aSnia } 7760bbfda8aSnia 7770bbfda8aSnia ip->height = h * ip->count; 7780bbfda8aSnia tmp->me = ip->count; 7790bbfda8aSnia tmp->x = -1; 7800bbfda8aSnia tmp->y = -1; 7810bbfda8aSnia tmp->height = -1; 7820bbfda8aSnia tmp->width = -1; 7830bbfda8aSnia 7840bbfda8aSnia 7850bbfda8aSnia /* Make a window for this row in the IM */ 7860bbfda8aSnia valuemask = (CWBackPixel | CWBorderPixel | CWEventMask | CWCursor); 7870bbfda8aSnia attributes.background_pixel = tmp->cp.back; 7880bbfda8aSnia attributes.border_pixel = tmp->cp.back; 7890bbfda8aSnia attributes.event_mask = (KeyPressMask | ButtonPressMask | 7900bbfda8aSnia ButtonReleaseMask | ExposureMask); 7910bbfda8aSnia if(Scr->IconManagerFocus) { 7920bbfda8aSnia attributes.event_mask |= (EnterWindowMask | LeaveWindowMask); 7930bbfda8aSnia } 7940bbfda8aSnia attributes.cursor = Scr->IconMgrCursor; 7950bbfda8aSnia tmp->w = XCreateWindow(dpy, ip->w, 0, 0, 1, 7960bbfda8aSnia h, 0, 7970bbfda8aSnia CopyFromParent, CopyFromParent, 7980bbfda8aSnia CopyFromParent, 7990bbfda8aSnia valuemask, &attributes); 8000bbfda8aSnia 8010bbfda8aSnia 8020bbfda8aSnia /* Setup the icon for it too */ 8030bbfda8aSnia valuemask = (CWBackPixel | CWBorderPixel | CWEventMask | CWCursor); 8040bbfda8aSnia attributes.background_pixel = tmp->cp.back; 8050bbfda8aSnia attributes.border_pixel = Scr->Black; 8060bbfda8aSnia attributes.event_mask = (ButtonReleaseMask | ButtonPressMask 8070bbfda8aSnia | ExposureMask); 8080bbfda8aSnia attributes.cursor = Scr->ButtonCursor; 8090bbfda8aSnia /* The precise location will be set it in PackIconManager. */ 8100bbfda8aSnia tmp->icon = XCreateWindow(dpy, tmp->w, 0, 0, 8110bbfda8aSnia im_iconified_icon_width, 8120bbfda8aSnia im_iconified_icon_height, 8130bbfda8aSnia 0, CopyFromParent, 8140bbfda8aSnia CopyFromParent, 8150bbfda8aSnia CopyFromParent, 8160bbfda8aSnia valuemask, &attributes); 8170bbfda8aSnia 8180bbfda8aSnia 8190bbfda8aSnia /* Bump housekeeping for the IM */ 8200bbfda8aSnia ip->count += 1; 8210bbfda8aSnia PackIconManager(ip); 8220bbfda8aSnia if(Scr->WindowMask) { 8230bbfda8aSnia XRaiseWindow(dpy, Scr->WindowMask); 8240bbfda8aSnia } 8250bbfda8aSnia XMapWindow(dpy, tmp->w); 8260bbfda8aSnia 8270bbfda8aSnia XSaveContext(dpy, tmp->w, TwmContext, (XPointer) tmp_win); 8280bbfda8aSnia XSaveContext(dpy, tmp->w, ScreenContext, (XPointer) Scr); 8290bbfda8aSnia XSaveContext(dpy, tmp->icon, TwmContext, (XPointer) tmp_win); 8300bbfda8aSnia XSaveContext(dpy, tmp->icon, ScreenContext, (XPointer) Scr); 8310bbfda8aSnia 8320bbfda8aSnia if(!ip->twm_win->isicon) { 8330bbfda8aSnia if(visible(ip->twm_win)) { 8340bbfda8aSnia SetMapStateProp(ip->twm_win, NormalState); 8350bbfda8aSnia XMapWindow(dpy, ip->w); 8360bbfda8aSnia XMapWindow(dpy, ip->twm_win->frame); 8370bbfda8aSnia } 8380bbfda8aSnia ip->twm_win->mapped = true; 8390bbfda8aSnia } 8400bbfda8aSnia 8410bbfda8aSnia 8420bbfda8aSnia /* 8430bbfda8aSnia * Stick this entry on the head of our list of "IM entries we 8440bbfda8aSnia * created", and loop around to the next WS for this IM. 8450bbfda8aSnia */ 8460bbfda8aSnia tmp->nextv = old; 8470bbfda8aSnia old = tmp; 8480bbfda8aSnia ip = ip->nextv; 8490bbfda8aSnia } 8500bbfda8aSnia 8510bbfda8aSnia /* If we didn't create at least one thing, we're done here */ 8520bbfda8aSnia if(tmp == NULL) { 8530bbfda8aSnia return NULL; 8540bbfda8aSnia } 8550bbfda8aSnia 8560bbfda8aSnia /* Stash where the window is IM-listed */ 8570bbfda8aSnia tmp_win->iconmanagerlist = tmp; 8580bbfda8aSnia 8590bbfda8aSnia /* ??? */ 8600bbfda8aSnia if(! visible(tmp->iconmgr->twm_win)) { 8610bbfda8aSnia old = tmp; 8620bbfda8aSnia tmp = tmp->nextv; 8630bbfda8aSnia while(tmp != NULL) { 8640bbfda8aSnia if(visible(tmp->iconmgr->twm_win)) { 8650bbfda8aSnia break; 8660bbfda8aSnia } 8670bbfda8aSnia old = tmp; 8680bbfda8aSnia tmp = tmp->nextv; 8690bbfda8aSnia } 8700bbfda8aSnia if(tmp != NULL) { 8710bbfda8aSnia old->nextv = tmp->nextv; 8720bbfda8aSnia tmp->nextv = tmp_win->iconmanagerlist; 8730bbfda8aSnia tmp_win->iconmanagerlist = tmp; 8740bbfda8aSnia } 8750bbfda8aSnia } 8760bbfda8aSnia 8770bbfda8aSnia /* Hand back the list places we added */ 8780bbfda8aSnia return tmp_win->iconmanagerlist; 879645f5050Syouri} 880645f5050Syouri 881645f5050Syouri/*********************************************************************** 882645f5050Syouri * 883645f5050Syouri * Procedure: 8840bbfda8aSnia * InsertInIconManager - put an allocated entry into an icon 8850bbfda8aSnia * manager 886645f5050Syouri * 887645f5050Syouri * Inputs: 8880bbfda8aSnia * ip - the icon manager pointer 8890bbfda8aSnia * tmp - the entry to insert 890645f5050Syouri * 891645f5050Syouri *********************************************************************** 892645f5050Syouri */ 893645f5050Syouri 894645f5050Syourivoid InsertInIconManager(IconMgr *ip, WList *tmp, TwmWindow *tmp_win) 895645f5050Syouri{ 8960bbfda8aSnia WList *tmp1; 8970bbfda8aSnia bool added; 8980bbfda8aSnia 8990bbfda8aSnia added = false; 9000bbfda8aSnia if(ip->first == NULL) { 9010bbfda8aSnia ip->first = tmp; 9020bbfda8aSnia tmp->prev = NULL; 9030bbfda8aSnia ip->last = tmp; 9040bbfda8aSnia added = true; 9050bbfda8aSnia } 9060bbfda8aSnia else if(Scr->SortIconMgr) { 9070bbfda8aSnia for(tmp1 = ip->first; tmp1 != NULL; tmp1 = tmp1->next) { 9080bbfda8aSnia int compresult; 9090bbfda8aSnia if(Scr->CaseSensitive) { 9100bbfda8aSnia compresult = strcmp(tmp_win->icon_name, tmp1->twm->icon_name); 9110bbfda8aSnia } 9120bbfda8aSnia else { 9130bbfda8aSnia compresult = strcasecmp(tmp_win->icon_name, tmp1->twm->icon_name); 9140bbfda8aSnia } 9150bbfda8aSnia if(compresult < 0) { 9160bbfda8aSnia tmp->next = tmp1; 9170bbfda8aSnia tmp->prev = tmp1->prev; 9180bbfda8aSnia tmp1->prev = tmp; 9190bbfda8aSnia if(tmp->prev == NULL) { 9200bbfda8aSnia ip->first = tmp; 9210bbfda8aSnia } 9220bbfda8aSnia else { 9230bbfda8aSnia tmp->prev->next = tmp; 9240bbfda8aSnia } 9250bbfda8aSnia added = true; 9260bbfda8aSnia break; 9270bbfda8aSnia } 9280bbfda8aSnia } 9290bbfda8aSnia } 9300bbfda8aSnia 9310bbfda8aSnia if(!added) { 9320bbfda8aSnia ip->last->next = tmp; 9330bbfda8aSnia tmp->prev = ip->last; 9340bbfda8aSnia ip->last = tmp; 9350bbfda8aSnia } 936645f5050Syouri} 937645f5050Syouri 938645f5050Syourivoid RemoveFromIconManager(IconMgr *ip, WList *tmp) 939645f5050Syouri{ 9400bbfda8aSnia if(tmp->prev == NULL) { 9410bbfda8aSnia ip->first = tmp->next; 9420bbfda8aSnia } 9430bbfda8aSnia else { 9440bbfda8aSnia tmp->prev->next = tmp->next; 9450bbfda8aSnia } 9460bbfda8aSnia 9470bbfda8aSnia if(tmp->next == NULL) { 9480bbfda8aSnia ip->last = tmp->prev; 9490bbfda8aSnia } 9500bbfda8aSnia else { 9510bbfda8aSnia tmp->next->prev = tmp->prev; 9520bbfda8aSnia } 9530bbfda8aSnia 9540bbfda8aSnia /* pebl: If the list was the current and tmp was the last in the list 9550bbfda8aSnia reset current list */ 9560bbfda8aSnia if(Current == tmp) { 9570bbfda8aSnia Current = ip->first; 9580bbfda8aSnia } 959645f5050Syouri} 960645f5050Syouri 961645f5050Syouri/*********************************************************************** 962645f5050Syouri * 963645f5050Syouri * Procedure: 9640bbfda8aSnia * RemoveIconManager - remove a window from the icon manager 965645f5050Syouri * 966645f5050Syouri * Inputs: 9670bbfda8aSnia * tmp_win - the TwmWindow structure 968645f5050Syouri * 969645f5050Syouri *********************************************************************** 970645f5050Syouri */ 971645f5050Syouri 972645f5050Syourivoid RemoveIconManager(TwmWindow *tmp_win) 973645f5050Syouri{ 9740bbfda8aSnia IconMgr *ip; 9750bbfda8aSnia WList *tmp, *tmp1, *save; 9760bbfda8aSnia 9770bbfda8aSnia if(tmp_win->iconmanagerlist == NULL) { 9780bbfda8aSnia return; 9790bbfda8aSnia } 9800bbfda8aSnia 9810bbfda8aSnia tmp = tmp_win->iconmanagerlist; 9820bbfda8aSnia tmp1 = NULL; 9830bbfda8aSnia 9840bbfda8aSnia while(tmp != NULL) { 9850bbfda8aSnia ip = tmp->iconmgr; 9860bbfda8aSnia if((tmp_win->occupation & ip->twm_win->occupation) != 0) { 9870bbfda8aSnia tmp1 = tmp; 9880bbfda8aSnia tmp = tmp->nextv; 9890bbfda8aSnia continue; 9900bbfda8aSnia } 9910bbfda8aSnia RemoveFromIconManager(ip, tmp); 9920bbfda8aSnia 9930bbfda8aSnia XDeleteContext(dpy, tmp->icon, TwmContext); 9940bbfda8aSnia XDeleteContext(dpy, tmp->icon, ScreenContext); 9950bbfda8aSnia XDestroyWindow(dpy, tmp->icon); 9960bbfda8aSnia XDeleteContext(dpy, tmp->w, TwmContext); 9970bbfda8aSnia XDeleteContext(dpy, tmp->w, ScreenContext); 9980bbfda8aSnia XDestroyWindow(dpy, tmp->w); 9990bbfda8aSnia ip->count -= 1; 10000bbfda8aSnia 10010bbfda8aSnia PackIconManager(ip); 10020bbfda8aSnia 10030bbfda8aSnia if(ip->count == 0) { 10040bbfda8aSnia XUnmapWindow(dpy, ip->twm_win->frame); 10050bbfda8aSnia ip->twm_win->mapped = false; 10060bbfda8aSnia } 10070bbfda8aSnia if(tmp1 == NULL) { 10080bbfda8aSnia tmp_win->iconmanagerlist = tmp_win->iconmanagerlist->nextv; 10090bbfda8aSnia } 10100bbfda8aSnia else { 10110bbfda8aSnia tmp1->nextv = tmp->nextv; 10120bbfda8aSnia } 10130bbfda8aSnia 10140bbfda8aSnia save = tmp; 10150bbfda8aSnia tmp = tmp->nextv; 10160bbfda8aSnia free(save); 10170bbfda8aSnia } 1018645f5050Syouri} 1019645f5050Syouri 10200bbfda8aSniavoid CurrentIconManagerEntry(WList *current) 1021645f5050Syouri{ 10220bbfda8aSnia Current = current; 1023645f5050Syouri} 1024645f5050Syouri 1025645f5050Syourivoid ActiveIconManager(WList *active) 1026645f5050Syouri{ 10270bbfda8aSnia active->active = true; 10280bbfda8aSnia Active = active; 10290bbfda8aSnia Active->iconmgr->active = active; 10300bbfda8aSnia Current = Active; 10310bbfda8aSnia DrawIconManagerBorder(active, false); 1032645f5050Syouri} 1033645f5050Syouri 1034645f5050Syourivoid NotActiveIconManager(WList *active) 1035645f5050Syouri{ 10360bbfda8aSnia active->active = false; 10370bbfda8aSnia DrawIconManagerBorder(active, false); 1038645f5050Syouri} 1039645f5050Syouri 10400bbfda8aSniavoid DrawIconManagerBorder(WList *tmp, bool fill) 1041645f5050Syouri{ 10420bbfda8aSnia if(Scr->use3Diconmanagers) { 10430bbfda8aSnia Draw3DBorder(tmp->w, 0, 0, tmp->width, tmp->height, 10440bbfda8aSnia Scr->IconManagerShadowDepth, tmp->cp, 10450bbfda8aSnia (tmp->active && Scr->Highlight ? on : off), 10460bbfda8aSnia fill, false); 10470bbfda8aSnia } 10480bbfda8aSnia else { 10490bbfda8aSnia XSetForeground(dpy, Scr->NormalGC, tmp->cp.fore); 10500bbfda8aSnia XDrawRectangle(dpy, tmp->w, Scr->NormalGC, 2, 2, tmp->width - 5, 10510bbfda8aSnia tmp->height - 5); 10520bbfda8aSnia 10530bbfda8aSnia XSetForeground(dpy, Scr->NormalGC, 10540bbfda8aSnia (tmp->active && Scr->Highlight 10550bbfda8aSnia ? tmp->highlight : tmp->cp.back)); 10560bbfda8aSnia 10570bbfda8aSnia XDrawRectangle(dpy, tmp->w, Scr->NormalGC, 0, 0, tmp->width - 1, 10580bbfda8aSnia tmp->height - 1); 10590bbfda8aSnia XDrawRectangle(dpy, tmp->w, Scr->NormalGC, 1, 1, tmp->width - 3, 10600bbfda8aSnia tmp->height - 3); 10610bbfda8aSnia } 1062645f5050Syouri} 1063645f5050Syouri 1064645f5050Syouri/*********************************************************************** 1065645f5050Syouri * 1066645f5050Syouri * Procedure: 10670bbfda8aSnia * SortIconManager - sort the dude 1068645f5050Syouri * 1069645f5050Syouri * Inputs: 10700bbfda8aSnia * ip - a pointer to the icon manager struture 1071645f5050Syouri * 1072645f5050Syouri *********************************************************************** 1073645f5050Syouri */ 1074645f5050Syouri 1075645f5050Syourivoid SortIconManager(IconMgr *ip) 1076645f5050Syouri{ 10770bbfda8aSnia WList *tmp1, *tmp2; 10780bbfda8aSnia int done; 10790bbfda8aSnia 10800bbfda8aSnia if(ip == NULL) { 10810bbfda8aSnia ip = Active->iconmgr; 10820bbfda8aSnia } 10830bbfda8aSnia 10840bbfda8aSnia done = false; 10850bbfda8aSnia do { 10860bbfda8aSnia for(tmp1 = ip->first; tmp1 != NULL; tmp1 = tmp1->next) { 10870bbfda8aSnia int compresult; 10880bbfda8aSnia if((tmp2 = tmp1->next) == NULL) { 10890bbfda8aSnia done = true; 10900bbfda8aSnia break; 10910bbfda8aSnia } 10920bbfda8aSnia if(Scr->CaseSensitive) { 10930bbfda8aSnia compresult = strcmp(tmp1->twm->icon_name, tmp2->twm->icon_name); 10940bbfda8aSnia } 10950bbfda8aSnia else { 10960bbfda8aSnia compresult = strcasecmp(tmp1->twm->icon_name, tmp2->twm->icon_name); 10970bbfda8aSnia } 10980bbfda8aSnia if(compresult > 0) { 10990bbfda8aSnia /* take it out and put it back in */ 11000bbfda8aSnia RemoveFromIconManager(ip, tmp2); 11010bbfda8aSnia InsertInIconManager(ip, tmp2, tmp2->twm); 11020bbfda8aSnia break; 11030bbfda8aSnia } 11040bbfda8aSnia } 11050bbfda8aSnia } 11060bbfda8aSnia while(!done); 11070bbfda8aSnia PackIconManager(ip); 1108645f5050Syouri} 1109645f5050Syouri 1110645f5050Syouri/*********************************************************************** 1111645f5050Syouri * 1112645f5050Syouri * Procedure: 11130bbfda8aSnia * PackIconManager - pack the icon manager windows following 11140bbfda8aSnia * an addition or deletion 1115645f5050Syouri * 1116645f5050Syouri * Inputs: 11170bbfda8aSnia * ip - a pointer to the icon manager struture 1118645f5050Syouri * 1119645f5050Syouri *********************************************************************** 1120645f5050Syouri */ 1121645f5050Syouri 11220bbfda8aSniavoid PackIconManagers(void) 11230bbfda8aSnia{ 11240bbfda8aSnia TwmWindow *twm_win; 11250bbfda8aSnia 11260bbfda8aSnia for(twm_win = Scr->FirstWindow; twm_win != NULL; twm_win = twm_win->next) { 11270bbfda8aSnia if(twm_win->iconmgrp) { 11280bbfda8aSnia PackIconManager(twm_win->iconmgrp); 11290bbfda8aSnia } 11300bbfda8aSnia } 11310bbfda8aSnia} 11320bbfda8aSnia 1133645f5050Syourivoid PackIconManager(IconMgr *ip) 1134645f5050Syouri{ 11350bbfda8aSnia int newwidth, i, row, col, maxcol, colinc, rowinc, wheight, wwidth; 11360bbfda8aSnia int new_x, new_y; 11370bbfda8aSnia int savewidth; 11380bbfda8aSnia WList *tmp; 11390bbfda8aSnia int mask; 11400bbfda8aSnia 11410bbfda8aSnia wheight = Scr->IconManagerFont.avg_height 11420bbfda8aSnia + 2 * (ICON_MGR_OBORDER + ICON_MGR_IBORDER); 11430bbfda8aSnia if(wheight < (im_iconified_icon_height + 4)) { 11440bbfda8aSnia wheight = im_iconified_icon_height + 4; 11450bbfda8aSnia } 11460bbfda8aSnia 11470bbfda8aSnia wwidth = ip->width / ip->columns; 11480bbfda8aSnia 11490bbfda8aSnia rowinc = wheight; 11500bbfda8aSnia colinc = wwidth; 11510bbfda8aSnia 11520bbfda8aSnia row = 0; 11530bbfda8aSnia col = ip->columns; 11540bbfda8aSnia maxcol = 0; 11550bbfda8aSnia for(i = 0, tmp = ip->first; tmp != NULL; i++, tmp = tmp->next) { 11560bbfda8aSnia tmp->me = i; 11570bbfda8aSnia if(++col >= ip->columns) { 11580bbfda8aSnia col = 0; 11590bbfda8aSnia row += 1; 11600bbfda8aSnia } 11610bbfda8aSnia if(col > maxcol) { 11620bbfda8aSnia maxcol = col; 11630bbfda8aSnia } 11640bbfda8aSnia 11650bbfda8aSnia new_x = col * colinc; 11660bbfda8aSnia new_y = (row - 1) * rowinc; 11670bbfda8aSnia 11680bbfda8aSnia /* if the position or size has not changed, don't touch it */ 11690bbfda8aSnia if(tmp->x != new_x || tmp->y != new_y || 11700bbfda8aSnia tmp->width != wwidth || tmp->height != wheight) { 11710bbfda8aSnia XMoveResizeWindow(dpy, tmp->w, new_x, new_y, wwidth, wheight); 11720bbfda8aSnia if(tmp->height != wheight) 11730bbfda8aSnia XMoveWindow(dpy, tmp->icon, ICON_MGR_OBORDER + ICON_MGR_IBORDER, 11740bbfda8aSnia (wheight - im_iconified_icon_height) / 2); 11750bbfda8aSnia 11760bbfda8aSnia tmp->row = row - 1; 11770bbfda8aSnia tmp->col = col; 11780bbfda8aSnia tmp->x = new_x; 11790bbfda8aSnia tmp->y = new_y; 11800bbfda8aSnia tmp->width = wwidth; 11810bbfda8aSnia tmp->height = wheight; 11820bbfda8aSnia } 11830bbfda8aSnia } 11840bbfda8aSnia maxcol += 1; 11850bbfda8aSnia 11860bbfda8aSnia ip->cur_rows = row; 11870bbfda8aSnia ip->cur_columns = maxcol; 11880bbfda8aSnia ip->height = row * rowinc; 11890bbfda8aSnia if(ip->height == 0) { 11900bbfda8aSnia ip->height = rowinc; 11910bbfda8aSnia } 11920bbfda8aSnia newwidth = maxcol * colinc; 11930bbfda8aSnia if(newwidth == 0) { 11940bbfda8aSnia newwidth = colinc; 11950bbfda8aSnia } 11960bbfda8aSnia 11970bbfda8aSnia XResizeWindow(dpy, ip->w, newwidth, ip->height); 11980bbfda8aSnia 11990bbfda8aSnia mask = XParseGeometry(ip->geometry, &JunkX, &JunkY, 12000bbfda8aSnia &JunkWidth, &JunkHeight); 12010bbfda8aSnia if(mask & XNegative) { 12020bbfda8aSnia ip->twm_win->frame_x += ip->twm_win->frame_width - newwidth - 12030bbfda8aSnia 2 * ip->twm_win->frame_bw3D; 12040bbfda8aSnia } 12050bbfda8aSnia if(mask & YNegative) { 12060bbfda8aSnia ip->twm_win->frame_y += ip->twm_win->frame_height - ip->height - 12070bbfda8aSnia 2 * ip->twm_win->frame_bw3D - ip->twm_win->title_height; 12080bbfda8aSnia } 12090bbfda8aSnia savewidth = ip->width; 12100bbfda8aSnia if(ip->twm_win) 12110bbfda8aSnia SetupWindow(ip->twm_win, 12120bbfda8aSnia ip->twm_win->frame_x, ip->twm_win->frame_y, 12130bbfda8aSnia newwidth + 2 * ip->twm_win->frame_bw3D, 12140bbfda8aSnia ip->height + ip->twm_win->title_height + 2 * ip->twm_win->frame_bw3D, -1); 12150bbfda8aSnia ip->width = savewidth; 12160bbfda8aSnia} 12170bbfda8aSnia 12180bbfda8aSniavoid dump_iconmanager(IconMgr *mgr, char *label) 12190bbfda8aSnia{ 12200bbfda8aSnia fprintf(stderr, "IconMgr %s %p name='%s' geom='%s'\n", 12210bbfda8aSnia label, 12220bbfda8aSnia mgr, 12230bbfda8aSnia mgr->name, 12240bbfda8aSnia mgr->geometry); 12250bbfda8aSnia fprintf(stderr, "next = %p, prev = %p, lasti = %p, nextv = %p\n", 12260bbfda8aSnia mgr->next, 12270bbfda8aSnia mgr->prev, 12280bbfda8aSnia mgr->lasti, 12290bbfda8aSnia mgr->nextv); 12300bbfda8aSnia} 12310bbfda8aSnia 12320bbfda8aSnia 12330bbfda8aSnia/* 12340bbfda8aSnia * Draw the window name into the icon manager line 12350bbfda8aSnia */ 12360bbfda8aSniavoid 12370bbfda8aSniaDrawIconManagerIconName(TwmWindow *tmp_win) 12380bbfda8aSnia{ 12390bbfda8aSnia WList *iconmanagerlist = tmp_win->iconmanagerlist; 12400bbfda8aSnia XRectangle ink_rect, logical_rect; 12410bbfda8aSnia 12420bbfda8aSnia XmbTextExtents(Scr->IconManagerFont.font_set, 12430bbfda8aSnia tmp_win->icon_name, strlen(tmp_win->icon_name), 12440bbfda8aSnia &ink_rect, &logical_rect); 12450bbfda8aSnia 12460bbfda8aSnia if(UpdateFont(&Scr->IconManagerFont, logical_rect.height)) { 12470bbfda8aSnia PackIconManagers(); 12480bbfda8aSnia } 12490bbfda8aSnia 12500bbfda8aSnia DrawIconManagerBorder(iconmanagerlist, true); 12510bbfda8aSnia 12520bbfda8aSnia FB(iconmanagerlist->cp.fore, iconmanagerlist->cp.back); 12530bbfda8aSnia 12540bbfda8aSnia /* XXX This is a completely absurd way of writing this */ 12550bbfda8aSnia ((Scr->use3Diconmanagers && (Scr->Monochrome != COLOR)) ? 12560bbfda8aSnia XmbDrawImageString : XmbDrawString) 12570bbfda8aSnia (dpy, 12580bbfda8aSnia iconmanagerlist->w, 12590bbfda8aSnia Scr->IconManagerFont.font_set, 12600bbfda8aSnia Scr->NormalGC, 12610bbfda8aSnia iconmgr_textx, 12620bbfda8aSnia (Scr->IconManagerFont.avg_height - logical_rect.height) / 2 12630bbfda8aSnia + (- logical_rect.y) 12640bbfda8aSnia + ICON_MGR_OBORDER 12650bbfda8aSnia + ICON_MGR_IBORDER, 12660bbfda8aSnia tmp_win->icon_name, 12670bbfda8aSnia strlen(tmp_win->icon_name)); 12680bbfda8aSnia} 12690bbfda8aSnia 12700bbfda8aSnia 12710bbfda8aSnia/* 12720bbfda8aSnia * Copy the icon into the icon manager for a window that's iconified. 12730bbfda8aSnia * This is slightly different for the 3d vs 2d case, since the 3d is just 12740bbfda8aSnia * copying a pixmap in, while the 2d is drawing a bitmap in with the 12750bbfda8aSnia * fg/bg colors appropriate to the line. 12760bbfda8aSnia */ 12770bbfda8aSniavoid 12780bbfda8aSniaShowIconifiedIcon(TwmWindow *tmp_win) 12790bbfda8aSnia{ 12800bbfda8aSnia WList *iconmanagerlist = tmp_win->iconmanagerlist; 12810bbfda8aSnia 12820bbfda8aSnia if(Scr->use3Diconmanagers && iconmanagerlist->iconifypm) { 12830bbfda8aSnia XCopyArea(dpy, iconmanagerlist->iconifypm, 12840bbfda8aSnia iconmanagerlist->icon, 12850bbfda8aSnia Scr->NormalGC, 0, 0, 12860bbfda8aSnia im_iconified_icon_width, im_iconified_icon_height, 0, 0); 12870bbfda8aSnia } 12880bbfda8aSnia else { 12890bbfda8aSnia FB(iconmanagerlist->cp.fore, iconmanagerlist->cp.back); 12900bbfda8aSnia XCopyPlane(dpy, Scr->siconifyPm, iconmanagerlist->icon, 12910bbfda8aSnia Scr->NormalGC, 0, 0, 12920bbfda8aSnia im_iconified_icon_width, im_iconified_icon_height, 0, 0, 1); 12930bbfda8aSnia } 1294645f5050Syouri} 1295