iconmgr.c revision 3e747e6d
13e747e6dSmrg/* 23e747e6dSmrg * 33e747e6dSmrgCopyright 1989,1998 The Open Group 43e747e6dSmrg 53e747e6dSmrgPermission to use, copy, modify, distribute, and sell this software and its 63e747e6dSmrgdocumentation for any purpose is hereby granted without fee, provided that 73e747e6dSmrgthe above copyright notice appear in all copies and that both that 83e747e6dSmrgcopyright notice and this permission notice appear in supporting 93e747e6dSmrgdocumentation. 103e747e6dSmrg 113e747e6dSmrgThe above copyright notice and this permission notice shall be included in 123e747e6dSmrgall copies or substantial portions of the Software. 133e747e6dSmrg 143e747e6dSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 153e747e6dSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 163e747e6dSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 173e747e6dSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 183e747e6dSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 193e747e6dSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 203e747e6dSmrg 213e747e6dSmrgExcept as contained in this notice, the name of The Open Group shall not be 223e747e6dSmrgused in advertising or otherwise to promote the sale, use or other dealings 233e747e6dSmrgin this Software without prior written authorization from The Open Group. 243e747e6dSmrg * */ 253e747e6dSmrg/* $XFree86: xc/programs/twm/iconmgr.c,v 1.5 2001/01/17 23:45:06 dawes Exp $ */ 263e747e6dSmrg 273e747e6dSmrg/*********************************************************************** 283e747e6dSmrg * 293e747e6dSmrg * $Xorg: iconmgr.c,v 1.4 2001/02/09 02:05:36 xorgcvs Exp $ 303e747e6dSmrg * 313e747e6dSmrg * Icon Manager routines 323e747e6dSmrg * 333e747e6dSmrg * 09-Mar-89 Tom LaStrange File Created 343e747e6dSmrg * 353e747e6dSmrg ***********************************************************************/ 363e747e6dSmrg/* $XFree86: xc/programs/twm/iconmgr.c,v 1.5 2001/01/17 23:45:06 dawes Exp $ */ 373e747e6dSmrg 383e747e6dSmrg#include <stdio.h> 393e747e6dSmrg#include "twm.h" 403e747e6dSmrg#include "util.h" 413e747e6dSmrg#include "parse.h" 423e747e6dSmrg#include "screen.h" 433e747e6dSmrg#include "resize.h" 443e747e6dSmrg#include "add_window.h" 453e747e6dSmrg#include "siconify.bm" 463e747e6dSmrg#include <X11/Xos.h> 473e747e6dSmrg#include <X11/Xmu/CharSet.h> 483e747e6dSmrg#ifdef macII 493e747e6dSmrgint strcmp(); /* missing from string.h in AUX 2.0 */ 503e747e6dSmrg#endif 513e747e6dSmrg 523e747e6dSmrgint iconmgr_textx = siconify_width+11; 533e747e6dSmrgWList *Active = NULL; 543e747e6dSmrgWList *DownIconManager = NULL; 553e747e6dSmrgint iconifybox_width = siconify_width; 563e747e6dSmrgint iconifybox_height = siconify_height; 573e747e6dSmrg 583e747e6dSmrg/** 593e747e6dSmrg * create all the icon manager windows for this screen. 603e747e6dSmrg */ 613e747e6dSmrgvoid CreateIconManagers() 623e747e6dSmrg{ 633e747e6dSmrg IconMgr *p; 643e747e6dSmrg int mask; 653e747e6dSmrg char str[100]; 663e747e6dSmrg char str1[100]; 673e747e6dSmrg Pixel background; 683e747e6dSmrg char *icon_name; 693e747e6dSmrg 703e747e6dSmrg if (Scr->NoIconManagers) 713e747e6dSmrg return; 723e747e6dSmrg 733e747e6dSmrg if (Scr->siconifyPm == None) 743e747e6dSmrg { 753e747e6dSmrg Scr->siconifyPm = XCreatePixmapFromBitmapData(dpy, Scr->Root, 763e747e6dSmrg (char *)siconify_bits, siconify_width, siconify_height, 1, 0, 1); 773e747e6dSmrg } 783e747e6dSmrg 793e747e6dSmrg for (p = &Scr->iconmgr; p != NULL; p = p->next) 803e747e6dSmrg { 813e747e6dSmrg mask = XParseGeometry(p->geometry, &JunkX, &JunkY, 823e747e6dSmrg (unsigned int *) &p->width, (unsigned int *)&p->height); 833e747e6dSmrg 843e747e6dSmrg if (mask & XNegative) 853e747e6dSmrg JunkX = Scr->MyDisplayWidth - p->width - 863e747e6dSmrg (2 * Scr->BorderWidth) + JunkX; 873e747e6dSmrg 883e747e6dSmrg if (mask & YNegative) 893e747e6dSmrg JunkY = Scr->MyDisplayHeight - p->height - 903e747e6dSmrg (2 * Scr->BorderWidth) + JunkY; 913e747e6dSmrg 923e747e6dSmrg background = Scr->IconManagerC.back; 933e747e6dSmrg GetColorFromList(Scr->IconManagerBL, p->name, (XClassHint *)NULL, 943e747e6dSmrg &background); 953e747e6dSmrg 963e747e6dSmrg p->w = XCreateSimpleWindow(dpy, Scr->Root, 973e747e6dSmrg JunkX, JunkY, p->width, p->height, 1, 983e747e6dSmrg Scr->Black, background); 993e747e6dSmrg 1003e747e6dSmrg sprintf(str, "%s Icon Manager", p->name); 1013e747e6dSmrg sprintf(str1, "%s Icons", p->name); 1023e747e6dSmrg if (p->icon_name) 1033e747e6dSmrg icon_name = p->icon_name; 1043e747e6dSmrg else 1053e747e6dSmrg icon_name = str1; 1063e747e6dSmrg 1073e747e6dSmrg XSetStandardProperties(dpy, p->w, str, icon_name, None, NULL, 0, NULL); 1083e747e6dSmrg 1093e747e6dSmrg p->twm_win = AddWindow(p->w, TRUE, p); 1103e747e6dSmrg SetMapStateProp (p->twm_win, WithdrawnState); 1113e747e6dSmrg } 1123e747e6dSmrg for (p = &Scr->iconmgr; p != NULL; p = p->next) 1133e747e6dSmrg { 1143e747e6dSmrg GrabButtons(p->twm_win); 1153e747e6dSmrg GrabKeys(p->twm_win); 1163e747e6dSmrg } 1173e747e6dSmrg} 1183e747e6dSmrg 1193e747e6dSmrg/** 1203e747e6dSmrg * allocate a new icon manager 1213e747e6dSmrg * 1223e747e6dSmrg * \param name the name of this icon manager 1233e747e6dSmrg * \param con_name the name of the associated icon 1243e747e6dSmrg * \param geom a geometry string to eventually parse 1253e747e6dSmrg * \param columns the number of columns this icon manager has 1263e747e6dSmrg */ 1273e747e6dSmrgIconMgr *AllocateIconManager(char *name, char *icon_name, char *geom, int columns) 1283e747e6dSmrg{ 1293e747e6dSmrg IconMgr *p; 1303e747e6dSmrg 1313e747e6dSmrg#ifdef DEBUG_ICONMGR 1323e747e6dSmrg fprintf(stderr, "AllocateIconManager\n"); 1333e747e6dSmrg fprintf(stderr, " name=\"%s\" icon_name=\"%s\", geom=\"%s\", col=%d\n", 1343e747e6dSmrg name, icon_name, geom, columns); 1353e747e6dSmrg#endif 1363e747e6dSmrg 1373e747e6dSmrg if (Scr->NoIconManagers) 1383e747e6dSmrg return NULL; 1393e747e6dSmrg 1403e747e6dSmrg p = (IconMgr *)malloc(sizeof(IconMgr)); 1413e747e6dSmrg p->name = name; 1423e747e6dSmrg p->icon_name = icon_name; 1433e747e6dSmrg p->geometry = geom; 1443e747e6dSmrg p->columns = columns; 1453e747e6dSmrg p->first = NULL; 1463e747e6dSmrg p->last = NULL; 1473e747e6dSmrg p->active = NULL; 1483e747e6dSmrg p->scr = Scr; 1493e747e6dSmrg p->count = 0; 1503e747e6dSmrg p->x = 0; 1513e747e6dSmrg p->y = 0; 1523e747e6dSmrg p->width = 150; 1533e747e6dSmrg p->height = 10; 1543e747e6dSmrg 1553e747e6dSmrg Scr->iconmgr.lasti->next = p; 1563e747e6dSmrg p->prev = Scr->iconmgr.lasti; 1573e747e6dSmrg Scr->iconmgr.lasti = p; 1583e747e6dSmrg p->next = NULL; 1593e747e6dSmrg 1603e747e6dSmrg return(p); 1613e747e6dSmrg} 1623e747e6dSmrg 1633e747e6dSmrg/** 1643e747e6dSmrg * move the pointer around in an icon manager 1653e747e6dSmrg * 1663e747e6dSmrg * \param dir one of the following: 1673e747e6dSmrg * - F_FORWICONMGR: forward in the window list 1683e747e6dSmrg * - F_BACKICONMGR: backward in the window list 1693e747e6dSmrg * - F_UPICONMGR: up one row 1703e747e6dSmrg * - F_DOWNICONMG: down one row 1713e747e6dSmrg * - F_LEFTICONMGR: left one column 1723e747e6dSmrg * - F_RIGHTICONMGR: right one column 1733e747e6dSmrg */ 1743e747e6dSmrgvoid MoveIconManager(int dir) 1753e747e6dSmrg{ 1763e747e6dSmrg IconMgr *ip; 1773e747e6dSmrg WList *tmp = NULL; 1783e747e6dSmrg int cur_row, cur_col, new_row, new_col; 1793e747e6dSmrg int row_inc, col_inc; 1803e747e6dSmrg int got_it; 1813e747e6dSmrg 1823e747e6dSmrg if (!Active) return; 1833e747e6dSmrg 1843e747e6dSmrg cur_row = Active->row; 1853e747e6dSmrg cur_col = Active->col; 1863e747e6dSmrg ip = Active->iconmgr; 1873e747e6dSmrg 1883e747e6dSmrg row_inc = 0; 1893e747e6dSmrg col_inc = 0; 1903e747e6dSmrg got_it = FALSE; 1913e747e6dSmrg 1923e747e6dSmrg switch (dir) 1933e747e6dSmrg { 1943e747e6dSmrg case F_FORWICONMGR: 1953e747e6dSmrg if ((tmp = Active->next) == NULL) 1963e747e6dSmrg tmp = ip->first; 1973e747e6dSmrg got_it = TRUE; 1983e747e6dSmrg break; 1993e747e6dSmrg 2003e747e6dSmrg case F_BACKICONMGR: 2013e747e6dSmrg if ((tmp = Active->prev) == NULL) 2023e747e6dSmrg tmp = ip->last; 2033e747e6dSmrg got_it = TRUE; 2043e747e6dSmrg break; 2053e747e6dSmrg 2063e747e6dSmrg case F_UPICONMGR: 2073e747e6dSmrg row_inc = -1; 2083e747e6dSmrg break; 2093e747e6dSmrg 2103e747e6dSmrg case F_DOWNICONMGR: 2113e747e6dSmrg row_inc = 1; 2123e747e6dSmrg break; 2133e747e6dSmrg 2143e747e6dSmrg case F_LEFTICONMGR: 2153e747e6dSmrg col_inc = -1; 2163e747e6dSmrg break; 2173e747e6dSmrg 2183e747e6dSmrg case F_RIGHTICONMGR: 2193e747e6dSmrg col_inc = 1; 2203e747e6dSmrg break; 2213e747e6dSmrg } 2223e747e6dSmrg 2233e747e6dSmrg /* If got_it is FALSE ast this point then we got a left, right, 2243e747e6dSmrg * up, or down, command. We will enter this loop until we find 2253e747e6dSmrg * a window to warp to. 2263e747e6dSmrg */ 2273e747e6dSmrg new_row = cur_row; 2283e747e6dSmrg new_col = cur_col; 2293e747e6dSmrg 2303e747e6dSmrg while (!got_it) 2313e747e6dSmrg { 2323e747e6dSmrg new_row += row_inc; 2333e747e6dSmrg new_col += col_inc; 2343e747e6dSmrg if (new_row < 0) 2353e747e6dSmrg new_row = ip->cur_rows - 1; 2363e747e6dSmrg if (new_col < 0) 2373e747e6dSmrg new_col = ip->cur_columns - 1; 2383e747e6dSmrg if (new_row >= ip->cur_rows) 2393e747e6dSmrg new_row = 0; 2403e747e6dSmrg if (new_col >= ip->cur_columns) 2413e747e6dSmrg new_col = 0; 2423e747e6dSmrg 2433e747e6dSmrg /* Now let's go through the list to see if there is an entry with this 2443e747e6dSmrg * new position 2453e747e6dSmrg */ 2463e747e6dSmrg for (tmp = ip->first; tmp != NULL; tmp = tmp->next) 2473e747e6dSmrg { 2483e747e6dSmrg if (tmp->row == new_row && tmp->col == new_col) 2493e747e6dSmrg { 2503e747e6dSmrg got_it = TRUE; 2513e747e6dSmrg break; 2523e747e6dSmrg } 2533e747e6dSmrg } 2543e747e6dSmrg } 2553e747e6dSmrg 2563e747e6dSmrg if (!got_it) 2573e747e6dSmrg { 2583e747e6dSmrg fprintf (stderr, 2593e747e6dSmrg "%s: unable to find window (%d, %d) in icon manager\n", 2603e747e6dSmrg ProgramName, new_row, new_col); 2613e747e6dSmrg return; 2623e747e6dSmrg } 2633e747e6dSmrg 2643e747e6dSmrg if (tmp == NULL) 2653e747e6dSmrg return; 2663e747e6dSmrg 2673e747e6dSmrg /* raise the frame so the icon manager is visible */ 2683e747e6dSmrg if (ip->twm_win->mapped) { 2693e747e6dSmrg XRaiseWindow(dpy, ip->twm_win->frame); 2703e747e6dSmrg XWarpPointer(dpy, None, tmp->icon, 0,0,0,0, 5, 5); 2713e747e6dSmrg } else { 2723e747e6dSmrg if (tmp->twm->title_height) { 2733e747e6dSmrg int tbx = Scr->TBInfo.titlex; 2743e747e6dSmrg int x = tmp->twm->highlightx; 2753e747e6dSmrg XWarpPointer (dpy, None, tmp->twm->title_w, 0, 0, 0, 0, 2763e747e6dSmrg tbx + (x - tbx) / 2, 2773e747e6dSmrg Scr->TitleHeight / 4); 2783e747e6dSmrg } else { 2793e747e6dSmrg XWarpPointer (dpy, None, tmp->twm->w, 0, 0, 0, 0, 5, 5); 2803e747e6dSmrg } 2813e747e6dSmrg } 2823e747e6dSmrg} 2833e747e6dSmrg 2843e747e6dSmrg/** 2853e747e6dSmrg * jump from one icon manager to another, possibly even on another screen 2863e747e6dSmrg * \param dir one of the following: 2873e747e6dSmrg * - F_NEXTICONMGR - go to the next icon manager 2883e747e6dSmrg * - F_PREVICONMGR - go to the previous one 2893e747e6dSmrg */ 2903e747e6dSmrg 2913e747e6dSmrgvoid JumpIconManager(int dir) 2923e747e6dSmrg{ 2933e747e6dSmrg IconMgr *ip, *tmp_ip = NULL; 2943e747e6dSmrg int got_it = FALSE; 2953e747e6dSmrg ScreenInfo *sp; 2963e747e6dSmrg int screen; 2973e747e6dSmrg 2983e747e6dSmrg if (!Active) return; 2993e747e6dSmrg 3003e747e6dSmrg 3013e747e6dSmrg#define ITER(i) (dir == F_NEXTICONMGR ? (i)->next : (i)->prev) 3023e747e6dSmrg#define IPOFSP(sp) (dir == F_NEXTICONMGR ? &(sp->iconmgr) : sp->iconmgr.lasti) 3033e747e6dSmrg#define TEST(ip) if ((ip)->count != 0 && (ip)->twm_win->mapped) \ 3043e747e6dSmrg { got_it = TRUE; break; } 3053e747e6dSmrg 3063e747e6dSmrg ip = Active->iconmgr; 3073e747e6dSmrg for (tmp_ip = ITER(ip); tmp_ip; tmp_ip = ITER(tmp_ip)) { 3083e747e6dSmrg TEST (tmp_ip); 3093e747e6dSmrg } 3103e747e6dSmrg 3113e747e6dSmrg if (!got_it) { 3123e747e6dSmrg int origscreen = ip->scr->screen; 3133e747e6dSmrg int inc = (dir == F_NEXTICONMGR ? 1 : -1); 3143e747e6dSmrg 3153e747e6dSmrg for (screen = origscreen + inc; ; screen += inc) { 3163e747e6dSmrg if (screen >= NumScreens) 3173e747e6dSmrg screen = 0; 3183e747e6dSmrg else if (screen < 0) 3193e747e6dSmrg screen = NumScreens - 1; 3203e747e6dSmrg 3213e747e6dSmrg sp = ScreenList[screen]; 3223e747e6dSmrg if (sp) { 3233e747e6dSmrg for (tmp_ip = IPOFSP (sp); tmp_ip; tmp_ip = ITER(tmp_ip)) { 3243e747e6dSmrg TEST (tmp_ip); 3253e747e6dSmrg } 3263e747e6dSmrg } 3273e747e6dSmrg if (got_it || screen == origscreen) break; 3283e747e6dSmrg } 3293e747e6dSmrg } 3303e747e6dSmrg 3313e747e6dSmrg#undef ITER 3323e747e6dSmrg#undef IPOFSP 3333e747e6dSmrg#undef TEST 3343e747e6dSmrg 3353e747e6dSmrg if (!got_it) { 3363e747e6dSmrg Bell(XkbBI_MinorError,0,None); 3373e747e6dSmrg return; 3383e747e6dSmrg } 3393e747e6dSmrg 3403e747e6dSmrg /* raise the frame so it is visible */ 3413e747e6dSmrg XRaiseWindow(dpy, tmp_ip->twm_win->frame); 3423e747e6dSmrg if (tmp_ip->active) 3433e747e6dSmrg XWarpPointer(dpy, None, tmp_ip->active->icon, 0,0,0,0, 5, 5); 3443e747e6dSmrg else 3453e747e6dSmrg XWarpPointer(dpy, None, tmp_ip->w, 0,0,0,0, 5, 5); 3463e747e6dSmrg} 3473e747e6dSmrg 3483e747e6dSmrg/** 3493e747e6dSmrg * add a window to an icon manager 3503e747e6dSmrg * 3513e747e6dSmrg * \param tmp_win the TwmWindow structure 3523e747e6dSmrg */ 3533e747e6dSmrgWList *AddIconManager(TwmWindow *tmp_win) 3543e747e6dSmrg{ 3553e747e6dSmrg WList *tmp; 3563e747e6dSmrg int h; 3573e747e6dSmrg unsigned long valuemask; /* mask for create windows */ 3583e747e6dSmrg XSetWindowAttributes attributes; /* attributes for create windows */ 3593e747e6dSmrg IconMgr *ip; 3603e747e6dSmrg 3613e747e6dSmrg tmp_win->list = NULL; 3623e747e6dSmrg 3633e747e6dSmrg if (tmp_win->iconmgr || tmp_win->transient || Scr->NoIconManagers) 3643e747e6dSmrg return NULL; 3653e747e6dSmrg 3663e747e6dSmrg if (LookInList(Scr->IconMgrNoShow, tmp_win->full_name, &tmp_win->class)) 3673e747e6dSmrg return NULL; 3683e747e6dSmrg if (Scr->IconManagerDontShow && 3693e747e6dSmrg !LookInList(Scr->IconMgrShow, tmp_win->full_name, &tmp_win->class)) 3703e747e6dSmrg return NULL; 3713e747e6dSmrg if ((ip = (IconMgr *)LookInList(Scr->IconMgrs, tmp_win->full_name, 3723e747e6dSmrg &tmp_win->class)) == NULL) 3733e747e6dSmrg ip = &Scr->iconmgr; 3743e747e6dSmrg 3753e747e6dSmrg tmp = (WList *) malloc(sizeof(WList)); 3763e747e6dSmrg tmp->iconmgr = ip; 3773e747e6dSmrg tmp->next = NULL; 3783e747e6dSmrg tmp->active = FALSE; 3793e747e6dSmrg tmp->down = FALSE; 3803e747e6dSmrg 3813e747e6dSmrg InsertInIconManager(ip, tmp, tmp_win); 3823e747e6dSmrg 3833e747e6dSmrg tmp->twm = tmp_win; 3843e747e6dSmrg 3853e747e6dSmrg tmp->fore = Scr->IconManagerC.fore; 3863e747e6dSmrg tmp->back = Scr->IconManagerC.back; 3873e747e6dSmrg tmp->highlight = Scr->IconManagerHighlight; 3883e747e6dSmrg 3893e747e6dSmrg GetColorFromList(Scr->IconManagerFL, tmp_win->full_name, &tmp_win->class, 3903e747e6dSmrg &tmp->fore); 3913e747e6dSmrg GetColorFromList(Scr->IconManagerBL, tmp_win->full_name, &tmp_win->class, 3923e747e6dSmrg &tmp->back); 3933e747e6dSmrg GetColorFromList(Scr->IconManagerHighlightL, tmp_win->full_name, 3943e747e6dSmrg &tmp_win->class, &tmp->highlight); 3953e747e6dSmrg 3963e747e6dSmrg h = Scr->IconManagerFont.height + 10; 3973e747e6dSmrg if (h < (siconify_height + 4)) 3983e747e6dSmrg h = siconify_height + 4; 3993e747e6dSmrg 4003e747e6dSmrg ip->height = h * ip->count; 4013e747e6dSmrg tmp->me = ip->count; 4023e747e6dSmrg tmp->x = -1; 4033e747e6dSmrg tmp->y = -1; 4043e747e6dSmrg 4053e747e6dSmrg valuemask = (CWBackPixel | CWBorderPixel | CWEventMask | CWCursor); 4063e747e6dSmrg attributes.background_pixel = tmp->back; 4073e747e6dSmrg attributes.border_pixel = tmp->back; 4083e747e6dSmrg attributes.event_mask = (KeyPressMask | ButtonPressMask | 4093e747e6dSmrg ButtonReleaseMask | ExposureMask | 4103e747e6dSmrg EnterWindowMask | LeaveWindowMask); 4113e747e6dSmrg attributes.cursor = Scr->IconMgrCursor; 4123e747e6dSmrg tmp->w = XCreateWindow (dpy, ip->w, 0, 0, (unsigned int) 1, 4133e747e6dSmrg (unsigned int) h, (unsigned int) 0, 4143e747e6dSmrg CopyFromParent, (unsigned int) CopyFromParent, 4153e747e6dSmrg (Visual *) CopyFromParent, valuemask, &attributes); 4163e747e6dSmrg 4173e747e6dSmrg 4183e747e6dSmrg valuemask = (CWBackPixel | CWBorderPixel | CWEventMask | CWCursor); 4193e747e6dSmrg attributes.background_pixel = tmp->back; 4203e747e6dSmrg attributes.border_pixel = Scr->Black; 4213e747e6dSmrg attributes.event_mask = (ButtonReleaseMask| ButtonPressMask | 4223e747e6dSmrg ExposureMask); 4233e747e6dSmrg attributes.cursor = Scr->ButtonCursor; 4243e747e6dSmrg tmp->icon = XCreateWindow (dpy, tmp->w, 5, (int) (h - siconify_height)/2, 4253e747e6dSmrg (unsigned int) siconify_width, 4263e747e6dSmrg (unsigned int) siconify_height, 4273e747e6dSmrg (unsigned int) 0, CopyFromParent, 4283e747e6dSmrg (unsigned int) CopyFromParent, 4293e747e6dSmrg (Visual *) CopyFromParent, 4303e747e6dSmrg valuemask, &attributes); 4313e747e6dSmrg 4323e747e6dSmrg ip->count += 1; 4333e747e6dSmrg PackIconManager(ip); 4343e747e6dSmrg XMapWindow(dpy, tmp->w); 4353e747e6dSmrg 4363e747e6dSmrg XSaveContext(dpy, tmp->w, IconManagerContext, (caddr_t) tmp); 4373e747e6dSmrg XSaveContext(dpy, tmp->w, TwmContext, (caddr_t) tmp_win); 4383e747e6dSmrg XSaveContext(dpy, tmp->w, ScreenContext, (caddr_t) Scr); 4393e747e6dSmrg XSaveContext(dpy, tmp->icon, TwmContext, (caddr_t) tmp_win); 4403e747e6dSmrg XSaveContext(dpy, tmp->icon, ScreenContext, (caddr_t) Scr); 4413e747e6dSmrg tmp_win->list = tmp; 4423e747e6dSmrg 4433e747e6dSmrg if (!ip->twm_win->icon) 4443e747e6dSmrg { 4453e747e6dSmrg XMapWindow(dpy, ip->w); 4463e747e6dSmrg XMapWindow(dpy, ip->twm_win->frame); 4473e747e6dSmrg } 4483e747e6dSmrg 4493e747e6dSmrg if (Active == NULL) Active = tmp; 4503e747e6dSmrg 4513e747e6dSmrg return (tmp); 4523e747e6dSmrg} 4533e747e6dSmrg 4543e747e6dSmrg/** 4553e747e6dSmrg * put an allocated entry into an icon manager 4563e747e6dSmrg * 4573e747e6dSmrg * \param ip the icon manager pointer 4583e747e6dSmrg * \param tmp the entry to insert 4593e747e6dSmrg */ 4603e747e6dSmrgvoid InsertInIconManager(IconMgr *ip, WList *tmp, TwmWindow *tmp_win) 4613e747e6dSmrg{ 4623e747e6dSmrg WList *tmp1; 4633e747e6dSmrg int added; 4643e747e6dSmrg int (*compar)(const char *, const char *) 4653e747e6dSmrg = (Scr->CaseSensitive ? strcmp : XmuCompareISOLatin1); 4663e747e6dSmrg 4673e747e6dSmrg added = FALSE; 4683e747e6dSmrg if (ip->first == NULL) 4693e747e6dSmrg { 4703e747e6dSmrg ip->first = tmp; 4713e747e6dSmrg tmp->prev = NULL; 4723e747e6dSmrg ip->last = tmp; 4733e747e6dSmrg added = TRUE; 4743e747e6dSmrg } 4753e747e6dSmrg else if (Scr->SortIconMgr) 4763e747e6dSmrg { 4773e747e6dSmrg for (tmp1 = ip->first; tmp1 != NULL; tmp1 = tmp1->next) 4783e747e6dSmrg { 4793e747e6dSmrg if ((*compar)(tmp_win->icon_name, tmp1->twm->icon_name) < 0) 4803e747e6dSmrg { 4813e747e6dSmrg tmp->next = tmp1; 4823e747e6dSmrg tmp->prev = tmp1->prev; 4833e747e6dSmrg tmp1->prev = tmp; 4843e747e6dSmrg if (tmp->prev == NULL) 4853e747e6dSmrg ip->first = tmp; 4863e747e6dSmrg else 4873e747e6dSmrg tmp->prev->next = tmp; 4883e747e6dSmrg added = TRUE; 4893e747e6dSmrg break; 4903e747e6dSmrg } 4913e747e6dSmrg } 4923e747e6dSmrg } 4933e747e6dSmrg 4943e747e6dSmrg if (!added) 4953e747e6dSmrg { 4963e747e6dSmrg ip->last->next = tmp; 4973e747e6dSmrg tmp->prev = ip->last; 4983e747e6dSmrg ip->last = tmp; 4993e747e6dSmrg } 5003e747e6dSmrg} 5013e747e6dSmrg 5023e747e6dSmrgvoid RemoveFromIconManager(IconMgr *ip, WList *tmp) 5033e747e6dSmrg{ 5043e747e6dSmrg if (tmp->prev == NULL) 5053e747e6dSmrg ip->first = tmp->next; 5063e747e6dSmrg else 5073e747e6dSmrg tmp->prev->next = tmp->next; 5083e747e6dSmrg 5093e747e6dSmrg if (tmp->next == NULL) 5103e747e6dSmrg ip->last = tmp->prev; 5113e747e6dSmrg else 5123e747e6dSmrg tmp->next->prev = tmp->prev; 5133e747e6dSmrg} 5143e747e6dSmrg 5153e747e6dSmrg/** 5163e747e6dSmrg * remove a window from the icon manager 5173e747e6dSmrg * \param tmp_win the TwmWindow structure 5183e747e6dSmrg */ 5193e747e6dSmrgvoid RemoveIconManager(TwmWindow *tmp_win) 5203e747e6dSmrg{ 5213e747e6dSmrg IconMgr *ip; 5223e747e6dSmrg WList *tmp; 5233e747e6dSmrg 5243e747e6dSmrg if (tmp_win->list == NULL) 5253e747e6dSmrg return; 5263e747e6dSmrg 5273e747e6dSmrg tmp = tmp_win->list; 5283e747e6dSmrg tmp_win->list = NULL; 5293e747e6dSmrg ip = tmp->iconmgr; 5303e747e6dSmrg 5313e747e6dSmrg RemoveFromIconManager(ip, tmp); 5323e747e6dSmrg 5333e747e6dSmrg XDeleteContext(dpy, tmp->icon, TwmContext); 5343e747e6dSmrg XDeleteContext(dpy, tmp->icon, ScreenContext); 5353e747e6dSmrg XDestroyWindow(dpy, tmp->icon); 5363e747e6dSmrg XDeleteContext(dpy, tmp->w, IconManagerContext); 5373e747e6dSmrg XDeleteContext(dpy, tmp->w, TwmContext); 5383e747e6dSmrg XDeleteContext(dpy, tmp->w, ScreenContext); 5393e747e6dSmrg XDestroyWindow(dpy, tmp->w); 5403e747e6dSmrg ip->count -= 1; 5413e747e6dSmrg free((char *) tmp); 5423e747e6dSmrg 5433e747e6dSmrg PackIconManager(ip); 5443e747e6dSmrg 5453e747e6dSmrg if (ip->count == 0) 5463e747e6dSmrg { 5473e747e6dSmrg XUnmapWindow(dpy, ip->twm_win->frame); 5483e747e6dSmrg } 5493e747e6dSmrg 5503e747e6dSmrg} 5513e747e6dSmrg 5523e747e6dSmrgvoid ActiveIconManager(WList *active) 5533e747e6dSmrg{ 5543e747e6dSmrg active->active = TRUE; 5553e747e6dSmrg Active = active; 5563e747e6dSmrg Active->iconmgr->active = active; 5573e747e6dSmrg DrawIconManagerBorder(active); 5583e747e6dSmrg} 5593e747e6dSmrg 5603e747e6dSmrgvoid NotActiveIconManager(WList *active) 5613e747e6dSmrg{ 5623e747e6dSmrg active->active = FALSE; 5633e747e6dSmrg DrawIconManagerBorder(active); 5643e747e6dSmrg} 5653e747e6dSmrg 5663e747e6dSmrgvoid DrawIconManagerBorder(WList *tmp) 5673e747e6dSmrg{ 5683e747e6dSmrg { 5693e747e6dSmrg XSetForeground(dpy, Scr->NormalGC, tmp->fore); 5703e747e6dSmrg XDrawRectangle(dpy, tmp->w, Scr->NormalGC, 2, 2, 5713e747e6dSmrg tmp->width-5, tmp->height-5); 5723e747e6dSmrg 5733e747e6dSmrg if (tmp->active && Scr->Highlight) 5743e747e6dSmrg XSetForeground(dpy, Scr->NormalGC, tmp->highlight); 5753e747e6dSmrg else 5763e747e6dSmrg XSetForeground(dpy, Scr->NormalGC, tmp->back); 5773e747e6dSmrg 5783e747e6dSmrg XDrawRectangle(dpy, tmp->w, Scr->NormalGC, 0, 0, 5793e747e6dSmrg tmp->width-1, tmp->height-1); 5803e747e6dSmrg XDrawRectangle(dpy, tmp->w, Scr->NormalGC, 1, 1, 5813e747e6dSmrg tmp->width-3, tmp->height-3); 5823e747e6dSmrg } 5833e747e6dSmrg} 5843e747e6dSmrg 5853e747e6dSmrg/** 5863e747e6dSmrg * sort The Dude 5873e747e6dSmrg * 5883e747e6dSmrg * \param ip a pointer to the icon manager struture 5893e747e6dSmrg */ 5903e747e6dSmrgvoid SortIconManager(IconMgr *ip) 5913e747e6dSmrg{ 5923e747e6dSmrg WList *tmp1, *tmp2; 5933e747e6dSmrg int done; 5943e747e6dSmrg int (*compar)(const char *, const char *) 5953e747e6dSmrg = (Scr->CaseSensitive ? strcmp : XmuCompareISOLatin1); 5963e747e6dSmrg 5973e747e6dSmrg if (ip == NULL) 5983e747e6dSmrg ip = Active->iconmgr; 5993e747e6dSmrg 6003e747e6dSmrg done = FALSE; 6013e747e6dSmrg do 6023e747e6dSmrg { 6033e747e6dSmrg for (tmp1 = ip->first; tmp1 != NULL; tmp1 = tmp1->next) 6043e747e6dSmrg { 6053e747e6dSmrg if ((tmp2 = tmp1->next) == NULL) 6063e747e6dSmrg { 6073e747e6dSmrg done = TRUE; 6083e747e6dSmrg break; 6093e747e6dSmrg } 6103e747e6dSmrg if ((*compar)(tmp1->twm->icon_name, tmp2->twm->icon_name) > 0) 6113e747e6dSmrg { 6123e747e6dSmrg /* take it out and put it back in */ 6133e747e6dSmrg RemoveFromIconManager(ip, tmp2); 6143e747e6dSmrg InsertInIconManager(ip, tmp2, tmp2->twm); 6153e747e6dSmrg break; 6163e747e6dSmrg } 6173e747e6dSmrg } 6183e747e6dSmrg } 6193e747e6dSmrg while (!done); 6203e747e6dSmrg PackIconManager(ip); 6213e747e6dSmrg} 6223e747e6dSmrg 6233e747e6dSmrg/** 6243e747e6dSmrg * pack the icon manager windows following 6253e747e6dSmrg * an addition or deletion 6263e747e6dSmrg * 6273e747e6dSmrg * \param ip a pointer to the icon manager struture 6283e747e6dSmrg */ 6293e747e6dSmrgvoid PackIconManager(IconMgr *ip) 6303e747e6dSmrg{ 6313e747e6dSmrg int newwidth, i, row, col, maxcol, colinc, rowinc, wheight, wwidth; 6323e747e6dSmrg int new_x, new_y; 6333e747e6dSmrg int savewidth; 6343e747e6dSmrg WList *tmp; 6353e747e6dSmrg 6363e747e6dSmrg wheight = Scr->IconManagerFont.height + 10; 6373e747e6dSmrg if (wheight < (siconify_height + 4)) 6383e747e6dSmrg wheight = siconify_height + 4; 6393e747e6dSmrg 6403e747e6dSmrg wwidth = ip->width / ip->columns; 6413e747e6dSmrg 6423e747e6dSmrg rowinc = wheight; 6433e747e6dSmrg colinc = wwidth; 6443e747e6dSmrg 6453e747e6dSmrg row = 0; 6463e747e6dSmrg col = ip->columns; 6473e747e6dSmrg maxcol = 0; 6483e747e6dSmrg for (i = 0, tmp = ip->first; tmp != NULL; i++, tmp = tmp->next) 6493e747e6dSmrg { 6503e747e6dSmrg tmp->me = i; 6513e747e6dSmrg if (++col >= ip->columns) 6523e747e6dSmrg { 6533e747e6dSmrg col = 0; 6543e747e6dSmrg row += 1; 6553e747e6dSmrg } 6563e747e6dSmrg if (col > maxcol) 6573e747e6dSmrg maxcol = col; 6583e747e6dSmrg 6593e747e6dSmrg new_x = col * colinc; 6603e747e6dSmrg new_y = (row-1) * rowinc; 6613e747e6dSmrg 6623e747e6dSmrg /* if the position or size has not changed, don't touch it */ 6633e747e6dSmrg if (tmp->x != new_x || tmp->y != new_y || 6643e747e6dSmrg tmp->width != wwidth || tmp->height != wheight) 6653e747e6dSmrg { 6663e747e6dSmrg XMoveResizeWindow(dpy, tmp->w, new_x, new_y, wwidth, wheight); 6673e747e6dSmrg 6683e747e6dSmrg tmp->row = row-1; 6693e747e6dSmrg tmp->col = col; 6703e747e6dSmrg tmp->x = new_x; 6713e747e6dSmrg tmp->y = new_y; 6723e747e6dSmrg tmp->width = wwidth; 6733e747e6dSmrg tmp->height = wheight; 6743e747e6dSmrg } 6753e747e6dSmrg } 6763e747e6dSmrg maxcol += 1; 6773e747e6dSmrg 6783e747e6dSmrg ip->cur_rows = row; 6793e747e6dSmrg ip->cur_columns = maxcol; 6803e747e6dSmrg ip->height = row * rowinc; 6813e747e6dSmrg if (ip->height == 0) 6823e747e6dSmrg ip->height = rowinc; 6833e747e6dSmrg newwidth = maxcol * colinc; 6843e747e6dSmrg if (newwidth == 0) 6853e747e6dSmrg newwidth = colinc; 6863e747e6dSmrg 6873e747e6dSmrg XResizeWindow(dpy, ip->w, newwidth, ip->height); 6883e747e6dSmrg 6893e747e6dSmrg savewidth = ip->width; 6903e747e6dSmrg if (ip->twm_win) 6913e747e6dSmrg SetupWindow (ip->twm_win, 6923e747e6dSmrg ip->twm_win->frame_x, ip->twm_win->frame_y, 6933e747e6dSmrg newwidth, ip->height + ip->twm_win->title_height, -1); 6943e747e6dSmrg ip->width = savewidth; 6953e747e6dSmrg} 696