sdo@soliado.East.Sun.COM (Scott Oaks - Sun Consulting NYC) (04/29/91)
Submitted-by: sdo@soliado.East.Sun.COM (Scott Oaks - Sun Consulting NYC) Posting-number: Volume 12, Issue 59 Archive-name: olvwm/part03 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 3 (of 16)." # Contents: Error.c olvwm.man win.c winbutton.c winpush.c # Wrapped by sdo@piccolo on Fri Apr 26 17:31:03 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'Error.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Error.c'\" else echo shar: Extracting \"'Error.c'\" \(9113 characters\) sed "s/^X//" >'Error.c' <<'END_OF_FILE' X/* X * (c) Copyright 1989 Sun Microsystems, Inc. Sun design patents X * pending in the U.S. and foreign countries. See LEGAL_NOTICE X * file for terms of the license. X * X * Written for Sun Microsystems by Crucible, Santa Cruz, CA. X */ X static char sccsid[] = "@(#)Error.c 1.2 olvwm version 3/30/91"; X/* X * Based on static char sccsid[] = "@(#) Error.c 25.4 90/05/30 Crucible"; X */ X X#include <stdio.h> X#include <X11/Xproto.h> X#include <X11/Xlib.h> X X/* globals */ X X/* locals */ static char *hyperSensitive = NULL; X X#define NXOPCODES 128 /* # of X opcodes */ typedef struct { X unsigned int fatal, warning, ignore; X} ErrorEntry; X X/* The following defines create bitmasks from the X Error Codes */ X#define BReq (1<<BadRequest) X#define BVal (1<<BadValue) X#define BWin (1<<BadWindow) X#define BPix (1<<BadPixmap) X#define BAtm (1<<BadAtom) X#define BCur (1<<BadCursor) X#define BFnt (1<<BadFont) X#define BMch (1<<BadMatch) X#define BDrw (1<<BadDrawable) X#define BAcc (1<<BadAccess) X#define BAlc (1<<BadAlloc) X#define BCol (1<<BadColor) X#define BGC (1<<BadGC) X#define BIDC (1<<BadIDChoice) X#define BNam (1<<BadName) X#define BLen (1<<BadLength) X#define BImp (1<<BadImplementation) X X#define BAll (~0) /* matches all error bitmasks */ X X/* This error table encodes the severity of an error in relation to X * an X primitive. For instance if BadWindow was fatal for X * a certain primitive but BadColor was not, the following entry would be used: X * {BWin, BCol, 0} X */ static ErrorEntry errorTable[NXOPCODES] = { X {BAll, 0, 0}, /* 0, Not Used */ X {BAll, 0, 0}, /* 1, X_CreateWindow */ X {0, ~BWin, BWin}, /* 2, X_ChangeWindowAttributes */ X {0, ~BWin, BWin}, /* 3, X_GetWindowAttributes */ X {0, BAll, 0}, /* 4, X_DestroyWindow */ X {0, BAll, 0}, /* 5, X_DestroySubwindows */ X {0, ~BWin, BWin}, /* 6, X_ChangeSaveSet */ X {0, ~BWin, BWin}, /* 7, X_ReparentWindow */ X {0, BAll, 0}, /* 8, X_MapWindow */ X {0, BAll, 0}, /* 9, X_MapSubwindows */ X {0, ~BWin, BWin}, /* 10, X_UnmapWindow */ X {0, BAll, 0}, /* 11, X_UnmapSubwindows */ X {0, ~BWin, BWin}, /* 12, X_ConfigureWindow */ X {0, BAll, 0}, /* 13, X_CirculateWindow */ X {0, BAll, 0}, /* 14, X_GetGeometry */ X {0, ~BWin, BWin}, /* 15, X_QueryTree */ X {0, BAll, 0}, /* 16, X_InternAtom */ X {0, BAll, 0}, /* 17, X_GetAtomName */ X {0, ~BWin, BWin}, /* 18, X_ChangeProperty */ X {0, BAll, 0}, /* 19, X_DeleteProperty */ X {0, ~BWin, BWin}, /* 20, X_GetProperty */ X {0, BAll, 0}, /* 21, X_ListProperties */ X {0, BAll, 0}, /* 22, X_SetSelectionOwner */ X {0, BAll, 0}, /* 23, X_GetSelectionOwner */ X {0, BAll, 0}, /* 24, X_ConvertSelection */ X {0, ~BWin, BWin}, /* 25, X_SendEvent */ X {0, 0, BAll}, /* 26, X_GrabPointer */ X {0, 0, BAll}, /* 27, X_UngrabPointer */ X {0, 0, BAll}, /* 28, X_GrabButton */ X {0, 0, BAll}, /* 29, X_UngrabButton */ X {0, 0, BAll}, /* 30, X_ChangeActivePointerGrab */ X {0, BAll, 0}, /* 31, X_GrabKeyboard */ X {0, BAll, 0}, /* 32, X_UngrabKeyboard */ X {0, BAll, 0}, /* 33, X_GrabKey */ X {0, BAll, 0}, /* 34, X_UngrabKey */ X {0, BAll, 0}, /* 35, X_AllowEvents */ X {BAll, 0, 0}, /* 36, X_GrabServer */ X {0, BAll, 0}, /* 37, X_UngrabServer */ X {0, BAll, 0}, /* 38, X_QueryPointer */ X {0, BAll, 0}, /* 39, X_GetMotionEvents */ X {0, BAll, 0}, /* 40, X_TranslateCoords */ X {0, BAll, 0}, /* 41, X_WarpPointer */ X {0, ~(BMch|BWin), BMch|BWin}, /* 42, X_SetInputFocus */ X {0, BAll, 0}, /* 43, X_GetInputFocus */ X {0, BAll, 0}, /* 44, X_QueryKeymap */ X {0, BAll, 0}, /* 45, X_OpenFont */ X {0, BAll, 0}, /* 46, X_CloseFont */ X {0, BAll, 0}, /* 47, X_QueryFont */ X {0, BAll, 0}, /* 48, X_QueryTextExtents */ X {0, BAll, 0}, /* 49, X_ListFonts */ X {0, BAll, 0}, /* 50, X_ListFontsWithInfo */ X {0, BAll, 0}, /* 51, X_SetFontPath */ X {0, BAll, 0}, /* 52, X_GetFontPath */ X {0, BAll, 0}, /* 53, X_CreatePixmap */ X {0, BAll, 0}, /* 54, X_FreePixmap */ X {0, BAll, 0}, /* 55, X_CreateGC */ X {0, BAll, 0}, /* 56, X_ChangeGC */ X {0, BAll, 0}, /* 57, X_CopyGC */ X {0, BAll, 0}, /* 58, X_SetDashes */ X {0, BAll, 0}, /* 59, X_SetClipRectangles */ X {0, BAll, 0}, /* 60, X_FreeGC */ X {0, ~BMch, BMch}, /* 61, X_ClearArea */ X {0, BAll, 0}, /* 62, X_CopyArea */ X {0, BAll, 0}, /* 63, X_CopyPlane */ X {0, BAll, 0}, /* 64, X_PolyPoint */ X {0, BAll, 0}, /* 65, X_PolyLine */ X {0, BAll, 0}, /* 66, X_PolySegment */ X {0, BAll, 0}, /* 67, X_PolyRectangle */ X {0, BAll, 0}, /* 68, X_PolyArc */ X {0, BAll, 0}, /* 69, X_FillPoly */ X {0, BAll, 0}, /* 70, X_PolyFillRectangle */ X {0, BAll, 0}, /* 71, X_PolyFillArc */ X {0, BAll, 0}, /* 72, X_PutImage */ X {0, BAll, 0}, /* 73, X_GetImage */ X {0, BAll, 0}, /* 74, X_PolyText8 */ X {0, BAll, 0}, /* 75, X_PolyText16 */ X {0, BAll, 0}, /* 76, X_ImageText8 */ X {0, BAll, 0}, /* 77, X_ImageText16 */ X {0, BAll, 0}, /* 78, X_CreateColormap */ X {0, BAll, 0}, /* 79, X_FreeColormap */ X {0, BAll, 0}, /* 80, X_CopyColormapAndFree */ X {0, BAll, 0}, /* 81, X_InstallColormap */ X {0, BAll, 0}, /* 82, X_UninstallColormap */ X {0, BAll, 0}, /* 83, X_ListInstalledColormaps */ X {0, BAll, 0}, /* 84, X_AllocColor */ X {0, BAll, 0}, /* 85, X_AllocNamedColor */ X {0, BAll, 0}, /* 86, X_AllocColorCells */ X {0, BAll, 0}, /* 87, X_AllocColorPlanes */ X {0, BAll, 0}, /* 88, X_FreeColors */ X {0, BAll, 0}, /* 89, X_StoreColors */ X {0, BAll, 0}, /* 90, X_StoreNamedColor */ X {0, BAll, 0}, /* 91, X_QueryColors */ X {0, BAll, 0}, /* 92, X_LookupColor */ X {0, BAll, 0}, /* 93, X_CreateCursor */ X {0, BAll, 0}, /* 94, X_CreateGlyphCursor */ X {0, BAll, 0}, /* 95, X_FreeCursor */ X {0, BAll, 0}, /* 96, X_RecolorCursor */ X {0, BAll, 0}, /* 97, X_QueryBestSize */ X {0, BAll, 0}, /* 98, X_QueryExtension */ X {0, BAll, 0}, /* 99, X_ListExtensions */ X {0, BAll, 0}, /* 100, X_ChangeKeyboardMapping */ X {0, BAll, 0}, /* 101, X_GetKeyboardMapping */ X {0, BAll, 0}, /* 102, X_ChangeKeyboardControl */ X {0, BAll, 0}, /* 103, X_GetKeyboardControl */ X {0, BAll, 0}, /* 104, X_Bell */ X {0, BAll, 0}, /* 105, X_ChangePointerControl */ X {0, BAll, 0}, /* 106, X_GetPointerControl */ X {0, BAll, 0}, /* 107, X_SetScreenSaver */ X {0, BAll, 0}, /* 108, X_GetScreenSaver */ X {0, BAll, 0}, /* 109, X_ChangeHosts */ X {0, BAll, 0}, /* 110, X_ListHosts */ X {0, BAll, 0}, /* 111, X_SetAccessControl */ X {0, BAll, 0}, /* 112, X_SetCloseDownMode */ X {0, BAll, 0}, /* 113, X_KillClient */ X {0, BAll, 0}, /* 114, X_RotateProperties */ X {0, BAll, 0}, /* 115, X_ForceScreenSaver */ X {0, BAll, 0}, /* 116, X_SetPointerMapping */ X {0, BAll, 0}, /* 117, X_GetPointerMapping */ X {0, BAll, 0}, /* 118, X_SetModifierMapping */ X {0, BAll, 0}, /* 119, X_GetModifierMapping */ X {BAll, 0, 0}, /* 120, Not Used */ X {BAll, 0, 0}, /* 121, Not Used */ X {BAll, 0, 0}, /* 122, Not Used */ X {BAll, 0, 0}, /* 123, Not Used */ X {BAll, 0, 0}, /* 124, Not Used */ X {BAll, 0, 0}, /* 125, Not Used */ X {BAll, 0, 0}, /* 126, Not Used */ X {0, BAll, 0}, /* 127, X_NoOperation */ X }; X/* X * ErrorSensitive -- cause an exit on all X errors X */ XErrorSensitive(s) char *s; X{ X hyperSensitive = s; X} X X/* X * ErrorInsensitive -- perform normal X error processing X */ X/*ARGSUSED*/ /* dpy arg will be used when multiple Displays supported */ XErrorInsensitive(dpy) Display *dpy; X{ X hyperSensitive = NULL; X} X X/* X * ErrorHandler -- this routine is called whenever an error in the X X * protocol is detected. X */ XErrorHandler(dpy, event) Display *dpy; XXErrorEvent *event; X{ X char buffer[BUFSIZ]; X int errBitmask; X X XGetErrorText(dpy, event->error_code, buffer, BUFSIZ); X X if (hyperSensitive != NULL) X { X /* treat all errors as fatal */ X (void) fprintf(stderr, "olvwm: Fatal X Error: %s\n", buffer); X (void) fprintf(stderr, "%s\n", hyperSensitive); X exit(-1); X /*NOTREACHED*/ X } X X errBitmask = 1 << event->error_code; X X if (errBitmask & errorTable[event->request_code].ignore) X return 0; X else if (errBitmask & errorTable[event->request_code].warning) X { X (void) fprintf(stderr, "olvwm: Warning, X Error: %s\n", buffer); X (void) fprintf(stderr, " Request Major code: %d\n", X event->request_code); X (void) fprintf(stderr, " Request Minor code: %d\n", X event->minor_code); X (void) fprintf(stderr, " ResourceId 0x%x\n", X event->resourceid); X X return 0; X } X else if (errBitmask & errorTable[event->request_code].fatal) X { X (void) fprintf(stderr, "olvwm: Fatal X Error: %s\n", buffer); X (void) fprintf(stderr, " Request Major code: %d\n", X event->request_code); X (void) fprintf(stderr, " Request Minor code: %d\n", X event->minor_code); X (void) fprintf(stderr, " ResourceId 0x%x\n", X event->resourceid); X (void) fprintf(stderr, " Error Serial #%d\n", event->serial); X (void) fprintf(stderr, " Current Serial #%d\n", dpy->request); X X /* do not return from fatal errors */ X exit(-1); X /*NOTREACHED*/ X } X X return 0; X} X X/* X * ErrorGeneral -- this routine is called whenever a general error occurs X * within OLWM. Exits from olwm. X */ void XErrorGeneral(txt) char *txt; X{ X (void) fprintf(stderr,"olvwm: Fatal Error: %s\n", txt); X#ifdef DEBUG X abort(); X#else X exit(-1); X#endif X} X X/* X * ErrorWarning -- this routine is called whenever a condition requiring X * a warning message occurs within OLWM. X */ void XErrorWarning(txt) char *txt; X{ X (void) fprintf(stderr,"olvwm: Warning: %s\n", txt); X} X END_OF_FILE if test 9113 -ne `wc -c <'Error.c'`; then echo shar: \"'Error.c'\" unpacked with wrong size! fi # end of 'Error.c' fi if test -f 'olvwm.man' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'olvwm.man'\" else echo shar: Extracting \"'olvwm.man'\" \(10814 characters\) sed "s/^X//" >'olvwm.man' <<'END_OF_FILE' X.\" @(#)olvwm.1 1.3 olvwm version 4/17/91 X.TH OLVWM 1 "31 March 1991" X.SH NAME olvwm \- OPEN LOOK virtual window manager for OpenWindows X.SH SYNOPSIS X.B olvwm X[ X.B \-2d X] [ X.B \-3d X] [ X.B \-c X] [ X.B \-click X] [ X.B \-f X] [ X.B \-follow X] [ X.B \-parent X] X.br X[ X.B \-display X.I displaystring X] [ X.B \-fn X.I fontname X] [ X.B \-font X.I fontname X] [ X.B \-name X.I rsrcname X] [ X.B \-xrm X.I rsrcstring X] X.br X[ X.B \-all X] [ X.B \-debug X] [ X.B \-orphans X] [ X.B \-synchronize X] X.\" ======================================================================== X.SH DESCRIPTION X.LP X.B olvwm is a virtual window manager for the X Window System that implements parts of the OPEN LOOK graphical user interface. X.B olvwm differs from X.B olwm in that olvwm manages a virtual desktop which is larger than the actual screen. However, X.B olvwm is equivalent in all other respects to X.B olwm X[though X.B olvwm breaks parts of the OPEN LOOK user interface that X.B olwm respects.] This manual page discusses only the interface for the virtual desktop; for all other information, see the X.B olwm manual page. X.LP When it is started, X.B olvwm displays a virtual desktop manager (VDM) window along with any other tools normally started in your .xinitrc file. The virtual desktop manager is a reduced display of all windows active on the desktop at any time. The area of the desktop which is visible (that is, which appears on your screen) is outlined in the virtual desktop manager. X.LP This window manager also includes David Plotkin's auto-pinned root menu resources. X.SH MOVING WINDOWS X.LP You move windows on the screen just as you normally would in X.B olwm. You can also drag windows from the screen into the virtual desktop manager or from the virtual desktop manager to the screen, or just within the virtual desktop manager. Note that if you select on a window's frame which is overlapping the virtual desktop manager you will end up dragging the window into the virtual desktop manager. You can set the AllowMoveIntoDesktop resource to false if you are bothered by this behaviour. X.SH MANIPULATING THE VIRTUAL DESKTOP X.LP If you select a window inside the virtual desktop manager, you can move the window. If, however, you select the background area of the virtual desktop manager within the viewing rectangle, you can move the viewing rectangle of the desktop. When you release the mouse button, the desktop will shift and you will now see the windows within the virtual desktop manager's viewing rectangle. X.LP You can also use the arrow keys to move the viewing rectangle and affect your view. If the virtual desktop manager has the keyboard focus, simply press the right arrow to move your view into the desktop to the right, etc. If your set the allowArrowInRoot resource to true (which, in fact, is it's default value), then arrows keys will work when the root window has the keyboard focus as well. X.LP You can use the arrow keys when the virtual desktop manager has been iconified (though you must keep track mentally of where on the desktop you are). X.SH RESIZING THE VIRTUAL DESKTOP X.LP You can use the resize corners on the virtual desktop manager to resize the virtual desktop at will. If you make the virtual desktop smaller, windows which might be off the new virtual desktop will NOT be moved X(though they will not be lost, either, and you can get them back by resizing the desktop again). Note that after a resize the virtual desktop will be shifted to the upper-left hand corner of the virtual desktop manager; this means that if you pick the left-hand corner of the VDM and make it larger, you'll get extra desktop area on the righthand side of the virtual desktop. X.SH STICKY WINDOWS X.LP You'll notice that the virtual desktop manager never moves on your screen if you change views. That's because the desktop manager is permanently "sticky." X.LP Windows which are "sticky" never move position on the screen when you change your view into the desktop. To set a particular window as sticky, simply select "Stick" in it's frame menu. You may similarly unstick the window via it's menu. X.LP X[Note: Only base frames are eligible to become sticky; frames inherit the stickyness of their base frames. Thus, for a particular application, either all windows are sticky or none of them are. The exception to this is that base frames created after a base frame is set to be "sticky" are created as unsticky. For most OPEN LOOK applications, this affects only pin-up menus; you should pin any menus you want to be sticky BEFORE you set the base frame to be sticky.] X.LP Windows are sticky by default it their class name (set via the WM_CLASS) property is in the list of strings for VirtualSticky (see RESOURCES below) X.SH PLACING WINDOWS X.LP If you specify a window placement directly (via -Wp arguments or XX11 geometry screens), the window will appear at that location on the virtual desktop (even if that location is not currently visible). X.LP If you do not specify a window position, then X.B olvwm will place it somewhere on your visible screen using similar window/icon placement rules as X.B olwm. X.\" ======================================================================== X.SH WINDOW MENU X.LP The window menu of most windows has all the tools defined in X.B olwm. In addition, the menu of base windows has the following command X.TP X.B Stick/Unstick Affect the stickyness of the particular window. Windows which are sticky will always appear in the same place on the screen no matter which part of the virtual desktop you're looking at. Windows which are not sticky X(by default, all windows) will move when you change the view on the virtual desktop. X.\" ======================================================================== X.SH RESOURCES See the man page for X.B olwm for a complete description of resources. All resources of class OpenWindows described there are supported by X.B olvwm. In addition, for X.B olvwm only, resources of instance "olvwm" are also read. You can thus name the following resources as olvwm.<resource> or as OpenWindows.<resource> depending on your naming preference. X.TP X.BI VirtualDesktop " (string)" Specifies the size of the virtual desktop. You can specify this in terms of screen sizes, so that a virtual desktop of 3 screens across and 2 screens high would appear as the string "3x2". You may also specify this in terms of absolute pixel sizes, e.g. "3800x1800" as long as the pixel size is greater than the size of your framebuffer. X.I Default value: "3x2" X.P X.TP X.BI PannerScale " (int)" Sets the scale in which the virtual desktop manager will be drawn. X.I Default value: 15. X.P X.TP X.BI VirtualGeometry " (string)" Specifies the geometry string of the desktop manager in standard X11 format (wxh+x+y). The width and height, if specified, are ignored, but the x and y can be used to specify the initial location of the desktop manager. X.I Default value: 0x0+0+0 X.TP X.BI VirtualIconGeometry " (string)" Speficied the geometry string of the desktop manager icon in standard X11 format (wxh+x+y). The width and height are ignored, but the x and y can be used to specify the initial location of the desktop manager icon. X.I Default value: 0x0+0+0 X.P X.TP X.BI VirtualIconic " (Boolean)" If true, the virtual desk manager will come up iconic. X.I Default value: False X.P X.TP X.BI AllowMoveIntoDesktop " (Boolean)" If true, allows windows to be moved from the screen into the desktop manager and vice versa. Otherwise, moving a window on the screen will only allow it to be placed in the visible desktop area; and moving a window in the desktop manager will not let it be dragged onto the screen. X.I Default value: True X.P X.TP X.BI VirtualFont " (string)" The font name used to display title of windows within the virtual desktop manager. X.I Default value: A string representing a medium-sized Lucida Font X.P X.TP X.BI VirtualBackgroundColor " (color specification)" The color of the background of the virtual desktop manager. X.I Default value: Based on the frame color of your desktop. X.P X.TP X.BI VirtualForegroundColor " (color specification)" The color of the virtual windows in the virtual desktop manager. X.I Default value: The frame color of your desktop. X.P X.TP X.BI VirtualFontColor " (color specification)" The color of the title within the virtual windows of the virtual desktop manager. X.I Default value: Black X.P X.TP X.BI VirtualBackgroundMap " (Pixmap filename)" The name of a file containing a pixmap to use as the background of the virtual desktop manager. This item, if present, takes precedence over the VirtualBackgroundColor. X.I Default value: unused X.P X.TP X.BI AutoShowRootMenu " (Bool)" If true, the root menu will come up pinned at start up. X.I Default value: False X.P X.TP X.BI AutoRootMenuX " (int)" If AutoShowRootMenu is true, this is the X location where the menu will come up. X.I Default value: 0 X.P X.TP X.BI AutoRootMenuY " (int)" If AutoShowRootMenu is true, this is the Y location where the menu will come up. X.I Default value: 0 X.P X.TP X.BI VirtualSticky " (list of strings)" The list of windows which should be sticky by default. Like the olwm MinimalDecor, this should be the list of class of windows (typically set via the WM_CLASS property) which should be sticky. X.I Default value: Null X.P X.\" ======================================================================== X.SH COPYRIGHTS X.LP OPEN LOOK is a trademark of AT&T. X.br The X Window system is a trademark of the Massachusetts Institute of Technology. X.br OpenWindows is a trademark of Sun Microsystems, Inc. X.br Portions (c) Copyright 1989 Sun Microsystems, Inc. Sun design patents pending in the U.S. and foreign countries. OPEN LOOK is a trademark of AT&T. Used by written permission of the owners. X.br Portions (c) Copyright Bigelow & Holmes 1986, 1985. Lucida is a registered trademark of Bigelow & Holmes. Permission to use the Lucida trademark is hereby granted only in association with the images and fonts described in this file. X.br Portions may be (c) 1990 Solbourne Computers. X.br Please see the LEGAL_NOTICES file for full disclosure of copyright information. X X.\" ======================================================================== X.SH BUGS X.LP It's highly recommended to set the X.B olwm resource RefreshRecursively to False in order to get refreshes on the virtual desktop to work correctly. X.LP New frames should inherit the stickyness of their parent. X.LP The virtual desktop manager icon is, in the words of an office mate, X``pretty lame.'' Better yet, though, it should show feedback so it's possible to tell when on the desktop you are when it's closed. X.LP Need a way for base windows to be sticky on creation (but I don't like tvtwm's method of having particular applications sticky). X.LP Probably scores more; this was a weekend-type hack after all :-). END_OF_FILE if test 10814 -ne `wc -c <'olvwm.man'`; then echo shar: \"'olvwm.man'\" unpacked with wrong size! fi # end of 'olvwm.man' fi if test -f 'win.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'win.c'\" else echo shar: Extracting \"'win.c'\" \(9251 characters\) sed "s/^X//" >'win.c' <<'END_OF_FILE' X/* X * (c) Copyright 1989 Sun Microsystems, Inc. Sun design patents X * pending in the U.S. and foreign countries. See LEGAL_NOTICE X * file for terms of the license. X * X * Written for Sun Microsystems by Crucible, Santa Cruz, CA. X */ X static char sccsid[] = "@(#)win.c 1.2 olvwm version 3/30/91"; X X/* X * Based on static char sccsid[] = "@(#) win.c 25.6 90/05/20 Crucible"; X * X */ X X#include <stdio.h> X#include <memory.h> X#include <X11/Xos.h> X#include <X11/Xlib.h> X#include <X11/Xutil.h> X#include <X11/Xatom.h> X X#include "olwm.h" X#include "win.h" X#include "mem.h" X#include "st.h" X X#include "globals.h" X X/*************************************************************************** X* local functions X***************************************************************************/ X static enum st_retval doRedrawOneWindow(w,win,c) Window w; WinGeneric *win; void *c; X{ X if ((WinFunc(win,core.drawfunc) != NULL) && (win->core.client != NULL)) X (WinFunc(win,core.drawfunc))(win->core.client->dpy,win); X return ST_CONTINUE; X} X static void callSelectTree(dpy,win,sel) Display *dpy; WinGeneric *win; Bool sel; X{ X List *l = win->core.children; X X if (WinFunc(win,core.selectfunc) != NULL) X (*(WinFunc(win,core.selectfunc)))(dpy,win,sel); X for (win = ListEnum(&l); win != NULL; win = ListEnum(&l)) X callSelectTree(dpy, win, sel); X} X X/* Destroying a window tree: walk the trees associated with a client, X * invoking the destroyfuncs on each. The order that the windows are X * destroyed is significant; it works from the root upwards. The X * client structure is not affected; it is assumed that this function X * is only called from routines which take responsibility for removing X * the client structure as well. X */ static void callDestroyTree(dpy,win) Display *dpy; WinGeneric *win; X{ X List *l; X WinGeneric *cwin; X X if (win == NULL) X return; X l = win->core.children; X for (cwin = ListEnum(&l); cwin != NULL; cwin = ListEnum(&l)) X callDestroyTree(dpy, cwin); X if (WinFunc(win,core.destroyfunc) != NULL) X (*(WinFunc(win,core.destroyfunc)))(dpy,win); X} X static void setTreeConfig(dpy,win) Display *dpy; WinGeneric *win; X{ X List *l = win->core.children; X WinGeneric *wc; X X (*(WinFunc(win,core.setconfigfunc)))(dpy,win); X for (wc = ListEnum(&l); wc != NULL; wc = ListEnum(&l)) X { X setTreeConfig(dpy,wc); X } X} X static void callFocusTree(win, focus) WinGeneric *win; Bool focus; X{ X List *l; X WinGeneric *cwin; X X if (win == NULL) X return; X if (WinFunc(win,core.focusfunc) != NULL) X (WinFunc(win,core.focusfunc))(win->core.client->dpy,win,focus); X l = win->core.children; X for (cwin = ListEnum(&l); cwin != NULL; cwin = ListEnum(&l)) X callFocusTree(cwin, focus); X} X X static void callDrawTree(win) X WinGeneric *win; X{ X List *l; X WinGeneric *cwin; X X if (WinFunc(win,core.drawfunc) != NULL) X (WinFunc(win,core.drawfunc))(win->core.client->dpy,win); X X l = win->core.children; X for (cwin = ListEnum(&l); cwin != NULL; cwin = ListEnum(&l)) X callDrawTree(cwin); X} X X X/*************************************************************************** X* global functions X***************************************************************************/ X X/* WinCallSelect - call a client's select functions for either the icon or X * frame trees, depending on which is visible. Passes along sel, X * which is True iff the client is being selected. X */ void WinCallSelect(cli, sel) Client *cli; Bool sel; X{ X if (cli->wmState == NormalState) X callSelectTree(cli->dpy, cli->framewin, sel); X else if (cli->wmState == IconicState) X callSelectTree(cli->dpy, cli->iconwin, sel); X} X X/* WinCallFocus - call a client's focus functions for the frame tree. X * Passes along focus, which is True iff the client is gaining focus X */ void WinCallFocus(win,focus) WinGeneric *win; Bool focus; X{ X if (win == NULL) X return; X win->core.client->isFocus = focus; X callFocusTree(win, focus); X} X X/* WinCallDestroy - call a client's destroy functions for both the icon and X * frame trees X */ void WinCallDestroy(cli) Client *cli; X{ X Display *dpy = cli->dpy; X WinPaneFrame *framewin = cli->framewin; X WinIconFrame *iconwin = cli->iconwin; X X callDestroyTree(dpy, framewin); X callDestroyTree(dpy, iconwin); X} X X/* WinCallConfig - initiate a configuration change, starting at some X * particular window. X * Configuration change works as follows: a window is the initiator X * of the change. If the children of this window need to be sized, X * then they are called to do so; then the window sizes itself and X * sets the position of each of its children. This process is X * repeated on the parent of the initiating window, and so on up X * to the top window in the hierarchy (presumably a frame). X * A second pass then occurs, doing a depth-first preorder X * traversal of the window tree, performing the window's set X * configuration function to make the computed change. X * In the first pass, any window which changes its configuration X * should return this fact to be propagated back to this routine; X * if no window has changed configuration then the second pass X * won't be performed. X * The initiator window is passed (in some cases) the configure X * request event which cause the action to begin. X */ void WinCallConfig(dpy,win,pxcre) Display *dpy; WinGeneric *win; XXConfigureRequestEvent *pxcre; X{ X Bool fDirty = False; X WinGeneric *w; X X do X { X fDirty = (WinFunc(win,core.newconfigfunc))(win,pxcre) || fDirty; X pxcre = NULL; X w = win; X } X while ((win = win->core.parent) != NULL); X if (fDirty) X { X setTreeConfig(dpy,w); X } X} X X/* X * WinCallDraw X * Call all child windows' draw functions. X */ void WinCallDraw(win) X WinGeneric *win; X{ X callDrawTree(win); X} X X X/* WinAddChild -- add a child to a parent's list of children X */ void WinAddChild(parent,child) WinGeneric *parent; WinGeneric *child; X{ X parent->core.children = ListCons(child,parent->core.children); X child->core.parent = parent; X} X X/* WinRemoveChild -- remove a child from a parent's list of children X */ void WinRemoveChild(parent,child) WinGeneric *parent; WinGeneric *child; X{ X List **l; X X for (l = &(parent->core.children); *l != NULL; l = &((*l)->next)) X { X if ((WinGeneric *)((*l)->value) == child) X { X ListDestroyCell(l); X return; X } X } X#ifdef DEBUG X printf("Warning: tried to remove child %x from parent %x, but it wasn't there\n",child,parent); X#endif X} X X/* WinRootPos -- figure the root coordinates of a window's position X */ void WinRootPos(win,px,py) WinGeneric *win; int *px, *py; X{ X *px = 0; X *py = 0; X for ( ; win != NULL; win = win->core.parent) X { X *px += win->core.x; X *py += win->core.y; X } X} X X X/* WinRedrawAllWindows -- call every window's draw function (if provided) X */ void WinRedrawAllWindows() X{ X WIApply(doRedrawOneWindow, NULL); X} X X/*************************************************************************** X* general event/class functions X***************************************************************************/ X int WinEventExpose(dpy, event, win) Display *dpy; XXEvent *event; WinGeneric *win; X{ X if (event->xexpose.count == 0) X (WinFunc(win,core.drawfunc))(dpy, win); X else if (GRV.PrintAll) { X fprintf(stderr, "Expose event ignored\n"); X DebugWindow(win); X } X} X X int WinNewPosFunc(win,x,y) WinGeneric *win; int x,y; X{ X if (x != win->core.x) X { X win->core.x = x; X win->core.dirtyconfig |= CWX; X } X X if (y != win->core.y) X { X win->core.y = y; X win->core.dirtyconfig |= CWY; X } X X return win->core.dirtyconfig; X} X X int WinNewConfigFunc(win, pxcre) WinGeneric *win; XXConfigureRequestEvent *pxcre; X{ X int neww = WinFunc(win,core.widthfunc)(win, pxcre); X int newh = WinFunc(win,core.heightfunc)(win, pxcre); X X if (neww != win->core.width) X { X win->core.width = neww; X win->core.dirtyconfig |= CWWidth; X } X if (newh != win->core.height) X { X win->core.height = newh; X win->core.dirtyconfig |= CWHeight; X } X return win->core.dirtyconfig; X} X X int WinSetConfigFunc(dpy, win) Display *dpy; WinGeneric *win; X{ X XWindowChanges xwc; X X if (win->core.dirtyconfig) X { X xwc.x = win->core.x; X xwc.y = win->core.y; X xwc.width = win->core.width; X xwc.height = win->core.height; X /* generic windows never change border or stacking */ X XConfigureWindow(dpy,win->core.self,win->core.dirtyconfig,&xwc); X } X win->core.dirtyconfig &= ~(CWX|CWY|CWWidth|CWHeight); X} X X X/* X * WinAddColorClient X * X * Add cli to this win's list of colormap clients. Assumes that cli isn't X * already in the list. X */ void WinAddColorClient(win, cli) X WinGeneric *win; X Client *cli; X{ X win->core.colormapClients = ListCons(cli, win->core.colormapClients); X} X X X/* X * WinRemoveColorClient X * X * Remove cli from this win's list of colormap clients. If there are no more X * clients, and this window is a WIN_COLORMAP, destroy the window. Assumes X * that cli appears in win's list zero or one times. X */ void WinRemoveColorClient(dpy, win, cli) X Display *dpy; X WinGeneric *win; X Client *cli; X{ X List **l; X X l = &win->core.colormapClients; X while (*l != NULL) { X if ((*l)->value == cli) { X ListDestroyCell(l); X break; X } X l = &((*l)->next); X } X if (win->core.colormapClients == NULL_LIST X && win->core.kind == WIN_COLORMAP) X (WinFunc(win, core.destroyfunc))(dpy, win); X} END_OF_FILE if test 9251 -ne `wc -c <'win.c'`; then echo shar: \"'win.c'\" unpacked with wrong size! fi # end of 'win.c' fi if test -f 'winbutton.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'winbutton.c'\" else echo shar: Extracting \"'winbutton.c'\" \(9099 characters\) sed "s/^X//" >'winbutton.c' <<'END_OF_FILE' X/* X * (c) Copyright 1989, 1990 Sun Microsystems, Inc. Sun design patents X * pending in the U.S. and foreign countries. See LEGAL_NOTICE X * file for terms of the license. X * X * Written for Sun Microsystems by Crucible, Santa Cruz, CA. X */ X static char sccsid[] = "@(#)winbutton.c 1.2 olvwm version 3/30/91"; X X/* X * Based on static char sccsid[] = "@(#) winbutton.c 25.5 90/05/21 Crucible"; X * X */ X X#include <errno.h> X#include <stdio.h> X#include <X11/Xos.h> X#include <X11/Xlib.h> X#include <X11/Xutil.h> X#include <X11/Xatom.h> X#include <olgx/olgx.h> X#include "mem.h" X#include "olwm.h" X#include "win.h" X#include "globals.h" X X/*************************************************************************** X* global data X***************************************************************************/ X extern Graphics_info *olgx_gisnormal; extern GC DrawSelectedGC; extern GC DrawBackgroundGC; X X/*************************************************************************** X* private data X***************************************************************************/ X X#define in_windowmark(x,y) \ X ( (x) >= 0 && (y) >= 0 && \ X (x) <= Abbrev_MenuButton_Width(olgx_gisnormal) && \ X (y) <= Abbrev_MenuButton_Height(olgx_gisnormal) \ X ) static Bool buttonActive = False; static ClassButton classButton; X X/*************************************************************************** X* private functions X***************************************************************************/ X X/* X * eventButtonPress - handle button press events on the close button window. X */ static int eventButtonPress(dpy, event, winInfo) Display *dpy; XXEvent *event; WinButton *winInfo; X{ X Client *cli = winInfo->core.client; X WinPaneFrame *winFrame = cli->framewin; X X olgx_draw_abbrev_button(olgx_gisnormal, winInfo->core.self, X 0, 0, OLGX_INVOKED); X switch (MouseButton(dpy, event)) X { X case MB_ADJUST: X return; X X case MB_MENU: X if (winFrame->fcore.menu) X MenuShow(dpy, winFrame, winFrame->fcore.menu, event); X olgx_draw_abbrev_button(olgx_gisnormal, X winInfo->core.self, X 0, 0, OLGX_NORMAL | OLGX_ERASE); X return; X X } X XGrabPointer(dpy, winInfo->core.self, X False, X (ButtonReleaseMask | ButtonPressMask | PointerMotionMask), X GrabModeAsync, GrabModeAsync, X None, X GRV.MovePointer, X CurrentTime); X buttonActive = True; X} X X/* X * eventButtonRelease - handle button release events on the close button window. X */ static int eventButtonRelease(dpy, event, winInfo) Display *dpy; XXEvent *event; WinButton *winInfo; X{ X Client *cli = winInfo->core.client; X int x,y; X X /* REMIND: why is this necessary? The pointer should have X * been re-grabbed with GrabModeAsync, thus deactivating X * the grab upon the release of the button. */ X XUngrabPointer(dpy,event->xbutton.time); X X x = event->xbutton.x; X y = event->xbutton.y; X X buttonActive = False; X olgx_draw_abbrev_button(olgx_gisnormal, winInfo->core.self, X 0, 0, OLGX_NORMAL | OLGX_ERASE); X X if (!in_windowmark(x,y)) X { X return; X } X X /* we want to do the default action of the menu for this X * window. This will either be Iconify if the window is X * a base window, or dismiss if not */ X switch(cli->wmDecors->menu_type) X { X case MENU_FULL: X StateNormIcon(cli); X break; X X case MENU_NONE: X case MENU_LIMITED: X /* X * Send a WM_DELETE_WINDOW event. X * REMIND change to use event time X */ X ClientKill(cli,False); X break; X } X} X X/* X * eventMotionNotify - handle motion notify events on the close button window. X */ static int eventMotionNotify(dpy, event, winInfo) Display *dpy; XXEvent *event; WinButton *winInfo; X{ X Client *cli = winInfo->core.client; X int x,y; X X if (!event->xmotion.same_screen) X return; X X x = event->xmotion.x; X y = event->xmotion.y; X if ( buttonActive && !in_windowmark(x,y) ) { X olgx_draw_abbrev_button(olgx_gisnormal, winInfo->core.self, X 0, 0, OLGX_NORMAL | OLGX_ERASE); X buttonActive = False; X } else if ( !buttonActive && in_windowmark(x,y) ) { X olgx_draw_abbrev_button(olgx_gisnormal, winInfo->core.self, X 0, 0, OLGX_INVOKED); X buttonActive = True; X } X} X X/* X * drawButton -- draw the pushpin window X */ X/*ARGSUSED*/ /* dpy arg will be used when multiple Displays supported */ static int drawButton(dpy, winInfo) Display *dpy; WinButton *winInfo; X{ X GC erasegc; X X /* X * REMIND X * X * Erase the background first. Unfortunately, we can't depend on X * OLGX_ERASE to do the right thing, because it (a) erases only in BG1, X * and (b) erases only in 2D mode. We need to erase a background color X * that depends on the state of the frame. If we're in click-focus and we X * have the focus, draw in BG2; otherwise, draw in BG1. X */ X X if (!GRV.FocusFollowsMouse && winInfo->core.client->isFocus) X erasegc = DrawSelectedGC; X else X erasegc = DrawBackgroundGC; X X XFillRectangle(dpy, winInfo->core.self, erasegc, 0, 0, X Abbrev_MenuButton_Width(olgx_gisnormal), X Abbrev_MenuButton_Height(olgx_gisnormal)); X X olgx_draw_abbrev_button(olgx_gisnormal, winInfo->core.self, X 0, 0, OLGX_NORMAL | OLGX_ERASE); X} X X X/* X * DestroyButton -- destroy the close button window resources and free any allocated X * data. X */ static int destroyButton(dpy, winInfo) Display *dpy; WinButton *winInfo; X{ X /* free our data and throw away window */ X XDestroyWindow(dpy, winInfo->core.self); X WIUninstallInfo(winInfo->core.self); X MemFree(winInfo); X} X X/* X * focusButton - the focus or selection state has changed X */ static int focusButton(dpy, winInfo, selected) Display *dpy; WinButton *winInfo; Bool selected; X{ X (WinFunc(winInfo,core.drawfunc))(dpy, winInfo); X} X X/* X * heightfuncButton - recomputes the height of the close button window X */ static int heightfuncButton(win, pxcre) WinButton *win; XXConfigureRequestEvent *pxcre; X{ X return Abbrev_MenuButton_Width(olgx_gisnormal); X} X X/* X * widthfuncButton - recomputes the width of the close button window X */ static int widthfuncButton(win, pxcre) WinButton *win; XXConfigureRequestEvent *pxcre; X{ X return Abbrev_MenuButton_Height(olgx_gisnormal); X} X X X/*************************************************************************** X* global functions X***************************************************************************/ X X/* X * MakeButton -- create the close button window. Return a WinGeneric structure. X */ WinButton * MakeButton(dpy, par, x, y) Display *dpy; WinGeneric *par; int x,y; X{ X WinButton *w; X Window win; X unsigned long valuemask; X XSetWindowAttributes attributes; X X attributes.event_mask = X ButtonReleaseMask | ButtonPressMask | ExposureMask; X attributes.cursor = GRV.IconPointer; X valuemask = CWEventMask | CWCursor; X X win = XCreateWindow(dpy, par->core.self, X x, y, X Abbrev_MenuButton_Width(olgx_gisnormal), X Abbrev_MenuButton_Height(olgx_gisnormal), X 0, X DefaultDepth(dpy, DefaultScreen(dpy)), X CopyFromParent, X DefaultVisual(dpy, DefaultScreen(dpy)), X valuemask, X &attributes); X X /* create the associated structure */ X w = MemNew(WinButton); X w->core.self = win; X w->class = &classButton; X w->core.kind = WIN_WINBUTTON; X WinAddChild(par,w); X w->core.children = NULL; X w->core.client = par->core.client; X w->core.x = x; X w->core.y = y; X w->core.width = Abbrev_MenuButton_Width(olgx_gisnormal); X w->core.height = Abbrev_MenuButton_Height(olgx_gisnormal); X w->core.dirtyconfig = 0; X w->core.exposures = NULL; X X /* register the window */ X WIInstallInfo(w); X X XMapWindow(dpy, win); X X return w; X} X void ButtonInit(dpy) Display *dpy; X{ X classButton.core.kind = WIN_WINBUTTON; X classButton.core.xevents[ButtonPress] = eventButtonPress; X classButton.core.xevents[ButtonRelease] = eventButtonRelease; X classButton.core.xevents[MotionNotify] = eventMotionNotify; X classButton.core.xevents[Expose] = WinEventExpose; X classButton.core.focusfunc = focusButton; X classButton.core.drawfunc = drawButton; X classButton.core.destroyfunc = destroyButton; X classButton.core.selectfunc = NULL; X classButton.core.newconfigfunc = WinNewConfigFunc; X classButton.core.newposfunc = WinNewPosFunc; X classButton.core.setconfigfunc = WinSetConfigFunc; X classButton.core.createcallback = NULL; X classButton.core.heightfunc = heightfuncButton; X classButton.core.widthfunc = widthfuncButton; X} X END_OF_FILE if test 9099 -ne `wc -c <'winbutton.c'`; then echo shar: \"'winbutton.c'\" unpacked with wrong size! fi # end of 'winbutton.c' fi if test -f 'winpush.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'winpush.c'\" else echo shar: Extracting \"'winpush.c'\" \(10341 characters\) sed "s/^X//" >'winpush.c' <<'END_OF_FILE' X/* X * (c) Copyright 1989, 1990 Sun Microsystems, Inc. Sun design patents X * pending in the U.S. and foreign countries. See LEGAL_NOTICE X * file for terms of the license. X * X * Written for Sun Microsystems by Crucible, Santa Cruz, CA. X */ X static char sccsid[] = "@(#) winpush.c 25.7 90/05/21 Crucible"; X#include <errno.h> X#include <stdio.h> X#include <X11/Xos.h> X#include <X11/Xlib.h> X#include <X11/Xutil.h> X#include <X11/Xatom.h> X#include <olgx/olgx.h> X#include "mem.h" X#include "olwm.h" X#include "win.h" X#include "globals.h" X X/*************************************************************************** X* global data X***************************************************************************/ X extern Atom AtomDeleteWindow; extern Atom AtomPushpinState; extern Graphics_info *olgx_gisnormal; extern Graphics_info *olgx_gisrevpin; extern GC DrawBusyGC, DrawBackgroundGC; X X/*************************************************************************** X* private data X***************************************************************************/ X static ClassPushPin classPushPin; static Bool pushpinStateAfterPress; /* State of the pushpin X * after the user pressed X * the mouse button. */ X X/*************************************************************************** X* private functions X***************************************************************************/ X X/* locallyChangePushPinState -- temporarily change the pushpin state, X * while tracking a button press over the pin. The permanent change X * will be made later. X */ static void locallyChangePushPinState(dpy,winInfo,newState) Display *dpy; WinPushPin *winInfo; Bool newState; X{ X if (winInfo->pushpinin != newState) X { X winInfo->pushpinin = newState; X (WinFunc(winInfo,core.drawfunc))(dpy, winInfo); X } X} X X/* changePushPinState -- permanently change the push pin state */ static void changePushPinState(dpy, event, winInfo) Display *dpy; XXEvent *event; WinPushPin *winInfo; X{ X Client *cli = winInfo->core.client; X X (WinFunc(winInfo,core.drawfunc))(dpy, winInfo); X X /* Tell the client that the state of its push-pin X * has changed. X */ X XChangeProperty(dpy, PANEWINOFCLIENT(cli), X AtomPushpinState, X XA_INTEGER, 32, X PropModeReplace, X (unsigned char *)&(winInfo->pushpinin), 1); X X /* If the client has WM_DELETE_WINDOW in X * its WM_PROTOCOLS, then we should send X * a WM_DELETE_WINDOW client message. X */ X if (!winInfo->pushpinin) X { X ClientKill(winInfo->core.client,False); X } X#ifdef NOTDEF X /* Else just unmap the window. */ X /* REMIND what should we do here? (if client isn't in delete protocol) X else X XUnmapWindow(dpy, clientEvent.xclient.window); X */ X#endif X} X X/* X * eventButtonPress - handle button press events on the pushpin window X */ static int eventButtonPress(dpy, event, winInfo) Display *dpy; XXEvent *event; WinPushPin *winInfo; X{ X if (MouseButton(dpy,event) == MB_SELECT) X { X locallyChangePushPinState(dpy, winInfo, !(winInfo->pushpinin)); X pushpinStateAfterPress = winInfo->pushpinin; X } X} X X/* X * eventButtonRelease - handle button release events on the pushpin window X */ static int eventButtonRelease(dpy, event, winInfo) Display *dpy; XXEvent *event; WinPushPin *winInfo; X{ X /* X * If the user pressed the SELECT button, and the pin state is the X * same as it was just after he pressed the button over the pin, that X * means that we really are changing the pin state. Otherwise, the X * user has previewed a pin state change but has backed off, so we do X * nothing. X */ X if (MouseButton(dpy,event) == MB_SELECT && X pushpinStateAfterPress == winInfo->pushpinin) X { X changePushPinState(dpy,event,winInfo); X } X} X X/* X * eventMotionNotify - handle pointer moves X */ static int eventMotionNotify(dpy, event, winInfo) Display *dpy; XXEvent *event; WinPushPin *winInfo; X{ X Bool fInWindow; X X if (!event->xmotion.same_screen) X return; X X /* When the user moves the cursor off the pushpin X * while s/he has the button down we should pull X * the button out. If the user moves back onto the X * pushpin put the pin back in. So, X * X * if (cursor is off the pushpin) and (pin is in) X * OR X * (cursor is on the pushpin) and (pin is out) X * then X * change the state of the pushpin. X */ X fInWindow = !((event->xmotion.x < 0) || X (event->xmotion.y < 0) || X (event->xmotion.x >= PushPinOut_Width(olgx_gisnormal)) || X (event->xmotion.y >= PushPinOut_Height(olgx_gisnormal))); X locallyChangePushPinState(dpy, winInfo, X fInWindow?pushpinStateAfterPress:!pushpinStateAfterPress); X X /* REMIND Maybe we should do this by getting LeaveNotify events X * and seeing if MB_SELECT is pressed. If it is, then we X * know the user left the pushpin with the button pressed??? X */ X} X X X/* X * drawPushPin -- draw the pushpin window X */ X/*ARGSUSED*/ /* dpy arg will be used when multiple Displays supported */ static int drawPushPin(dpy, winInfo) Display *dpy; WinPushPin *winInfo; X{ X Client *cli = winInfo->core.client; X X /* If the titlebar is in reverse video we need to X * draw the pushpin in reverse video also. X */ X if (GRV.F3dUsed) { X /* X * REMIND X * We need to erase the background here to BG2. We can't use X * OLGX_ERASE because olgx erases only in BG1. So, we draw an X * filled, invoked box that is just larger than the pin X * window, so that the border doesn't show. X */ X olgx_draw_box(olgx_gisnormal, winInfo->core.self, -1, -1, X winInfo->core.width+2, X winInfo->core.height+2, X ((cli->isFocus) && (!GRV.FocusFollowsMouse))? X OLGX_INVOKED : OLGX_NORMAL, X True); X } else { X XFillRectangle(dpy, winInfo->core.self, DrawBackgroundGC, X 0, 0, winInfo->core.width, winInfo->core.height); X } X if (winInfo->core.client->isBusy) X { X XFillRectangle(dpy, winInfo->core.self, DrawBusyGC, X 0, 0, winInfo->core.width, winInfo->core.height); X } X olgx_draw_pushpin(olgx_gisnormal, winInfo->core.self, 0, 0, X ((winInfo->pushpinin) ? OLGX_PUSHPIN_IN : OLGX_PUSHPIN_OUT)); X} X X X/* X * DestroyPushPin -- destroy the pushpin window resources and free any allocated X * data. X */ static int destroyPushPin(dpy, winInfo) Display *dpy; WinPushPin *winInfo; X{ X /* free our data and throw away window */ X XDestroyWindow(dpy, winInfo->core.self); X WIUninstallInfo(winInfo->core.self); X MemFree(winInfo); X} X X/* X * focusselectPushPin - the focus or selection state has changed X */ static int focusselectPushPin(dpy, winInfo, selected) Display *dpy; WinPushPin *winInfo; Bool selected; X{ X (WinFunc(winInfo,core.drawfunc))(dpy, winInfo); X} X X/* X * heightfuncPushPin - recomputes the correct height of the window X */ static int heightfuncPushPin(win, pxcre) WinPushPin *win; XXConfigureRequestEvent *pxcre; X{ X return PushPinOut_Width(olgx_gisnormal); X} X X/* X * widthfuncPushPin - recomputes the correct width of the window X */ static int widthfuncPushPin(win, pxcre) WinPushPin *win; XXConfigureRequestEvent *pxcre; X{ X return PushPinOut_Height(olgx_gisnormal); X} X X/*************************************************************************** X* global functions X***************************************************************************/ X X/* X * MakePushPin -- create the pushpin window. Return a WinGeneric structure. X */ WinPushPin * MakePushPin(dpy, par, pane, x, y) Display *dpy; WinGeneric *par; Window pane; int x,y; X{ X WinPushPin *w; X Window win; X unsigned long valuemask; X XSetWindowAttributes attributes; X X attributes.event_mask = Button1MotionMask | ButtonReleaseMask | X ButtonPressMask | ExposureMask; X attributes.win_gravity = NorthWestGravity; X valuemask = CWEventMask | CWWinGravity; X X win = XCreateWindow(dpy, par->core.self, X x, y, X PushPinOut_Width(olgx_gisnormal), X PushPinOut_Height(olgx_gisnormal), X 0, X DefaultDepth(dpy, DefaultScreen(dpy)), X CopyFromParent, X DefaultVisual(dpy, DefaultScreen(dpy)), X valuemask, X &attributes); X X /* create the associated structure */ X w = MemNew(WinPushPin); X w->core.self = win; X w->class = &classPushPin; X w->core.kind = WIN_PUSHPIN; X WinAddChild(par,w); X w->core.children = NULL; X w->core.client = par->core.client; X w->core.x = x; X w->core.y = y; X w->core.width = PushPinOut_Width(olgx_gisnormal); X w->core.height = PushPinOut_Height(olgx_gisnormal); X w->core.dirtyconfig = CWX | CWY | CWWidth | CWHeight; X w->core.exposures = NULL; X X /* Determine initial state of push pin. */ X w->pushpinin = (par->core.client->wmDecors->pushpin_initial_state == PIN_IN); X X /* Register the push-pin state. */ X XChangeProperty(dpy, pane, X AtomPushpinState, X XA_INTEGER, 32, X PropModeReplace, X (unsigned char *)&(w->pushpinin), 1); X X /* register the window */ X WIInstallInfo(w); X X XMapRaised(dpy, win); X X return w; X} X void PushPinInit(dpy) Display *dpy; X{ X classPushPin.core.kind = WIN_PUSHPIN; X classPushPin.core.xevents[Expose] = WinEventExpose; X classPushPin.core.xevents[ButtonPress] = eventButtonPress; X classPushPin.core.xevents[ButtonRelease] = eventButtonRelease; X classPushPin.core.xevents[MotionNotify] = eventMotionNotify; X classPushPin.core.focusfunc = focusselectPushPin; X classPushPin.core.drawfunc = drawPushPin; X classPushPin.core.destroyfunc = destroyPushPin; X classPushPin.core.selectfunc = focusselectPushPin; X classPushPin.core.newconfigfunc = WinNewConfigFunc; X classPushPin.core.newposfunc = WinNewPosFunc; X classPushPin.core.setconfigfunc = WinSetConfigFunc; X classPushPin.core.createcallback = NULL; X classPushPin.core.heightfunc = heightfuncPushPin; X classPushPin.core.widthfunc = widthfuncPushPin; X} END_OF_FILE if test 10341 -ne `wc -c <'winpush.c'`; then echo shar: \"'winpush.c'\" unpacked with wrong size! fi # end of 'winpush.c' fi echo shar: End of archive 3 \(of 16\). cp /dev/null ark3isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 16 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Dan Heller O'Reilly && Associates Z-Code Software Comp-sources-x: Senior Writer President comp-sources.x@uunet.uu.net argv@ora.com argv@zipcode.com