/*
* $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 <stdio.h>
#include <string.h>
#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();
}
syntax highlighted by Code2HTML, v. 0.9.1