iconmgr.c revision f66df612
13e747e6dSmrg/* 2ffd25bcaSmrg * 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 263e747e6dSmrg/*********************************************************************** 273e747e6dSmrg * 283e747e6dSmrg * Icon Manager routines 293e747e6dSmrg * 30f66df612Smrg * 09-Mar-89 Tom LaStrange File Created 313e747e6dSmrg * 323e747e6dSmrg ***********************************************************************/ 333e747e6dSmrg 343e747e6dSmrg#include <stdio.h> 353e747e6dSmrg#include "twm.h" 363e747e6dSmrg#include "util.h" 373e747e6dSmrg#include "parse.h" 383e747e6dSmrg#include "screen.h" 393e747e6dSmrg#include "resize.h" 403e747e6dSmrg#include "add_window.h" 413e747e6dSmrg#include "siconify.bm" 423e747e6dSmrg#include <X11/Xos.h> 433e747e6dSmrg#include <X11/Xmu/CharSet.h> 44c2535118Smrg 45f66df612Smrgstatic void InsertInIconManager(IconMgr *ip, WList *tmp, TwmWindow *tmp_win); 463e747e6dSmrg 47f66df612Smrgint iconmgr_textx = siconify_width + 11; 48c2535118Smrgstatic WList *Active = NULL; 493e747e6dSmrgWList *DownIconManager = NULL; 503e747e6dSmrgint iconifybox_width = siconify_width; 513e747e6dSmrgint iconifybox_height = siconify_height; 523e747e6dSmrg 533e747e6dSmrg/** 543e747e6dSmrg * create all the icon manager windows for this screen. 553e747e6dSmrg */ 56c2535118Smrgvoid 57c2535118SmrgCreateIconManagers(void) 583e747e6dSmrg{ 593e747e6dSmrg IconMgr *p; 603e747e6dSmrg char str[100]; 613e747e6dSmrg char str1[100]; 623e747e6dSmrg Pixel background; 63f66df612Smrg const char *icon_name; 643e747e6dSmrg 653e747e6dSmrg if (Scr->NoIconManagers) 66f66df612Smrg return; 673e747e6dSmrg 68f66df612Smrg if (Scr->siconifyPm == None) { 69f66df612Smrg Scr->siconifyPm = XCreatePixmapFromBitmapData(dpy, Scr->Root, 70f66df612Smrg (char *) siconify_bits, 71f66df612Smrg siconify_width, 72f66df612Smrg siconify_height, 1, 0, 1); 733e747e6dSmrg } 743e747e6dSmrg 75f66df612Smrg for (p = &Scr->iconmgr; p != NULL; p = p->next) { 76f66df612Smrg int mask = XParseGeometry(p->geometry, &JunkX, &JunkY, 77f66df612Smrg (unsigned int *) &p->width, 78f66df612Smrg (unsigned int *) &p->height); 793e747e6dSmrg 80f66df612Smrg if (mask & XNegative) 81f66df612Smrg JunkX = Scr->MyDisplayWidth - p->width - 82f66df612Smrg (2 * Scr->BorderWidth) + JunkX; 833e747e6dSmrg 84f66df612Smrg if (mask & YNegative) 85f66df612Smrg JunkY = Scr->MyDisplayHeight - p->height - 86f66df612Smrg (2 * Scr->BorderWidth) + JunkY; 873e747e6dSmrg 88f66df612Smrg background = Scr->IconManagerC.back; 89f66df612Smrg GetColorFromList(Scr->IconManagerBL, p->name, (XClassHint *) NULL, 90f66df612Smrg &background); 913e747e6dSmrg 92f66df612Smrg p->w = XCreateSimpleWindow(dpy, Scr->Root, 93f66df612Smrg JunkX, JunkY, (unsigned) p->width, 94f66df612Smrg (unsigned) p->height, 1, Scr->Black, 95f66df612Smrg background); 963e747e6dSmrg 97f66df612Smrg snprintf(str, sizeof(str), "%s Icon Manager", p->name); 98f66df612Smrg snprintf(str1, sizeof(str1), "%s Icons", p->name); 99f66df612Smrg if (p->icon_name) 100f66df612Smrg icon_name = p->icon_name; 101f66df612Smrg else 102f66df612Smrg icon_name = str1; 1033e747e6dSmrg 104f66df612Smrg XSetStandardProperties(dpy, p->w, str, icon_name, None, NULL, 0, NULL); 1053e747e6dSmrg 106f66df612Smrg p->twm_win = AddWindow(p->w, TRUE, p); 107f66df612Smrg SetMapStateProp(p->twm_win, WithdrawnState); 1083e747e6dSmrg } 109f66df612Smrg for (p = &Scr->iconmgr; p != NULL; p = p->next) { 110f66df612Smrg GrabButtons(p->twm_win); 111f66df612Smrg GrabKeys(p->twm_win); 1123e747e6dSmrg } 1133e747e6dSmrg} 1143e747e6dSmrg 1153e747e6dSmrg/** 1163e747e6dSmrg * allocate a new icon manager 1173e747e6dSmrg * 1183e747e6dSmrg * \param name the name of this icon manager 1193e747e6dSmrg * \param con_name the name of the associated icon 120f66df612Smrg * \param geom a geometry string to eventually parse 121f66df612Smrg * \param columns the number of columns this icon manager has 1223e747e6dSmrg */ 123f66df612SmrgIconMgr * 124f66df612SmrgAllocateIconManager(char *name, char *icon_name, char *geom, int columns) 1253e747e6dSmrg{ 1263e747e6dSmrg IconMgr *p; 1273e747e6dSmrg 1283e747e6dSmrg#ifdef DEBUG_ICONMGR 1293e747e6dSmrg fprintf(stderr, "AllocateIconManager\n"); 1303e747e6dSmrg fprintf(stderr, " name=\"%s\" icon_name=\"%s\", geom=\"%s\", col=%d\n", 131f66df612Smrg name, icon_name ? icon_name : "<null>", geom, columns); 1323e747e6dSmrg#endif 1333e747e6dSmrg 1343e747e6dSmrg if (Scr->NoIconManagers) 135f66df612Smrg return NULL; 1363e747e6dSmrg 137c2535118Smrg p = malloc(sizeof(IconMgr)); 1383e747e6dSmrg p->name = name; 1393e747e6dSmrg p->icon_name = icon_name; 1403e747e6dSmrg p->geometry = geom; 1413e747e6dSmrg p->columns = columns; 1423e747e6dSmrg p->first = NULL; 1433e747e6dSmrg p->last = NULL; 1443e747e6dSmrg p->active = NULL; 1453e747e6dSmrg p->scr = Scr; 1463e747e6dSmrg p->count = 0; 1473e747e6dSmrg p->x = 0; 1483e747e6dSmrg p->y = 0; 1493e747e6dSmrg p->width = 150; 1503e747e6dSmrg p->height = 10; 1513e747e6dSmrg 1523e747e6dSmrg Scr->iconmgr.lasti->next = p; 1533e747e6dSmrg p->prev = Scr->iconmgr.lasti; 1543e747e6dSmrg Scr->iconmgr.lasti = p; 1553e747e6dSmrg p->next = NULL; 1563e747e6dSmrg 157f66df612Smrg return (p); 1583e747e6dSmrg} 1593e747e6dSmrg 1603e747e6dSmrg/** 1613e747e6dSmrg * move the pointer around in an icon manager 1623e747e6dSmrg * 1633e747e6dSmrg * \param dir one of the following: 1643e747e6dSmrg * - F_FORWICONMGR: forward in the window list 1653e747e6dSmrg * - F_BACKICONMGR: backward in the window list 1663e747e6dSmrg * - F_UPICONMGR: up one row 1673e747e6dSmrg * - F_DOWNICONMG: down one row 1683e747e6dSmrg * - F_LEFTICONMGR: left one column 1693e747e6dSmrg * - F_RIGHTICONMGR: right one column 1703e747e6dSmrg */ 171f66df612Smrgvoid 172f66df612SmrgMoveIconManager(int dir) 1733e747e6dSmrg{ 1743e747e6dSmrg IconMgr *ip; 1753e747e6dSmrg WList *tmp = NULL; 1763e747e6dSmrg int cur_row, cur_col, new_row, new_col; 1773e747e6dSmrg int row_inc, col_inc; 1783e747e6dSmrg int got_it; 1793e747e6dSmrg 180f66df612Smrg if (!Active) 181f66df612Smrg return; 1823e747e6dSmrg 1833e747e6dSmrg cur_row = Active->row; 1843e747e6dSmrg cur_col = Active->col; 1853e747e6dSmrg ip = Active->iconmgr; 1863e747e6dSmrg 1873e747e6dSmrg row_inc = 0; 1883e747e6dSmrg col_inc = 0; 1893e747e6dSmrg got_it = FALSE; 1903e747e6dSmrg 191f66df612Smrg switch (dir) { 192f66df612Smrg case F_FORWICONMGR: 193f66df612Smrg if ((tmp = Active->next) == NULL) 194f66df612Smrg tmp = ip->first; 195f66df612Smrg got_it = TRUE; 196f66df612Smrg break; 197f66df612Smrg 198f66df612Smrg case F_BACKICONMGR: 199f66df612Smrg if ((tmp = Active->prev) == NULL) 200f66df612Smrg tmp = ip->last; 201f66df612Smrg got_it = TRUE; 202f66df612Smrg break; 203f66df612Smrg 204f66df612Smrg case F_UPICONMGR: 205f66df612Smrg row_inc = -1; 206f66df612Smrg break; 207f66df612Smrg 208f66df612Smrg case F_DOWNICONMGR: 209f66df612Smrg row_inc = 1; 210f66df612Smrg break; 211f66df612Smrg 212f66df612Smrg case F_LEFTICONMGR: 213f66df612Smrg col_inc = -1; 214f66df612Smrg break; 215f66df612Smrg 216f66df612Smrg case F_RIGHTICONMGR: 217f66df612Smrg col_inc = 1; 218f66df612Smrg break; 2193e747e6dSmrg } 2203e747e6dSmrg 2213e747e6dSmrg /* If got_it is FALSE ast this point then we got a left, right, 2223e747e6dSmrg * up, or down, command. We will enter this loop until we find 2233e747e6dSmrg * a window to warp to. 2243e747e6dSmrg */ 2253e747e6dSmrg new_row = cur_row; 2263e747e6dSmrg new_col = cur_col; 2273e747e6dSmrg 228f66df612Smrg while (!got_it) { 229f66df612Smrg new_row += row_inc; 230f66df612Smrg new_col += col_inc; 231f66df612Smrg if (new_row < 0) 232f66df612Smrg new_row = ip->cur_rows - 1; 233f66df612Smrg if (new_col < 0) 234f66df612Smrg new_col = ip->cur_columns - 1; 235f66df612Smrg if (new_row >= ip->cur_rows) 236f66df612Smrg new_row = 0; 237f66df612Smrg if (new_col >= ip->cur_columns) 238f66df612Smrg new_col = 0; 239f66df612Smrg 240f66df612Smrg /* Now let's go through the list to see if there is an entry with this 241f66df612Smrg * new position 242f66df612Smrg */ 243f66df612Smrg for (tmp = ip->first; tmp != NULL; tmp = tmp->next) { 244f66df612Smrg if (tmp->row == new_row && tmp->col == new_col) { 245f66df612Smrg got_it = TRUE; 246f66df612Smrg break; 247f66df612Smrg } 248f66df612Smrg } 2493e747e6dSmrg } 2503e747e6dSmrg 251f66df612Smrg if (!got_it) { 252f66df612Smrg twmWarning("unable to find window (%d, %d) in icon manager", 253f66df612Smrg new_row, new_col); 254f66df612Smrg return; 2553e747e6dSmrg } 2563e747e6dSmrg 2573e747e6dSmrg if (tmp == NULL) 258f66df612Smrg return; 2593e747e6dSmrg 2603e747e6dSmrg /* raise the frame so the icon manager is visible */ 2613e747e6dSmrg if (ip->twm_win->mapped) { 262f66df612Smrg XRaiseWindow(dpy, ip->twm_win->frame); 263f66df612Smrg XWarpPointer(dpy, None, tmp->icon, 0, 0, 0, 0, 5, 5); 264f66df612Smrg } 265f66df612Smrg else { 266f66df612Smrg if (tmp->twm->title_height) { 267f66df612Smrg int tbx = Scr->TBInfo.titlex; 268f66df612Smrg int x = tmp->twm->highlightx; 269f66df612Smrg 270f66df612Smrg XWarpPointer(dpy, None, tmp->twm->title_w, 0, 0, 0, 0, 271f66df612Smrg tbx + (x - tbx) / 2, Scr->TitleHeight / 4); 272f66df612Smrg } 273f66df612Smrg else { 274f66df612Smrg XWarpPointer(dpy, None, tmp->twm->w, 0, 0, 0, 0, 5, 5); 275f66df612Smrg } 2763e747e6dSmrg } 2773e747e6dSmrg} 2783e747e6dSmrg 2793e747e6dSmrg/** 2803e747e6dSmrg * jump from one icon manager to another, possibly even on another screen 2813e747e6dSmrg * \param dir one of the following: 282ffd25bcaSmrg * - F_NEXTICONMGR - go to the next icon manager 2833e747e6dSmrg * - F_PREVICONMGR - go to the previous one 2843e747e6dSmrg */ 2853e747e6dSmrg 286f66df612Smrgvoid 287f66df612SmrgJumpIconManager(int dir) 2883e747e6dSmrg{ 2893e747e6dSmrg IconMgr *ip, *tmp_ip = NULL; 2903e747e6dSmrg int got_it = FALSE; 2913e747e6dSmrg 292f66df612Smrg if (!Active) 293f66df612Smrg return; 2943e747e6dSmrg 2953e747e6dSmrg#define ITER(i) (dir == F_NEXTICONMGR ? (i)->next : (i)->prev) 2963e747e6dSmrg#define IPOFSP(sp) (dir == F_NEXTICONMGR ? &(sp->iconmgr) : sp->iconmgr.lasti) 2973e747e6dSmrg#define TEST(ip) if ((ip)->count != 0 && (ip)->twm_win->mapped) \ 298f66df612Smrg { got_it = TRUE; break; } 2993e747e6dSmrg 3003e747e6dSmrg ip = Active->iconmgr; 3013e747e6dSmrg for (tmp_ip = ITER(ip); tmp_ip; tmp_ip = ITER(tmp_ip)) { 302f66df612Smrg TEST(tmp_ip); 3033e747e6dSmrg } 3043e747e6dSmrg 3053e747e6dSmrg if (!got_it) { 306f66df612Smrg int origscreen = ip->scr->screen; 307f66df612Smrg int inc = (dir == F_NEXTICONMGR ? 1 : -1); 308f66df612Smrg int screen; 309f66df612Smrg 310f66df612Smrg for (screen = origscreen + inc;; screen += inc) { 311f66df612Smrg ScreenInfo *sp; 312f66df612Smrg 313f66df612Smrg if (screen >= NumScreens) 314f66df612Smrg screen = 0; 315f66df612Smrg else if (screen < 0) 316f66df612Smrg screen = NumScreens - 1; 317f66df612Smrg 318f66df612Smrg sp = ScreenList[screen]; 319f66df612Smrg if (sp) { 320f66df612Smrg for (tmp_ip = IPOFSP(sp); tmp_ip; tmp_ip = ITER(tmp_ip)) { 321f66df612Smrg TEST(tmp_ip); 322f66df612Smrg } 323f66df612Smrg } 324f66df612Smrg if (got_it || screen == origscreen) 325f66df612Smrg break; 326f66df612Smrg } 3273e747e6dSmrg } 3283e747e6dSmrg 3293e747e6dSmrg#undef ITER 3303e747e6dSmrg#undef IPOFSP 3313e747e6dSmrg#undef TEST 3323e747e6dSmrg 3333e747e6dSmrg if (!got_it) { 334f66df612Smrg Bell(XkbBI_MinorError, 0, None); 335f66df612Smrg return; 3363e747e6dSmrg } 3373e747e6dSmrg 3383e747e6dSmrg /* raise the frame so it is visible */ 3393e747e6dSmrg XRaiseWindow(dpy, tmp_ip->twm_win->frame); 3403e747e6dSmrg if (tmp_ip->active) 341f66df612Smrg XWarpPointer(dpy, None, tmp_ip->active->icon, 0, 0, 0, 0, 5, 5); 3423e747e6dSmrg else 343f66df612Smrg XWarpPointer(dpy, None, tmp_ip->w, 0, 0, 0, 0, 5, 5); 3443e747e6dSmrg} 3453e747e6dSmrg 3463e747e6dSmrg/** 3473e747e6dSmrg * add a window to an icon manager 3483e747e6dSmrg * 3493e747e6dSmrg * \param tmp_win the TwmWindow structure 3503e747e6dSmrg */ 351f66df612SmrgWList * 352f66df612SmrgAddIconManager(TwmWindow *tmp_win) 3533e747e6dSmrg{ 3543e747e6dSmrg WList *tmp; 3553e747e6dSmrg int h; 356f66df612Smrg unsigned long valuemask; /* mask for create windows */ 357f66df612Smrg XSetWindowAttributes attributes; /* attributes for create windows */ 3583e747e6dSmrg IconMgr *ip; 3593e747e6dSmrg 3603e747e6dSmrg tmp_win->list = NULL; 3613e747e6dSmrg 3623e747e6dSmrg if (tmp_win->iconmgr || tmp_win->transient || Scr->NoIconManagers) 363f66df612Smrg return NULL; 3643e747e6dSmrg 3653e747e6dSmrg if (LookInList(Scr->IconMgrNoShow, tmp_win->full_name, &tmp_win->class)) 366f66df612Smrg return NULL; 3673e747e6dSmrg if (Scr->IconManagerDontShow && 368f66df612Smrg !LookInList(Scr->IconMgrShow, tmp_win->full_name, &tmp_win->class)) 369f66df612Smrg return NULL; 370f66df612Smrg if ((ip = (IconMgr *) LookInList(Scr->IconMgrs, tmp_win->full_name, 371f66df612Smrg &tmp_win->class)) == NULL) 372f66df612Smrg ip = &Scr->iconmgr; 3733e747e6dSmrg 374c2535118Smrg tmp = malloc(sizeof(WList)); 3753e747e6dSmrg tmp->iconmgr = ip; 3763e747e6dSmrg tmp->next = NULL; 3773e747e6dSmrg tmp->active = FALSE; 3783e747e6dSmrg tmp->down = FALSE; 3793e747e6dSmrg 3803e747e6dSmrg InsertInIconManager(ip, tmp, tmp_win); 3813e747e6dSmrg 3823e747e6dSmrg tmp->twm = tmp_win; 3833e747e6dSmrg 3843e747e6dSmrg tmp->fore = Scr->IconManagerC.fore; 3853e747e6dSmrg tmp->back = Scr->IconManagerC.back; 3863e747e6dSmrg tmp->highlight = Scr->IconManagerHighlight; 3873e747e6dSmrg 3883e747e6dSmrg GetColorFromList(Scr->IconManagerFL, tmp_win->full_name, &tmp_win->class, 389f66df612Smrg &tmp->fore); 3903e747e6dSmrg GetColorFromList(Scr->IconManagerBL, tmp_win->full_name, &tmp_win->class, 391f66df612Smrg &tmp->back); 3923e747e6dSmrg GetColorFromList(Scr->IconManagerHighlightL, tmp_win->full_name, 393f66df612Smrg &tmp_win->class, &tmp->highlight); 3943e747e6dSmrg 3953e747e6dSmrg h = Scr->IconManagerFont.height + 10; 3963e747e6dSmrg if (h < (siconify_height + 4)) 397f66df612Smrg h = siconify_height + 4; 3983e747e6dSmrg 3993e747e6dSmrg ip->height = h * ip->count; 4003e747e6dSmrg tmp->me = ip->count; 4013e747e6dSmrg tmp->x = -1; 4023e747e6dSmrg tmp->y = -1; 403ffd25bcaSmrg 4043e747e6dSmrg valuemask = (CWBackPixel | CWBorderPixel | CWEventMask | CWCursor); 4053e747e6dSmrg attributes.background_pixel = tmp->back; 4063e747e6dSmrg attributes.border_pixel = tmp->back; 4073e747e6dSmrg attributes.event_mask = (KeyPressMask | ButtonPressMask | 408f66df612Smrg ButtonReleaseMask | ExposureMask | 409f66df612Smrg EnterWindowMask | LeaveWindowMask); 4103e747e6dSmrg attributes.cursor = Scr->IconMgrCursor; 411f66df612Smrg tmp->w = XCreateWindow(dpy, ip->w, 0, 0, (unsigned int) 1, 412f66df612Smrg (unsigned int) h, (unsigned int) 0, 413f66df612Smrg CopyFromParent, (unsigned int) CopyFromParent, 414f66df612Smrg (Visual *) CopyFromParent, valuemask, &attributes); 4153e747e6dSmrg 4163e747e6dSmrg valuemask = (CWBackPixel | CWBorderPixel | CWEventMask | CWCursor); 4173e747e6dSmrg attributes.background_pixel = tmp->back; 4183e747e6dSmrg attributes.border_pixel = Scr->Black; 419f66df612Smrg attributes.event_mask = (ButtonReleaseMask | ButtonPressMask | 420f66df612Smrg ExposureMask); 4213e747e6dSmrg attributes.cursor = Scr->ButtonCursor; 422f66df612Smrg tmp->icon = XCreateWindow(dpy, tmp->w, 5, (int) (h - siconify_height) / 2, 423f66df612Smrg (unsigned int) siconify_width, 424f66df612Smrg (unsigned int) siconify_height, 425f66df612Smrg (unsigned int) 0, CopyFromParent, 426f66df612Smrg (unsigned int) CopyFromParent, 427f66df612Smrg (Visual *) CopyFromParent, 428f66df612Smrg valuemask, &attributes); 4293e747e6dSmrg 4303e747e6dSmrg ip->count += 1; 4313e747e6dSmrg PackIconManager(ip); 4323e747e6dSmrg XMapWindow(dpy, tmp->w); 4333e747e6dSmrg 434f66df612Smrg XSaveContext(dpy, tmp->w, IconManagerContext, (XPointer) tmp); 435f66df612Smrg XSaveContext(dpy, tmp->w, TwmContext, (XPointer) tmp_win); 436f66df612Smrg XSaveContext(dpy, tmp->w, ScreenContext, (XPointer) Scr); 437f66df612Smrg XSaveContext(dpy, tmp->icon, TwmContext, (XPointer) tmp_win); 438f66df612Smrg XSaveContext(dpy, tmp->icon, ScreenContext, (XPointer) Scr); 4393e747e6dSmrg tmp_win->list = tmp; 4403e747e6dSmrg 441f66df612Smrg if (!ip->twm_win->icon) { 442f66df612Smrg XMapWindow(dpy, ip->w); 443f66df612Smrg XMapWindow(dpy, ip->twm_win->frame); 4443e747e6dSmrg } 4453e747e6dSmrg 446f66df612Smrg if (Active == NULL) 447f66df612Smrg Active = tmp; 4483e747e6dSmrg 4493e747e6dSmrg return (tmp); 4503e747e6dSmrg} 4513e747e6dSmrg 4523e747e6dSmrg/** 4533e747e6dSmrg * put an allocated entry into an icon manager 4543e747e6dSmrg * 4553e747e6dSmrg * \param ip the icon manager pointer 4563e747e6dSmrg * \param tmp the entry to insert 4573e747e6dSmrg */ 458f66df612Smrgstatic void 459f66df612SmrgInsertInIconManager(IconMgr *ip, WList *tmp, TwmWindow *tmp_win) 4603e747e6dSmrg{ 4613e747e6dSmrg WList *tmp1; 4623e747e6dSmrg int added; 463f66df612Smrg int (*compar) (const char *, const char *) 464f66df612Smrg = (Scr->CaseSensitive ? strcmp : XmuCompareISOLatin1); 4653e747e6dSmrg 4663e747e6dSmrg added = FALSE; 467f66df612Smrg if (ip->first == NULL) { 468f66df612Smrg ip->first = tmp; 469f66df612Smrg tmp->prev = NULL; 470f66df612Smrg ip->last = tmp; 471f66df612Smrg added = TRUE; 4723e747e6dSmrg } 473f66df612Smrg else if (Scr->SortIconMgr) { 474f66df612Smrg for (tmp1 = ip->first; tmp1 != NULL; tmp1 = tmp1->next) { 475f66df612Smrg if ((*compar) (tmp_win->icon_name, tmp1->twm->icon_name) < 0) { 476f66df612Smrg tmp->next = tmp1; 477f66df612Smrg tmp->prev = tmp1->prev; 478f66df612Smrg tmp1->prev = tmp; 479f66df612Smrg if (tmp->prev == NULL) 480f66df612Smrg ip->first = tmp; 481f66df612Smrg else 482f66df612Smrg tmp->prev->next = tmp; 483f66df612Smrg added = TRUE; 484f66df612Smrg break; 485f66df612Smrg } 486f66df612Smrg } 4873e747e6dSmrg } 4883e747e6dSmrg 489f66df612Smrg if (!added) { 490f66df612Smrg ip->last->next = tmp; 491f66df612Smrg tmp->prev = ip->last; 492f66df612Smrg ip->last = tmp; 4933e747e6dSmrg } 4943e747e6dSmrg} 4953e747e6dSmrg 496f66df612Smrgstatic void 497f66df612SmrgRemoveFromIconManager(IconMgr *ip, WList *tmp) 4983e747e6dSmrg{ 4993e747e6dSmrg if (tmp->prev == NULL) 500f66df612Smrg ip->first = tmp->next; 5013e747e6dSmrg else 502f66df612Smrg tmp->prev->next = tmp->next; 5033e747e6dSmrg 5043e747e6dSmrg if (tmp->next == NULL) 505f66df612Smrg ip->last = tmp->prev; 5063e747e6dSmrg else 507f66df612Smrg tmp->next->prev = tmp->prev; 5083e747e6dSmrg} 5093e747e6dSmrg 5103e747e6dSmrg/** 5113e747e6dSmrg * remove a window from the icon manager 5123e747e6dSmrg * \param tmp_win the TwmWindow structure 5133e747e6dSmrg */ 514f66df612Smrgvoid 515f66df612SmrgRemoveIconManager(TwmWindow *tmp_win) 5163e747e6dSmrg{ 5173e747e6dSmrg IconMgr *ip; 5183e747e6dSmrg WList *tmp; 5193e747e6dSmrg 5203e747e6dSmrg if (tmp_win->list == NULL) 521f66df612Smrg return; 5223e747e6dSmrg 5233e747e6dSmrg tmp = tmp_win->list; 5243e747e6dSmrg tmp_win->list = NULL; 5253e747e6dSmrg ip = tmp->iconmgr; 5263e747e6dSmrg 5273e747e6dSmrg RemoveFromIconManager(ip, tmp); 528ffd25bcaSmrg 5293e747e6dSmrg XDeleteContext(dpy, tmp->icon, TwmContext); 5303e747e6dSmrg XDeleteContext(dpy, tmp->icon, ScreenContext); 5313e747e6dSmrg XDestroyWindow(dpy, tmp->icon); 5323e747e6dSmrg XDeleteContext(dpy, tmp->w, IconManagerContext); 5333e747e6dSmrg XDeleteContext(dpy, tmp->w, TwmContext); 5343e747e6dSmrg XDeleteContext(dpy, tmp->w, ScreenContext); 5353e747e6dSmrg XDestroyWindow(dpy, tmp->w); 5363e747e6dSmrg ip->count -= 1; 537c2535118Smrg free(tmp); 5383e747e6dSmrg 5393e747e6dSmrg PackIconManager(ip); 5403e747e6dSmrg 541f66df612Smrg if (ip->count == 0) { 542f66df612Smrg XUnmapWindow(dpy, ip->twm_win->frame); 5433e747e6dSmrg } 5443e747e6dSmrg 5453e747e6dSmrg} 5463e747e6dSmrg 547f66df612Smrgvoid 548f66df612SmrgActiveIconManager(WList *active) 5493e747e6dSmrg{ 5503e747e6dSmrg active->active = TRUE; 5513e747e6dSmrg Active = active; 5523e747e6dSmrg Active->iconmgr->active = active; 5533e747e6dSmrg DrawIconManagerBorder(active); 5543e747e6dSmrg} 5553e747e6dSmrg 556f66df612Smrgvoid 557f66df612SmrgNotActiveIconManager(WList *active) 5583e747e6dSmrg{ 5593e747e6dSmrg active->active = FALSE; 5603e747e6dSmrg DrawIconManagerBorder(active); 5613e747e6dSmrg} 5623e747e6dSmrg 563f66df612Smrgvoid 564f66df612SmrgDrawIconManagerBorder(WList *tmp) 5653e747e6dSmrg{ 5663e747e6dSmrg { 567f66df612Smrg XSetForeground(dpy, Scr->NormalGC, tmp->fore); 568f66df612Smrg XDrawRectangle(dpy, tmp->w, Scr->NormalGC, 2, 2, 569f66df612Smrg (unsigned) (tmp->width - 5), 570f66df612Smrg (unsigned) (tmp->height - 5)); 571f66df612Smrg 572f66df612Smrg if (tmp->active && Scr->Highlight) 573f66df612Smrg XSetForeground(dpy, Scr->NormalGC, tmp->highlight); 574f66df612Smrg else 575f66df612Smrg XSetForeground(dpy, Scr->NormalGC, tmp->back); 576f66df612Smrg 577f66df612Smrg XDrawRectangle(dpy, tmp->w, Scr->NormalGC, 0, 0, 578f66df612Smrg (unsigned) (tmp->width - 1), 579f66df612Smrg (unsigned) (tmp->height - 1)); 580f66df612Smrg XDrawRectangle(dpy, tmp->w, Scr->NormalGC, 1, 1, 581f66df612Smrg (unsigned) (tmp->width - 3), 582f66df612Smrg (unsigned) (tmp->height - 3)); 5833e747e6dSmrg } 5843e747e6dSmrg} 5853e747e6dSmrg 5863e747e6dSmrg/** 5873e747e6dSmrg * sort The Dude 5883e747e6dSmrg * 589f66df612Smrg * \param ip a pointer to the icon manager structure 5903e747e6dSmrg */ 591f66df612Smrgvoid 592f66df612SmrgSortIconManager(IconMgr *ip) 5933e747e6dSmrg{ 5943e747e6dSmrg WList *tmp1, *tmp2; 5953e747e6dSmrg int done; 596f66df612Smrg int (*compar) (const char *, const char *) 597f66df612Smrg = (Scr->CaseSensitive ? strcmp : XmuCompareISOLatin1); 5983e747e6dSmrg 5993e747e6dSmrg if (ip == NULL) 600f66df612Smrg ip = Active->iconmgr; 6013e747e6dSmrg 6023e747e6dSmrg done = FALSE; 603f66df612Smrg do { 604f66df612Smrg for (tmp1 = ip->first; tmp1 != NULL; tmp1 = tmp1->next) { 605f66df612Smrg if ((tmp2 = tmp1->next) == NULL) { 606f66df612Smrg done = TRUE; 607f66df612Smrg break; 608f66df612Smrg } 609f66df612Smrg if ((*compar) (tmp1->twm->icon_name, tmp2->twm->icon_name) > 0) { 610f66df612Smrg /* take it out and put it back in */ 611f66df612Smrg RemoveFromIconManager(ip, tmp2); 612f66df612Smrg InsertInIconManager(ip, tmp2, tmp2->twm); 613f66df612Smrg break; 614f66df612Smrg } 615f66df612Smrg } 6163e747e6dSmrg } 6173e747e6dSmrg while (!done); 6183e747e6dSmrg PackIconManager(ip); 6193e747e6dSmrg} 6203e747e6dSmrg 6213e747e6dSmrg/** 622ffd25bcaSmrg * pack the icon manager windows following 623f66df612Smrg * an addition or deletion 6243e747e6dSmrg * 625f66df612Smrg * \param ip a pointer to the icon manager structure 6263e747e6dSmrg */ 627f66df612Smrgvoid 628f66df612SmrgPackIconManager(IconMgr *ip) 6293e747e6dSmrg{ 630f66df612Smrg int newwidth, i, row, col, maxcol, colinc, rowinc, wheight, wwidth; 6313e747e6dSmrg int savewidth; 6323e747e6dSmrg WList *tmp; 6333e747e6dSmrg 6343e747e6dSmrg wheight = Scr->IconManagerFont.height + 10; 6353e747e6dSmrg if (wheight < (siconify_height + 4)) 636f66df612Smrg wheight = siconify_height + 4; 6373e747e6dSmrg 6383e747e6dSmrg wwidth = ip->width / ip->columns; 6393e747e6dSmrg 6403e747e6dSmrg rowinc = wheight; 6413e747e6dSmrg colinc = wwidth; 6423e747e6dSmrg 6433e747e6dSmrg row = 0; 6443e747e6dSmrg col = ip->columns; 6453e747e6dSmrg maxcol = 0; 646f66df612Smrg 647f66df612Smrg for (i = 0, tmp = ip->first; tmp != NULL; i++, tmp = tmp->next) { 648f66df612Smrg int new_x, new_y; 649f66df612Smrg 650f66df612Smrg tmp->me = i; 651f66df612Smrg if (++col >= ip->columns) { 652f66df612Smrg col = 0; 653f66df612Smrg row += 1; 654f66df612Smrg } 655f66df612Smrg if (col > maxcol) 656f66df612Smrg maxcol = col; 657f66df612Smrg 658f66df612Smrg new_x = col * colinc; 659f66df612Smrg new_y = (row - 1) * rowinc; 660f66df612Smrg 661f66df612Smrg /* if the position or size has not changed, don't touch it */ 662f66df612Smrg if (tmp->x != new_x || tmp->y != new_y || 663f66df612Smrg tmp->width != wwidth || tmp->height != wheight) { 664f66df612Smrg XMoveResizeWindow(dpy, tmp->w, 665f66df612Smrg new_x, new_y, 666f66df612Smrg (unsigned) wwidth, (unsigned) wheight); 667f66df612Smrg 668f66df612Smrg tmp->row = row - 1; 669f66df612Smrg tmp->col = col; 670f66df612Smrg tmp->x = new_x; 671f66df612Smrg tmp->y = new_y; 672f66df612Smrg tmp->width = wwidth; 673f66df612Smrg tmp->height = wheight; 674f66df612Smrg } 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) 682f66df612Smrg ip->height = rowinc; 6833e747e6dSmrg newwidth = maxcol * colinc; 6843e747e6dSmrg if (newwidth == 0) 685f66df612Smrg newwidth = colinc; 6863e747e6dSmrg 687f66df612Smrg XResizeWindow(dpy, ip->w, (unsigned) newwidth, (unsigned) ip->height); 6883e747e6dSmrg 6893e747e6dSmrg savewidth = ip->width; 6903e747e6dSmrg if (ip->twm_win) 691f66df612Smrg SetupWindow(ip->twm_win, 692f66df612Smrg ip->twm_win->frame_x, ip->twm_win->frame_y, 693f66df612Smrg newwidth, ip->height + ip->twm_win->title_height, -1); 6943e747e6dSmrg ip->width = savewidth; 6953e747e6dSmrg} 696