2 * $Id: doors.c,v 3.0 90/11/20 16:13:17 dme Exp Locker: dme $
4 * Copyright (c) 1990 Dave Edmondson.
5 * Copyright (c) 1990 Imperial College of Science, Technoology & Medicine
8 * Permission to use, copy, modify, and distribute this software and its
9 * documentation for any purpose and without fee is hereby granted, provided
10 * that the above copyright notice appear in all copies and that both that
11 * copyright notice and this permission notice appear in supporting
12 * documentation, and that the names of Dave Edmondson or Imperial College
13 * not be used in advertising or publicity pertaining to distribution of the
14 * software without specific, written prior permission. Dave Edmondson and
15 * Imperial College make no representations about the suitability of this
16 * software for any purpose. It is provided "as is" without express or
25 #include "add_window.h"
27 extern void SetMapStateProp();
28 extern TwmDoor *door_add_internal();
29 extern void twmrc_error_prefix();
32 extern void HandleExpose();
33 extern void SetupWindow();
36 extern void AppletDown();
38 TwmDoor *door_add(name, position, destination)
39 char *name, *position, *destination;
41 int px, py, pw, ph, dx, dy;
45 * was 'Scr->use3Dborders' - djhjr - 8/11/98 *
46 int bw = (Scr->BorderBevelWidth > 0) ? Scr->ThreeDBorderWidth : Scr->BorderWidth;
48 int bw = Scr->BorderWidth;
50 JunkMask = XParseGeometry (position, &JunkX, &JunkY,
51 &JunkWidth, &JunkHeight);
53 /* we have some checking for negative (x,y) to do
54 sorta taken from desktop.c by DSE */
55 if ((JunkMask & XNegative) == XNegative) {
56 JunkX += Scr->MyDisplayWidth - JunkWidth - (2 * bw);
58 if ((JunkMask & YNegative) == YNegative) {
59 JunkY += Scr->MyDisplayHeight - JunkHeight - (2 * bw);
62 /* allow position to be omitted - djhjr - 5/10/99
63 if ((JunkMask & (XValue | YValue)) !=
66 fprintf (stderr, "bad Door position \"%s\"\n", position);
71 /* added this 'if (...) else' - djhjr - 5/10/99 */
72 if ((JunkMask & (XValue | YValue)) != (XValue | YValue))
74 /* allow AddWindow() to position it - djhjr - 5/10/99 */
79 /* if (JunkX <= 0 || JunkY <= 0) { */
80 if (JunkX < 0 || JunkY < 0) { /* 0,0 accepted now -- DSE */
82 fprintf (stderr, "silly Door position \"%s\"\n", position);
91 if (JunkMask & WidthValue)
94 /* means figure it out when you create the window */
96 if (JunkMask & HeightValue)
101 JunkMask = XParseGeometry (destination, &JunkX, &JunkY,
102 &JunkWidth, &JunkHeight);
103 if ((JunkMask & (XValue | YValue)) !=
105 twmrc_error_prefix();
106 fprintf (stderr, "bad Door destination \"%s\"\n", destination);
109 if (JunkX < 0 || JunkY < 0) {
110 twmrc_error_prefix();
111 fprintf (stderr, "silly Door destination \"%s\"\n",
118 return (door_add_internal(name, px, py, pw, ph, dx, dy));
121 TwmDoor *door_add_internal(name, px, py, pw, ph, dx, dy)
123 int px, py, pw, ph, dx, dy;
127 new = (TwmDoor *)malloc(sizeof(TwmDoor));
128 new->name = strdup(name);
130 /* this for getting colors */
131 new->class = XAllocClassHint();
132 new->class->res_name = new->name;
133 new->class->res_class = strdup(VTWM_DOOR_CLASS);
142 /* link into the list */
144 new->next = Scr->Doors;
146 Scr->Doors->prev = new;
152 void door_open(tmp_door)
157 /* djhjr - 4/26/96 */
159 * was 'Scr->use3Dborders' - djhjr - 8/11/98 *
160 int bw = (Scr->BorderBevelWidth > 0) ? Scr->ThreeDBorderWidth : Scr->BorderWidth;
162 int bw = Scr->BorderWidth;
164 /* look up colours */
165 if (!GetColorFromList(Scr->DoorForegroundL,
167 tmp_door->class, &tmp_door->colors.fore))
168 tmp_door->colors.fore = Scr->DoorC.fore;
169 if (!GetColorFromList(Scr->DoorBackgroundL,
171 tmp_door->class, &tmp_door->colors.back))
172 tmp_door->colors.back = Scr->DoorC.back;
174 if (tmp_door->width < 0)
175 /* djhjr - 9/14/03 */
176 #ifndef NO_I18N_SUPPORT
177 tmp_door->width = MyFont_TextWidth(&Scr->DoorFont,
179 tmp_door->width = XTextWidth(Scr->DoorFont.font,
182 strlen(tmp_door->name))
185 + (Scr->DoorBevelWidth * 2)
189 if (tmp_door->height < 0)
190 tmp_door->height = Scr->DoorFont.height
193 + (Scr->DoorBevelWidth * 2)
197 /* create the window */
198 w = XCreateSimpleWindow(dpy, Scr->Root,
199 tmp_door->x, tmp_door->y,
200 tmp_door->width, tmp_door->height,
202 tmp_door->colors.fore,
203 tmp_door->colors.back);
204 tmp_door->w = XCreateSimpleWindow(dpy, w,
206 tmp_door->width, tmp_door->height,
208 tmp_door->colors.fore,
209 tmp_door->colors.back);
211 /* reworked to limit the minimum size of a door - djhjr - 3/1/99
212 if ((tmp_door->x < 0) || (tmp_door->y < 0)) {
213 XSizeHints *hints = NULL;
217 * set the wmhints so that add_window() will allow
218 * the user to place the window
220 if (XGetWMNormalHints(dpy, w, hints, &ret) > 0) {
221 hints->flags = hints->flags &
222 (!USPosition & !PPosition);
223 XSetStandardProperties(dpy, w,
224 tmp_door->class->res_name,
225 tmp_door->class->res_name,
226 None, NULL, 0, hints);
229 XSetStandardProperties(dpy, w,
230 tmp_door->class->res_name,
231 tmp_door->class->res_name,
232 None, NULL, 0, NULL);
236 XSizeHints *hints = NULL;
238 if (tmp_door->x < 0 || tmp_door->y < 0)
243 * set the wmhints so that add_window() will allow
244 * the user to place the window
246 if (XGetWMNormalHints(dpy, w, hints, &ret) != 0)
247 hints->flags &= (!USPosition & !PPosition);
250 if (!hints) hints = XAllocSizeHints();
252 hints->flags |= PMinSize;
253 hints->min_width = tmp_door->width;
254 hints->min_height = tmp_door->height;
256 XSetStandardProperties(dpy, w,
257 tmp_door->class->res_name,
258 tmp_door->class->res_name,
259 None, NULL, 0, hints);
262 XSetClassHint(dpy, w, tmp_door->class);
264 /* set the name on both */
265 XStoreName(dpy, tmp_door->w, tmp_door->name);
266 XStoreName(dpy, w, tmp_door->name);
268 XDefineCursor( dpy, w, Scr->FrameCursor );/*RFB*/
269 XDefineCursor( dpy, tmp_door->w, Scr->DoorCursor );/*RFBCURSOR*/
271 /* moved these 'cuz AddWindow() will need 'em - djhjr - 11/15/01 */
272 /* store the address of the door on the window */
274 tmp_door->w, DoorContext, (caddr_t) tmp_door);
276 w, DoorContext, (caddr_t) tmp_door);
279 tmp_door->twin = AddWindow(w, FALSE, NULL);
281 SetMapStateProp(tmp_door->twin, NormalState);
283 /* interested in... */
284 XSelectInput(dpy, tmp_door->w, ExposureMask |
285 ButtonPressMask | ButtonReleaseMask);
287 /* store the address of the door on the window */
290 TwmContext, (caddr_t) tmp_door->twin);
293 XMapWindow(dpy, tmp_door->w);
301 for (tmp_door = Scr->Doors; tmp_door; tmp_door = tmp_door->next)
308 void door_enter(w, d)
312 int snapon; /* doors override real screen snapping - djhjr - 2/5/99 */
316 if (XFindContext(dpy, w, DoorContext, (caddr_t *)&d)
322 snapon = (int)Scr->snapRealScreen;
323 Scr->snapRealScreen = FALSE;
324 SetRealScreen(d->goto_x, d->goto_y);
325 Scr->snapRealScreen = (snapon) ? TRUE : FALSE;
331 void door_delete(w, d)
334 { /*marcel@duteca.et.tudelft.nl*/
337 if (XFindContext(dpy, w, DoorContext, (caddr_t *)&d)
344 Scr->Doors = d->next;
346 d->prev->next = d->next;
348 d->next->prev = d->prev;
350 /* djhjr - 4/27/99 */
354 * Must this be done here ? Is it do by XDestroyWindow(),
355 * or by HandleDestroyNotify() in events.c, or should it
356 * it be done there ? M.J.E. Mol.
358 * It looks as though the contexts, at least, should be
359 * deleted here, maybe more, I dunno. - djhjr 2/25/99
361 XDeleteContext(dpy, d->w, DoorContext);
362 XDeleteContext(dpy, d->w, TwmContext);
363 XDeleteContext(dpy, d->twin->w, DoorContext); /* ??? */
364 XUnmapWindow(dpy, d->w);
365 XUnmapWindow(dpy, w);
366 XDestroyWindow(dpy, w);
367 free(d->class->res_class); /* djhjr - 2/25/99 */
369 free(d->name); /* djhjr - 2/25/99 */
374 * create a new door on the fly
381 sprintf(name, "+%d+%d", Scr->VirtualDesktopX, Scr->VirtualDesktopY);
383 d = door_add_internal(name, -1, -1, -1, -1,
384 Scr->VirtualDesktopX, Scr->VirtualDesktopY);
390 * rename a door from cut buffer 0
392 * adapted from VTWM-5.2b - djhjr - 4/20/98
395 door_paste_name(w, d)
399 int width, height, count;
402 * was 'Scr->use3Dborders' - djhjr - 8/11/98 *
403 int bw = (Scr->BorderBevelWidth > 0) ? Scr->ThreeDBorderWidth : Scr->BorderWidth;
405 /* added initialization and test - djhjr - 3/1/99 */
407 if (Scr->BorderBevelWidth) bw = Scr->BorderWidth;
410 if (XFindContext(dpy, w, DoorContext, (caddr_t *)&d) == XCNOENT)
413 /* sanity check - djhjr - 10/31/00 */
414 if (!(ptr = XFetchBytes(dpy, &count)) || count == 0) return;
415 if (count > 128) count = 128;
418 d->name = realloc(d->name, count + 1);
420 d->name = malloc(count + 1);
422 sprintf(d->name, "%*s", count, ptr);
425 /* djhjr - 1/14/99 */
426 XClearWindow(dpy, d->w);
428 /* added 'Scr->DoorBevelWidth * 2' - djhjr - 2/7/99 */
429 /* djhjr - 9/14/03 */
430 #ifndef NO_I18N_SUPPORT
431 width = MyFont_TextWidth(&Scr->DoorFont, d->name, count) +
433 width = XTextWidth(Scr->DoorFont.font, d->name, count) +
435 SIZE_HINDENT + (Scr->DoorBevelWidth * 2);
436 height = Scr->DoorFont.height + SIZE_VINDENT + (Scr->DoorBevelWidth * 2);
438 /* limit the size of a door - djhjr - 3/1/99 */
439 d->twin->hints.flags |= PMinSize;
440 d->twin->hints.min_width = width;
441 d->twin->hints.min_height = height;
443 SetupWindow(d->twin, d->twin->frame_x, d->twin->frame_y,
444 width + 2 * bw, height + d->twin->title_height + 2 * bw, -1);