~ctwm/ctwm/trunk

« back to all changes in this revision

Viewing changes to add_window.c

  • Committer: Richard Levitte
  • Author(s): Claude Lecommandeur
  • Date: 2003-02-02 17:06:24 UTC
  • Revision ID: richard@levitte.org-20030202170624-ufdh8dgunc7nfrg7
Tags: ctwm-3.4
CTWM version 3.4

Monotone-Parent: c700ef3475b277d9b00913b22b99fdfe49782d14
Monotone-Revision: 1be23fb8d6d29219f3dc9717e362a5814b7eb554

Show diffs side-by-side

added added

removed removed

Lines of Context:
84
84
#include "events.h"
85
85
#include "menus.h"
86
86
#include "screen.h"
 
87
#include "icons.h"
87
88
#include "iconmgr.h"
88
89
 
89
90
#define gray_width 2
104
105
void ClickToFocusGrab   ();
105
106
void ClickToFocusUngrab ();
106
107
 
 
108
static void             splitWindowRegionEntry ();
 
109
static WindowEntry      *findWindowEntry ();
 
110
static WindowEntry      *prevWindowEntry ();
 
111
static void             mergeWindowEntries ();
 
112
 
107
113
char NoName[] = "Untitled"; /* name if no name is specified */
108
114
int  resizeWhenAdd;
109
115
 
446
452
        gravx = gravy = -1;
447
453
    }
448
454
    else
 
455
#endif
449
456
    {
450
457
        GetGravityOffsets (tmp_win, &gravx, &gravy);
451
458
    }
452
 
#endif
453
459
 
454
460
    /*
455
461
     * Don't bother user if:
469
475
          tmp_win->attr.x != 0 || tmp_win->attr.y != 0)))
470
476
      ask_user = FALSE;
471
477
 
 
478
    SetupOccupation (tmp_win);
 
479
    tmp_win->frame_width  = tmp_win->attr.width  + 2 * tmp_win->frame_bw3D;
 
480
    tmp_win->frame_height = tmp_win->attr.height + 2 * tmp_win->frame_bw3D +
 
481
                            tmp_win->title_height;
 
482
    ConstrainSize (tmp_win, &tmp_win->frame_width, &tmp_win->frame_height);
 
483
    if (PlaceWindowInRegion (tmp_win, &(tmp_win->attr.x), &(tmp_win->attr.y))) {
 
484
        ask_user = False;
 
485
    }
472
486
    /*
473
487
     * do any prompting for position
474
488
     */
475
 
    SetupOccupation (tmp_win);
476
489
 
477
490
#ifdef X11R6
478
491
    if (HandlingEvents && ask_user && !restoredFromPrevSession) {
815
828
                            &bytesafter,(unsigned char **)&tmp_win->icon_name))
816
829
        tmp_win->icon_name = tmp_win->name;
817
830
#endif /* NO_LOCALE */
 
831
 
818
832
    if (tmp_win->icon_name == NULL)
819
833
        tmp_win->icon_name = tmp_win->name;
 
834
#ifdef CLAUDE
 
835
    else if ((strlen (tmp_win->icon_name) > 11) &&
 
836
            (strncmp (tmp_win->icon_name, "Netscape: ", 10) == 0)) {
 
837
        char *tmp;
 
838
 
 
839
        tmp = strdup (tmp_win->icon_name + 10);
 
840
        XFree ((char*) tmp_win->icon_name);
 
841
        tmp_win->icon_name = tmp;
 
842
    }
 
843
#endif
820
844
 
821
845
    if (tmp_win->old_bw) XSetWindowBorderWidth (dpy, tmp_win->w, 0);
822
846
 
1069
1093
            XSaveContext(dpy, tmp_win->hilite_wr, TwmContext, (caddr_t)tmp_win);
1070
1094
            XSaveContext(dpy, tmp_win->hilite_wr, ScreenContext, (caddr_t)Scr);
1071
1095
        }
 
1096
        if (tmp_win->lolite_wl)
 
1097
        {
 
1098
            XSaveContext(dpy, tmp_win->lolite_wl, TwmContext, (caddr_t)tmp_win);
 
1099
            XSaveContext(dpy, tmp_win->lolite_wl, ScreenContext, (caddr_t)Scr);
 
1100
        }
 
1101
        if (tmp_win->lolite_wr)
 
1102
        {
 
1103
            XSaveContext(dpy, tmp_win->lolite_wr, TwmContext, (caddr_t)tmp_win);
 
1104
            XSaveContext(dpy, tmp_win->lolite_wr, ScreenContext, (caddr_t)Scr);
 
1105
        }
1072
1106
    }
1073
1107
 
1074
1108
    XUngrabServer(dpy);
1261
1295
    }
1262
1296
}
1263
1297
 
 
1298
void ComputeCommonTitleOffsets ()
 
1299
{
 
1300
    int buttonwidth = (Scr->TBInfo.width + Scr->TBInfo.pad);
 
1301
 
 
1302
    Scr->TBInfo.leftx = Scr->TBInfo.rightoff = Scr->FramePadding;
 
1303
    if (Scr->TBInfo.nleft  > 0) Scr->TBInfo.leftx    += Scr->ButtonIndent;
 
1304
    if (Scr->TBInfo.nright > 0) Scr->TBInfo.rightoff += (Scr->ButtonIndent +
 
1305
                               (Scr->TBInfo.nright * buttonwidth) -
 
1306
                                Scr->TBInfo.pad);
 
1307
 
 
1308
    Scr->TBInfo.titlex = (Scr->TBInfo.leftx +
 
1309
                                (Scr->TBInfo.nleft * buttonwidth) -
 
1310
                                Scr->TBInfo.pad +
 
1311
                                Scr->TitlePadding);
 
1312
}
 
1313
 
1264
1314
static void CreateHighlightWindows (tmp_win)
1265
1315
    TwmWindow *tmp_win;
1266
1316
{
1354
1404
                       Scr->d_visual, valuemask, &attributes);
1355
1405
}
1356
1406
 
1357
 
 
1358
 
void ComputeCommonTitleOffsets ()
 
1407
static void CreateLowlightWindows (tmp_win)
 
1408
    TwmWindow *tmp_win;
1359
1409
{
1360
 
    int buttonwidth = (Scr->TBInfo.width + Scr->TBInfo.pad);
1361
 
 
1362
 
    Scr->TBInfo.leftx = Scr->TBInfo.rightoff = Scr->FramePadding;
1363
 
    if (Scr->TBInfo.nleft  > 0) Scr->TBInfo.leftx    += Scr->ButtonIndent;
1364
 
    if (Scr->TBInfo.nright > 0) Scr->TBInfo.rightoff += (Scr->ButtonIndent +
1365
 
                               (Scr->TBInfo.nright * buttonwidth) -
1366
 
                                Scr->TBInfo.pad);
1367
 
 
1368
 
    Scr->TBInfo.titlex = (Scr->TBInfo.leftx +
1369
 
                                (Scr->TBInfo.nleft * buttonwidth) -
1370
 
                                Scr->TBInfo.pad +
1371
 
                                Scr->TitlePadding);
 
1410
    XSetWindowAttributes attributes;    /* attributes for create windows */
 
1411
    unsigned long valuemask;
 
1412
    int h = (Scr->TitleHeight - 2 * Scr->FramePadding);
 
1413
    int y = Scr->FramePadding;
 
1414
    ColorPair cp;
 
1415
 
 
1416
    if (!Scr->UseSunkTitlePixmap || ! tmp_win->titlehighlight) {
 
1417
        tmp_win->lolite_wl = (Window) 0;
 
1418
        tmp_win->lolite_wr = (Window) 0;
 
1419
        return;
 
1420
    }
 
1421
    /*
 
1422
     * If a special highlight pixmap was given, use that.  Otherwise,
 
1423
     * use a nice, even gray pattern.  The old horizontal lines look really
 
1424
     * awful on interlaced monitors (as well as resembling other looks a
 
1425
     * little bit too closely), but can be used by putting
 
1426
     *
 
1427
     *                 Pixmaps { TitleHighlight "hline2" }
 
1428
     *
 
1429
     * (or whatever the horizontal line bitmap is named) in the startup
 
1430
     * file.  If all else fails, use the foreground color to look like a
 
1431
     * solid line.
 
1432
     */
 
1433
 
 
1434
    if (! tmp_win->LoliteImage) {
 
1435
        if (Scr->HighlightPixmapName) {
 
1436
            cp = tmp_win->title;
 
1437
            cp.shadc = tmp_win->title.shadd;
 
1438
            cp.shadd = tmp_win->title.shadc;
 
1439
            tmp_win->LoliteImage = GetImage (Scr->HighlightPixmapName, cp);
 
1440
        }
 
1441
    }
 
1442
    if (tmp_win->LoliteImage) {
 
1443
        valuemask = CWBackPixmap;
 
1444
        attributes.background_pixmap = tmp_win->LoliteImage->pixmap;
 
1445
    } else {
 
1446
        valuemask = CWBackPixel;
 
1447
        attributes.background_pixel = tmp_win->title.fore;
 
1448
    }
 
1449
 
 
1450
    if (Scr->use3Dtitles) {
 
1451
        y += 2;
 
1452
        h -= 4;
 
1453
    }
 
1454
    if (Scr->TitleJustification == J_LEFT)
 
1455
        tmp_win->lolite_wl = (Window) 0;
 
1456
    else
 
1457
        tmp_win->lolite_wl = XCreateWindow (dpy, tmp_win->title_w, 0, y,
 
1458
                       (unsigned int) Scr->TBInfo.width, (unsigned int) h,
 
1459
                       (unsigned int) 0, Scr->d_depth, (unsigned int) CopyFromParent,
 
1460
                       Scr->d_visual, valuemask, &attributes);
 
1461
 
 
1462
    if (Scr->TitleJustification == J_RIGHT)
 
1463
        tmp_win->lolite_wr = (Window) 0;
 
1464
    else
 
1465
        tmp_win->lolite_wr = XCreateWindow (dpy, tmp_win->title_w, 0, y,
 
1466
                       (unsigned int) Scr->TBInfo.width, (unsigned int) h,
 
1467
                       (unsigned int) 0,  Scr->d_depth, (unsigned int) CopyFromParent,
 
1468
                       Scr->d_visual, valuemask, &attributes);
1372
1469
}
1373
1470
 
 
1471
 
1374
1472
void ComputeWindowTitleOffsets (tmp_win, width, squeeze)
1375
1473
    TwmWindow *tmp_win;
1376
1474
    Bool squeeze;
1486
1584
 
1487
1585
    if (tmp_win->title_height == 0)
1488
1586
    {
1489
 
        tmp_win->hilite_wl = 0;
1490
 
        tmp_win->hilite_wr = 0;
 
1587
        tmp_win->hilite_wl = (Window) 0;
 
1588
        tmp_win->hilite_wr = (Window) 0;
 
1589
        tmp_win->lolite_wl = (Window) 0;
 
1590
        tmp_win->lolite_wr = (Window) 0;
1491
1591
        return;
1492
1592
    }
1493
1593
 
1553
1653
    }
1554
1654
 
1555
1655
    CreateHighlightWindows (tmp_win);
 
1656
    CreateLowlightWindows  (tmp_win);
1556
1657
    XMapSubwindows(dpy, tmp_win->title_w);
1557
1658
    if (tmp_win->hilite_wl) XUnmapWindow(dpy, tmp_win->hilite_wl);
1558
1659
    if (tmp_win->hilite_wr) XUnmapWindow(dpy, tmp_win->hilite_wr);
 
1660
    if (tmp_win->lolite_wl) XMapWindow(dpy, tmp_win->lolite_wl);
 
1661
    if (tmp_win->lolite_wr) XMapWindow(dpy, tmp_win->lolite_wr);
1559
1662
    return;
1560
1663
}
1561
1664
 
1858
1961
    }
1859
1962
    t->HiliteImage = image->next;
1860
1963
}
 
1964
 
 
1965
name_list **AddWindowRegion (geom, grav1, grav2)
 
1966
char *geom;
 
1967
int  grav1, grav2;
 
1968
{
 
1969
    WindowRegion *wr;
 
1970
    int mask;
 
1971
 
 
1972
    wr = (WindowRegion*) malloc (sizeof (WindowRegion));
 
1973
    wr->next = NULL;
 
1974
 
 
1975
    if (!Scr->FirstWindowRegion) Scr->FirstWindowRegion = wr;
 
1976
 
 
1977
    wr->entries    = NULL;
 
1978
    wr->clientlist = NULL;
 
1979
    wr->grav1      = grav1;
 
1980
    wr->grav2      = grav2;
 
1981
    wr->x = wr->y = wr->w = wr->h = 0;
 
1982
 
 
1983
    mask = XParseGeometry (geom, &wr->x, &wr->y, (unsigned int*) &wr->w,
 
1984
                                                 (unsigned int*) &wr->h);
 
1985
 
 
1986
    if (mask & XNegative) wr->x += Scr->MyDisplayWidth  - wr->w;
 
1987
    if (mask & YNegative) wr->y += Scr->MyDisplayHeight - wr->h;
 
1988
 
 
1989
    return (&(wr->clientlist));
 
1990
}
 
1991
 
 
1992
void CreateWindowRegions () {
 
1993
    WindowRegion  *wr, *wr1 = NULL, *wr2 = NULL;
 
1994
    WorkSpaceList *wl;
 
1995
 
 
1996
    for (wl = Scr->workSpaceMgr.workSpaceList; wl != NULL; wl = wl->next) {
 
1997
        wl->FirstWindowRegion = NULL;
 
1998
        wr2 = NULL;
 
1999
        for (wr = Scr->FirstWindowRegion; wr != NULL; wr = wr->next) {
 
2000
            wr1  = (WindowRegion*) malloc (sizeof (WindowRegion));
 
2001
            *wr1 = *wr;
 
2002
            wr1->entries = (WindowEntry*) malloc (sizeof (WindowEntry));
 
2003
            wr1->entries->next = 0;
 
2004
            wr1->entries->x = wr1->x;
 
2005
            wr1->entries->y = wr1->y;
 
2006
            wr1->entries->w = wr1->w;
 
2007
            wr1->entries->h = wr1->h;
 
2008
            wr1->entries->twm_win = (TwmWindow*) 0;
 
2009
            wr1->entries->used = 0;
 
2010
            if (wr2) wr2->next = wr1; else wl->FirstWindowRegion = wr1;
 
2011
            wr2 = wr1;
 
2012
        }
 
2013
        if (wr1) wr1->next = NULL;
 
2014
    }
 
2015
}
 
2016
 
 
2017
 
 
2018
Bool PlaceWindowInRegion (tmp_win, final_x, final_y)
 
2019
TwmWindow *tmp_win;
 
2020
int       *final_x, *final_y;
 
2021
{
 
2022
    WindowRegion  *wr;
 
2023
    WindowEntry   *we;
 
2024
    int            w, h;
 
2025
    WorkSpaceList *wl;
 
2026
 
 
2027
    if (!Scr->FirstWindowRegion) return (False);
 
2028
    for (wl = Scr->workSpaceMgr.workSpaceList; wl != NULL; wl = wl->next) {
 
2029
        if (OCCUPY (tmp_win, wl)) break;
 
2030
    }
 
2031
    if (!wl) return (False);
 
2032
    w = tmp_win->frame_width;
 
2033
    h = tmp_win->frame_height;
 
2034
    we = (WindowEntry*) 0;
 
2035
    for (wr = wl->FirstWindowRegion; wr; wr = wr->next) {
 
2036
        if (LookInList (wr->clientlist, tmp_win->full_name, &tmp_win->class)) {
 
2037
            for (we = wr->entries; we; we=we->next) {
 
2038
                if (we->used) continue;
 
2039
                if (we->w >= w && we->h >= h) break;
 
2040
            }
 
2041
            if (we) break;
 
2042
        }
 
2043
    }
 
2044
    tmp_win->wr = (WindowRegion*) 0;
 
2045
    if (!we) return (False);
 
2046
 
 
2047
    splitWindowRegionEntry (we, wr->grav1, wr->grav2, w, h);
 
2048
    we->used = 1;
 
2049
    we->twm_win = tmp_win;
 
2050
    *final_x = we->x;
 
2051
    *final_y = we->y;
 
2052
    tmp_win->wr = wr;
 
2053
    return (True);
 
2054
}
 
2055
 
 
2056
static void splitWindowRegionEntry (we, grav1, grav2, w, h)
 
2057
WindowEntry     *we;
 
2058
int             grav1, grav2;
 
2059
int             w, h;
 
2060
{
 
2061
    WindowEntry *new;
 
2062
    int         save;
 
2063
 
 
2064
    switch (grav1) {
 
2065
        case D_NORTH:
 
2066
        case D_SOUTH:
 
2067
            save = we->w;
 
2068
            if (w != we->w) splitWindowRegionEntry (we, grav2, grav1, w, we->h);
 
2069
            if (h != we->h) {
 
2070
                new = (WindowEntry *) malloc (sizeof (WindowEntry));
 
2071
                new->twm_win = 0;
 
2072
                new->used = 0;
 
2073
                new->next = we->next;
 
2074
                we->next  = new;
 
2075
                new->x    = we->x;
 
2076
                new->h    = (we->h - h);
 
2077
                new->w    = we->w;
 
2078
                we->h     = h;
 
2079
                if (grav1 == D_SOUTH) {
 
2080
                    new->y = we->y;
 
2081
                    we->y  = new->y + new->h;
 
2082
                } else
 
2083
                    new->y = we->y + we->h;
 
2084
                }
 
2085
            break;
 
2086
        case D_EAST:
 
2087
        case D_WEST:
 
2088
            save = we->h;
 
2089
            if (h != we->h) splitWindowRegionEntry (we, grav2, grav1, we->w, h);
 
2090
            if (w != we->w) {
 
2091
                new = (WindowEntry *) malloc (sizeof (WindowEntry));
 
2092
                new->twm_win = 0;
 
2093
                new->used = 0;
 
2094
                new->next = we->next;
 
2095
                we->next  = new;
 
2096
                new->y    = we->y;
 
2097
                new->w    = (we->w - w);
 
2098
                new->h    = we->h;
 
2099
                we->w = w;
 
2100
                if (grav1 == D_EAST) {
 
2101
                    new->x = we->x;
 
2102
                    we->x  = new->x + new->w;
 
2103
                } else
 
2104
                    new->x = we->x + we->w;
 
2105
                }
 
2106
            break;
 
2107
    }
 
2108
}
 
2109
 
 
2110
static WindowEntry *findWindowEntry (wl, tmp_win, wrp)
 
2111
WorkSpaceList   *wl;
 
2112
TwmWindow       *tmp_win;
 
2113
WindowRegion    **wrp;
 
2114
{
 
2115
    WindowRegion *wr;
 
2116
    WindowEntry  *we;
 
2117
 
 
2118
    for (wr = wl->FirstWindowRegion; wr; wr = wr->next) {
 
2119
        for (we = wr->entries; we; we=we->next) {
 
2120
            if (we->twm_win == tmp_win) {
 
2121
                if (wrp) *wrp = wr;
 
2122
                return we;
 
2123
            }
 
2124
        }
 
2125
    }
 
2126
    return (WindowEntry*) 0;
 
2127
}
 
2128
 
 
2129
static WindowEntry *prevWindowEntry (we, wr)
 
2130
WindowEntry     *we;
 
2131
WindowRegion    *wr;
 
2132
{
 
2133
    WindowEntry *wp;
 
2134
 
 
2135
    if (we == wr->entries) return 0;
 
2136
    for (wp = wr->entries; wp->next != we; wp=wp->next);
 
2137
    return wp;
 
2138
}
 
2139
 
 
2140
static void mergeWindowEntries (old, we)
 
2141
WindowEntry     *old, *we;
 
2142
{
 
2143
    if (old->y == we->y) {
 
2144
        we->w = old->w + we->w;
 
2145
        if (old->x < we->x) we->x = old->x;
 
2146
    } else {
 
2147
        we->h = old->h + we->h;
 
2148
        if (old->y < we->y) we->y = old->y;
 
2149
    }
 
2150
}
 
2151
 
 
2152
void RemoveWindowFromRegion (tmp_win)
 
2153
TwmWindow       *tmp_win;
 
2154
{
 
2155
    WindowEntry   *we, *wp, *wn;
 
2156
    WindowRegion  *wr;
 
2157
    WorkSpaceList *wl;
 
2158
 
 
2159
    if (!Scr->FirstWindowRegion) return;
 
2160
    we = (WindowEntry*) 0;
 
2161
    for (wl = Scr->workSpaceMgr.workSpaceList; wl != NULL; wl = wl->next) {
 
2162
        we = findWindowEntry (wl, tmp_win, &wr);
 
2163
        if (we) break;
 
2164
    }
 
2165
    if (!we) return;
 
2166
 
 
2167
    we->twm_win = 0;
 
2168
    we->used = 0;
 
2169
    wp = prevWindowEntry (we, wr);
 
2170
    wn = we->next;
 
2171
    for (;;) {
 
2172
        if (wp && wp->used == 0 &&
 
2173
               ((wp->x == we->x && wp->w == we->w) ||
 
2174
                (wp->y == we->y && wp->h == we->h))) {
 
2175
            wp->next = we->next;
 
2176
            mergeWindowEntries (we, wp);
 
2177
            free ((char *) we);
 
2178
            we = wp;
 
2179
            wp = prevWindowEntry (wp, wr);
 
2180
        } else
 
2181
        if (wn && wn->used == 0 &&
 
2182
               ((wn->x == we->x && wn->w == we->w) ||
 
2183
                (wn->y == we->y && wn->h == we->h))) {
 
2184
            we->next = wn->next;
 
2185
            mergeWindowEntries (wn, we);
 
2186
            free ((char *) wn);
 
2187
            wn = we->next;
 
2188
        } else break;
 
2189
    }
 
2190
}
 
2191