152) How can I put decorations on transient windows using olwm?

Answer: From Jean-Philippe Martin-Flatin <syj@ecmwf.co.uk>

/**********************************************************************
** WindowDecorations.c
**
** Manages window decorations under the OpenLook window manager (OLWM).
**
** Adapted from a C++ program posted to comp.windows.x.motif by:
**
**    +--------------------------------------------------------------+
**    | Ron Edmark                          User Interface Group     |
**    | Tel:        (408) 980-1500 x282     Integrated Systems, Inc. |
**    | Internet:   edmark@isi.com          3260 Jay St.             |
**    | Voice mail: (408) 980-1590 x282     Santa Clara, CA 95054    |
**    +--------------------------------------------------------------+
***********************************************************************/

#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Protocols.h>
#include <Xm/Xm.h>
#include <Xm/AtomMgr.h>

/*
** Decorations for OpenLook:
** The caller can OR different mask options to change the frame decoration.
*/
#define OLWM_Header     (long)(1<<0)
#define OLWM_Resize     (long)(1<<1)
#define OLWM_Close      (long)(1<<2)

/*
** Prototypes
*/
static void InstallOLWMAtoms  (Widget w);
static void AddOLWMDialogFrame(Widget widget, long decorationMask);


/*
** Global variables
*/
static Atom AtomWinAttr;
static Atom AtomWTOther;
static Atom AtomDecor;
static Atom AtomResize;
static Atom AtomHeader;
static Atom AtomClose;
static int  not_installed_yet = TRUE;


static void InstallOLWMAtoms(Widget w)
{
        AtomWinAttr = XInternAtom(XtDisplay(w), "_OL_WIN_ATTR" ,    FALSE);
        AtomWTOther = XInternAtom(XtDisplay(w), "_OL_WT_OTHER",     FALSE);
        AtomDecor   = XInternAtom(XtDisplay(w), "_OL_DECOR_ADD",    FALSE);
        AtomResize  = XInternAtom(XtDisplay(w), "_OL_DECOR_RESIZE", FALSE);
        AtomHeader  = XInternAtom(XtDisplay(w), "_OL_DECOR_HEADER", FALSE);
        AtomClose   = XInternAtom(XtDisplay(w), "_OL_DECOR_CLOSE",  FALSE);

        not_installed_yet = FALSE;
}

static void AddOLWMDialogFrame(Widget widget, long decorationMask)
{
        Atom   winAttrs[2];
        Atom   winDecor[3];
        Widget shell = widget;
        Window win;
        int    numberOfDecorations = 0;

        /*
        ** Make sure atoms for OpenLook are installed only once
        */
        if (not_installed_yet) InstallOLWMAtoms(widget);

        while (!XtIsShell(shell)) shell = XtParent(shell);

        win = XtWindow(shell);

        /*
        ** Tell Open Look that our window is not one of the standard OLWM window        ** types. See OLIT Widget Set Programmer's Guide pp.70-73.
        */

        winAttrs[0] = AtomWTOther;

        XChangeProperty(XtDisplay(shell),
                        win,
                        AtomWinAttr,
                        XA_ATOM,
                        32,
                        PropModeReplace,
                        (unsigned char*)winAttrs,
                        1);

        /*
        ** Tell Open Look to add some decorations to our window
        */
        numberOfDecorations = 0;
        if (decorationMask & OLWM_Header)
                winDecor[numberOfDecorations++] = AtomHeader;
        if (decorationMask & OLWM_Resize)
                winDecor[numberOfDecorations++] = AtomResize;
        if (decorationMask & OLWM_Close)
        {
                winDecor[numberOfDecorations++] = AtomClose;

                /*
                ** If the close button is specified, the header must be
                ** specified. If the header bit is not set, set it.
                */
                if (!(decorationMask & OLWM_Header))
                        winDecor[numberOfDecorations++] = AtomHeader;
        }

        XChangeProperty(XtDisplay(shell),
                        win,
                        AtomDecor,
                        XA_ATOM,
                        32,
                        PropModeReplace,
                        (unsigned char*)winDecor,
                        numberOfDecorations);
}


/*
** Example of use of AddOLWMDialogFrame, with a bit of extra stuff
*/
void register_dialog_to_WM(Widget shell, XtCallbackProc Cbk_func)
{
        Atom atom;

        /*
        ** Alias the "Close" item in system menu attached to dialog shell
        ** to the activate callback of "Exit" in the menubar
        */
        if (Cbk_func)
        {
            atom = XmInternAtom(XtDisplay(shell),"WM_DELETE_WINDOW",TRUE);
            XmAddWMProtocolCallback(shell,atom, Cbk_func,NULL);
        }

        /*
        ** If Motif is the window manager, skip OpenLook specific stuff
        */
        if (XmIsMotifWMRunning(shell)) return;

        /*
        ** Register dialog shell to OpenLook.
        **
        ** WARNING: on some systems, adding the "Close" button allows the title
        ** to be properly centered in the title bar. On others, activating
        ** "Close" crashes OpenLook. The reason is not clear yet, but it seems
        ** the first case occurs with OpenWindows 2 while the second occurs with
        ** Openwindows 3. Thus, comment out one of the two following lines as
        ** suitable for your site, and send e-mail to syj@ecmwf.co.uk if you
        ** find out what is going on !
        */
        AddOLWMDialogFrame(shell,(OLWM_Header | OLWM_Resize));
/*      AddOLWMDialogFrame(shell,(OLWM_Header | OLWM_Resize | OLWM_Close)); */
}
Go Back Up

Go To Previous

Go To Next