/* * $Id: doors.c,v 3.0 90/11/20 16:13:17 dme Exp Locker: dme $ * * Copyright (c) 1990 Dave Edmondson. * Copyright (c) 1990 Imperial College of Science, Technoology & Medicine * All Rights Reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the names of Dave Edmondson or Imperial College * not be used in advertising or publicity pertaining to distribution of the * software without specific, written prior permission. Dave Edmondson and * Imperial College make no representations about the suitability of this * software for any purpose. It is provided "as is" without express or * implied warranty. */ #include #include #include "doors.h" #include "screen.h" #include "desktop.h" #include "add_window.h" #define strdup Strdup /* avoid conflict with system header files */ char *strdup(s1) char * s1; { char *s2; s2 = malloc((unsigned) strlen(s1)+1); return (s2 == NULL ? NULL : strcpy(s2,s1)); } extern void SetMapStateProp(); extern TwmDoor *door_add_internal(); extern void twmrc_error_prefix(); /* djhjr - 4/20/98 */ extern void HandleExpose(); extern void SetupWindow(); /* djhjr - 4/27/99 */ extern void AppletDown(); TwmDoor *door_add(name, position, destination) char *name, *position, *destination; { int px, py, pw, ph, dx, dy; /* djhjr - 4/26/96 */ /* djhjr - 8/11/98 * was 'Scr->use3Dborders' - djhjr - 8/11/98 * int bw = (Scr->BorderBevelWidth > 0) ? Scr->ThreeDBorderWidth : Scr->BorderWidth; */ int bw = Scr->BorderWidth; JunkMask = XParseGeometry (position, &JunkX, &JunkY, &JunkWidth, &JunkHeight); /* we have some checking for negative (x,y) to do sorta taken from desktop.c by DSE */ if ((JunkMask & XNegative) == XNegative) { JunkX += Scr->MyDisplayWidth - JunkWidth - (2 * bw); } if ((JunkMask & YNegative) == YNegative) { JunkY += Scr->MyDisplayHeight - JunkHeight - (2 * bw); } /* allow position to be omitted - djhjr - 5/10/99 if ((JunkMask & (XValue | YValue)) != (XValue | YValue)) { twmrc_error_prefix(); fprintf (stderr, "bad Door position \"%s\"\n", position); return NULL; } */ /* added this 'if (...) else' - djhjr - 5/10/99 */ if ((JunkMask & (XValue | YValue)) != (XValue | YValue)) { /* allow AddWindow() to position it - djhjr - 5/10/99 */ JunkX = JunkY = -1; } else { /* if (JunkX <= 0 || JunkY <= 0) { */ if (JunkX < 0 || JunkY < 0) { /* 0,0 accepted now -- DSE */ twmrc_error_prefix(); fprintf (stderr, "silly Door position \"%s\"\n", position); return NULL; } } /* they seemed ok */ px = JunkX; py = JunkY; if (JunkMask & WidthValue) pw = JunkWidth; else /* means figure it out when you create the window */ pw = -1; if (JunkMask & HeightValue) ph = JunkHeight; else ph = -1; JunkMask = XParseGeometry (destination, &JunkX, &JunkY, &JunkWidth, &JunkHeight); if ((JunkMask & (XValue | YValue)) != (XValue | YValue)) { twmrc_error_prefix(); fprintf (stderr, "bad Door destination \"%s\"\n", destination); return NULL; } if (JunkX < 0 || JunkY < 0) { twmrc_error_prefix(); fprintf (stderr, "silly Door destination \"%s\"\n", destination); return NULL; } dx = JunkX; dy = JunkY; return (door_add_internal(name, px, py, pw, ph, dx, dy)); } TwmDoor *door_add_internal(name, px, py, pw, ph, dx, dy) char *name; int px, py, pw, ph, dx, dy; { TwmDoor *new; new = (TwmDoor *)malloc(sizeof(TwmDoor)); new->name = strdup(name); /* this for getting colors */ new->class = XAllocClassHint(); new->class->res_name = new->name; new->class->res_class = strdup(VTWM_DOOR_CLASS); new->x = px; new->y = py; new->width = pw; new->height = ph; new->goto_x = dx; new->goto_y = dy; /* link into the list */ new->prev = NULL; new->next = Scr->Doors; if (Scr->Doors) Scr->Doors->prev = new; Scr->Doors = new; return (new); } void door_open(tmp_door) TwmDoor *tmp_door; { Window w; /* djhjr - 4/26/96 */ /* djhjr - 8/11/98 * was 'Scr->use3Dborders' - djhjr - 8/11/98 * int bw = (Scr->BorderBevelWidth > 0) ? Scr->ThreeDBorderWidth : Scr->BorderWidth; */ int bw = Scr->BorderWidth; /* look up colours */ if (!GetColorFromList(Scr->DoorForegroundL, tmp_door->name, tmp_door->class, &tmp_door->colors.fore)) tmp_door->colors.fore = Scr->DoorC.fore; if (!GetColorFromList(Scr->DoorBackgroundL, tmp_door->name, tmp_door->class, &tmp_door->colors.back)) tmp_door->colors.back = Scr->DoorC.back; if (tmp_door->width < 0) /* djhjr - 9/14/03 */ #ifndef NO_I18N_SUPPORT tmp_door->width = MyFont_TextWidth(&Scr->DoorFont, #else tmp_door->width = XTextWidth(Scr->DoorFont.font, #endif tmp_door->name, strlen(tmp_door->name)) /* djhjr - 2/7/99 */ + (Scr->DoorBevelWidth * 2) + SIZE_HINDENT; if (tmp_door->height < 0) tmp_door->height = Scr->DoorFont.height /* djhjr - 2/7/99 */ + (Scr->DoorBevelWidth * 2) + SIZE_VINDENT; /* create the window */ w = XCreateSimpleWindow(dpy, Scr->Root, tmp_door->x, tmp_door->y, tmp_door->width, tmp_door->height, bw, tmp_door->colors.fore, tmp_door->colors.back); tmp_door->w = XCreateSimpleWindow(dpy, w, 0, 0, tmp_door->width, tmp_door->height, 0, tmp_door->colors.fore, tmp_door->colors.back); /* reworked to limit the minimum size of a door - djhjr - 3/1/99 if ((tmp_door->x < 0) || (tmp_door->y < 0)) { XSizeHints *hints = NULL; long ret; * * set the wmhints so that add_window() will allow * the user to place the window * if (XGetWMNormalHints(dpy, w, hints, &ret) > 0) { hints->flags = hints->flags & (!USPosition & !PPosition); XSetStandardProperties(dpy, w, tmp_door->class->res_name, tmp_door->class->res_name, None, NULL, 0, hints); } } else { XSetStandardProperties(dpy, w, tmp_door->class->res_name, tmp_door->class->res_name, None, NULL, 0, NULL); } */ { XSizeHints *hints = NULL; if (tmp_door->x < 0 || tmp_door->y < 0) { long ret; /* * set the wmhints so that add_window() will allow * the user to place the window */ if (XGetWMNormalHints(dpy, w, hints, &ret) != 0) hints->flags &= (!USPosition & !PPosition); } if (!hints) hints = XAllocSizeHints(); hints->flags |= PMinSize; hints->min_width = tmp_door->width; hints->min_height = tmp_door->height; XSetStandardProperties(dpy, w, tmp_door->class->res_name, tmp_door->class->res_name, None, NULL, 0, hints); } XSetClassHint(dpy, w, tmp_door->class); /* set the name on both */ XStoreName(dpy, tmp_door->w, tmp_door->name); XStoreName(dpy, w, tmp_door->name); XDefineCursor( dpy, w, Scr->FrameCursor );/*RFB*/ XDefineCursor( dpy, tmp_door->w, Scr->DoorCursor );/*RFBCURSOR*/ /* moved these 'cuz AddWindow() will need 'em - djhjr - 11/15/01 */ /* store the address of the door on the window */ XSaveContext(dpy, tmp_door->w, DoorContext, (caddr_t) tmp_door); XSaveContext(dpy, w, DoorContext, (caddr_t) tmp_door); /* give to twm */ tmp_door->twin = AddWindow(w, FALSE, NULL); SetMapStateProp(tmp_door->twin, NormalState); /* interested in... */ XSelectInput(dpy, tmp_door->w, ExposureMask | ButtonPressMask | ButtonReleaseMask); /* store the address of the door on the window */ XSaveContext(dpy, tmp_door->w, TwmContext, (caddr_t) tmp_door->twin); /* map it */ XMapWindow(dpy, tmp_door->w); XMapWindow(dpy, w); } void door_open_all() { TwmDoor *tmp_door; for (tmp_door = Scr->Doors; tmp_door; tmp_door = tmp_door->next) door_open(tmp_door); } /* * go into a door */ void door_enter(w, d) Window w; TwmDoor *d; { int snapon; /* doors override real screen snapping - djhjr - 2/5/99 */ if (!d) /* find the door */ if (XFindContext(dpy, w, DoorContext, (caddr_t *)&d) == XCNOENT) /* not a door ! */ return; /* go to it */ snapon = (int)Scr->snapRealScreen; Scr->snapRealScreen = FALSE; SetRealScreen(d->goto_x, d->goto_y); Scr->snapRealScreen = (snapon) ? TRUE : FALSE; } /* * delete a door */ void door_delete(w, d) Window w; TwmDoor *d; { /*marcel@duteca.et.tudelft.nl*/ if (!d) /* find the door */ if (XFindContext(dpy, w, DoorContext, (caddr_t *)&d) == XCNOENT) /* not a door ! */ return; /* unlink it: */ if (Scr->Doors == d) Scr->Doors = d->next; if (d->prev != NULL) d->prev->next = d->next; if (d->next != NULL) d->next->prev = d->prev; /* djhjr - 4/27/99 */ AppletDown(d->twin); /* * Must this be done here ? Is it do by XDestroyWindow(), * or by HandleDestroyNotify() in events.c, or should it * it be done there ? M.J.E. Mol. * * It looks as though the contexts, at least, should be * deleted here, maybe more, I dunno. - djhjr 2/25/99 */ XDeleteContext(dpy, d->w, DoorContext); XDeleteContext(dpy, d->w, TwmContext); XDeleteContext(dpy, d->twin->w, DoorContext); /* ??? */ XUnmapWindow(dpy, d->w); XUnmapWindow(dpy, w); XDestroyWindow(dpy, w); free(d->class->res_class); /* djhjr - 2/25/99 */ XFree(d->class); free(d->name); /* djhjr - 2/25/99 */ free(d); } /* * create a new door on the fly */ void door_new() { TwmDoor *d; char name[256]; sprintf(name, "+%d+%d", Scr->VirtualDesktopX, Scr->VirtualDesktopY); d = door_add_internal(name, -1, -1, -1, -1, Scr->VirtualDesktopX, Scr->VirtualDesktopY); door_open(d); } /* * rename a door from cut buffer 0 * * adapted from VTWM-5.2b - djhjr - 4/20/98 */ void door_paste_name(w, d) Window w; TwmDoor* d; { int width, height, count; char *ptr; /* djhjr - 8/11/98 * was 'Scr->use3Dborders' - djhjr - 8/11/98 * int bw = (Scr->BorderBevelWidth > 0) ? Scr->ThreeDBorderWidth : Scr->BorderWidth; */ /* added initialization and test - djhjr - 3/1/99 */ int bw = 0; if (Scr->BorderBevelWidth) bw = Scr->BorderWidth; if (!d) if (XFindContext(dpy, w, DoorContext, (caddr_t *)&d) == XCNOENT) return; /* sanity check - djhjr - 10/31/00 */ if (!(ptr = XFetchBytes(dpy, &count)) || count == 0) return; if (count > 128) count = 128; if (d->name) d->name = realloc(d->name, count + 1); else d->name = malloc(count + 1); sprintf(d->name, "%*s", count, ptr); XFree(ptr); /* djhjr - 1/14/99 */ XClearWindow(dpy, d->w); /* added 'Scr->DoorBevelWidth * 2' - djhjr - 2/7/99 */ /* djhjr - 9/14/03 */ #ifndef NO_I18N_SUPPORT width = MyFont_TextWidth(&Scr->DoorFont, d->name, count) + #else width = XTextWidth(Scr->DoorFont.font, d->name, count) + #endif SIZE_HINDENT + (Scr->DoorBevelWidth * 2); height = Scr->DoorFont.height + SIZE_VINDENT + (Scr->DoorBevelWidth * 2); /* limit the size of a door - djhjr - 3/1/99 */ d->twin->hints.flags |= PMinSize; d->twin->hints.min_width = width; d->twin->hints.min_height = height; SetupWindow(d->twin, d->twin->frame_x, d->twin->frame_y, width + 2 * bw, height + d->twin->title_height + 2 * bw, -1); HandleExpose(); }