cdesktopenv/cde/programs/dtwm/WmOL.c

471 lines
12 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/*
* (c) Copyright 1989 Sun Microsystems, Inc.
* (c) Copyright 1993 HEWLETT-PACKARD COMPANY
* ALL RIGHTS RESERVED
*/
/*
* Included Files:
*/
#include <stdlib.h>
#include "WmGlobal.h"
#include "WmOL.h"
#include "WmProperty.h"
#include <Xm/AtomMgr.h>
#define ValidPropertyList(pcd) ((pcd)->paInitialProperties != NULL)
/*************************************<->*************************************
*
* InitOLCompat ()
*
* Description:
* -----------
* Interns the atoms necessary for OL protocols.
*
* Inputs:
* ------
*
* Outputs:
* --------
*
*************************************<->***********************************/
void
InitOLCompat(void)
{
wmGD.xa_OL_WIN_ATTR =
XmInternAtom (DISPLAY, OL_WIN_ATTR, False);
wmGD.xa_OL_DECOR_RESIZE =
XmInternAtom (DISPLAY, OL_DECOR_RESIZE, False);
wmGD.xa_OL_DECOR_HEADER =
XmInternAtom (DISPLAY, OL_DECOR_HEADER, False);
wmGD.xa_OL_DECOR_CLOSE =
XmInternAtom (DISPLAY, OL_DECOR_CLOSE, False);
wmGD.xa_OL_DECOR_PIN =
XmInternAtom (DISPLAY, OL_DECOR_PIN, False);
wmGD.xa_OL_DECOR_ADD =
XmInternAtom (DISPLAY, OL_DECOR_ADD, False);
wmGD.xa_OL_DECOR_DEL =
XmInternAtom (DISPLAY, OL_DECOR_DEL, False);
wmGD.xa_OL_WT_BASE =
XmInternAtom (DISPLAY, OL_WT_BASE, False);
wmGD.xa_OL_WT_COMMAND =
XmInternAtom (DISPLAY, OL_WT_CMD, False);
wmGD.xa_OL_WT_HELP =
XmInternAtom (DISPLAY, OL_WT_HELP, False);
wmGD.xa_OL_WT_NOTICE =
XmInternAtom (DISPLAY, OL_WT_NOTICE, False);
wmGD.xa_OL_WT_OTHER =
XmInternAtom (DISPLAY, OL_WT_OTHER, False);
wmGD.xa_OL_PIN_IN =
XmInternAtom (DISPLAY, OL_PIN_IN, False);
wmGD.xa_OL_PIN_OUT =
XmInternAtom (DISPLAY, OL_PIN_OUT, False);
wmGD.xa_OL_MENU_LIMITED =
XmInternAtom (DISPLAY, OL_MENU_LIMITED, False);
wmGD.xa_OL_MENU_FULL =
XmInternAtom (DISPLAY, OL_MENU_FULL, False);
} /* END OF FUNCTION InitOLCompat */
/*************************************<->*************************************
*
* HasOpenLookHints (pCD)
*
* Description:
* -----------
* Returns True if this client has OpenLook hints on it.
*
* Inputs:
* ------
* pCD = pointer to client data
*
* Outputs:
* --------
* Returns True if client has the _OL_WIN_ATTR property on it.
*
*************************************<->***********************************/
Boolean
HasOpenLookHints(
ClientData *pCD )
{
Boolean rval = False;
OLWinAttr *property = NULL;
if (ValidPropertyList (pCD) &&
HasProperty(pCD, wmGD.xa_OL_WIN_ATTR))
{
rval = True;
}
else if ((property=GetOLWinAttr (pCD)) != NULL)
{
XFree ((char *) property);
rval = True;
}
return (rval);
} /* END OF FUNCTION HasOpenLookHints */
/*************************************<->*************************************
*
* GetOLWinAttr (pCD)
*
* Description:
* -----------
* Fetches the OLWinAttr property off of the client
*
* Inputs:
* ------
* pCD = pointer to client data
*
* Outputs:
* --------
* Returns a pointer to the OLWinAttr property if found and valid.
* (Returned data should be freed with XFree())
* Returns NULL pointer otherwise.
*
*************************************<->***********************************/
OLWinAttr *
GetOLWinAttr(
ClientData *pCD )
{
Boolean rval = False;
OLWinAttr *property = NULL;
OLWinAttr *prop_new;
Atom actual_type;
int actual_format;
unsigned long nitems;
unsigned long leftover;
int ret_val;
ret_val = XGetWindowProperty (DISPLAY, pCD->client, wmGD.xa_OL_WIN_ATTR,
0L, ENTIRE_CONTENTS,
False, wmGD.xa_OL_WIN_ATTR,
&actual_type, &actual_format,
&nitems, &leftover, (unsigned char **)&property);
if (ret_val != Success)
{
property = NULL;
}
else if ((actual_format != 32) ||
(actual_type != wmGD.xa_OL_WIN_ATTR))
{
if (property)
XFree((char *)property);
property = NULL;
}
if (property && (nitems == OLDOLWINATTRLENGTH))
{
/* Old size, convert to new size */
/*
* !!! Should use XAlloc() here, but Xlib doesn't
* define an inverse function of XFree(). !!!
*/
prop_new = (OLWinAttr *) malloc (sizeof(OLWinAttr));
prop_new->flags = WA_WINTYPE | WA_MENUTYPE | WA_PINSTATE;
prop_new->win_type = ((old_OLWinAttr *)property)->win_type;
prop_new->menu_type = ((old_OLWinAttr *)property)->menu_type;
prop_new->pin_initial_state =
((old_OLWinAttr *)property)->pin_initial_state;
XFree ((char *) property);
property = prop_new;
}
/* convert pin state for old clients */
if (property && (property->flags & WA_PINSTATE))
{
if (property->pin_initial_state == wmGD.xa_OL_PIN_IN)
{
property->pin_initial_state = PIN_IN;
}
else if (property->pin_initial_state == wmGD.xa_OL_PIN_OUT)
{
property->pin_initial_state = PIN_OUT;
}
}
return (property);
} /* END OF FUNCTION GetOLWinAttr */
/*************************************<->*************************************
*
* GetOLDecorFlags (pCD, property, pDecor)
*
* Description:
* -----------
* Fetches the _OL_DECOR_ADD or _OL_DECOR_DEL property off of the
* client and returns OL flavored decor flags.
*
* Inputs:
* ------
* pCD = pointer to client data
* property = property to fetch
* pDecor = pointer to OL decor flags word
*
* Outputs:
* --------
* Return = True if property found, False otherwise
* *pDecor = OL decor flags if valid property found,
* undefined if property not found.
*
*************************************<->***********************************/
Boolean
GetOLDecorFlags(
ClientData *pCD,
Atom property,
unsigned long *pDecor)
{
int status, i;
Boolean rval;
Atom actual_type;
int actual_format;
unsigned long nitems;
unsigned long leftover;
Atom *pAtoms = NULL;
status = XGetWindowProperty (DISPLAY, pCD->client, property,
0L, ENTIRE_CONTENTS,
False, XA_ATOM,
&actual_type, &actual_format,
&nitems, &leftover, (unsigned char **)&pAtoms);
if ((status != Success) ||
!pAtoms ||
(nitems == 0) ||
(actual_type != XA_ATOM) ||
(actual_format != 32))
{
if (pAtoms)
XFree((char *)pAtoms);
rval = False;
}
else
{
*pDecor = 0;
/*
* We only look for the ones we might be interested in.
* Several OL decoration types are ignored.
*/
for (i = 0; i < nitems; i++) {
if (pAtoms[i] == wmGD.xa_OL_DECOR_RESIZE)
*pDecor |= OLDecorResizable;
else if (pAtoms[i] == wmGD.xa_OL_DECOR_HEADER)
*pDecor |= OLDecorHeader;
else if (pAtoms[i] == wmGD.xa_OL_DECOR_CLOSE)
*pDecor |= OLDecorCloseButton;
else if (pAtoms[i] == wmGD.xa_OL_DECOR_PIN)
*pDecor |= OLDecorPushPin;
}
XFree((char *)pAtoms);
rval = True;
}
return (rval);
} /* END OF FUNCTION GetOLDecorFlags */
/*************************************<->*************************************
*
* ProcessOLDecoration (pCD)
*
* Description:
* -----------
*
* Inputs:
* ------
* pCD = pointer to client data
*
* Outputs:
* --------
* pCD = possibly modified with new decoration info
*
*************************************<->***********************************/
void
ProcessOLDecoration(
ClientData *pCD)
{
OLWinAttr * pOLWinAttr;
unsigned long OLdecor;
long decorMask;
if (HasOpenLookHints (pCD) &&
((pOLWinAttr = GetOLWinAttr (pCD)) != NULL))
{
/*
* This window already has some decoration applied to
* it based on its ICCCM type (transient or not).
* Use the OL hints to construct a mask to further
* modify these decorations.
*/
if ((pOLWinAttr->flags & WA_WINTYPE) == 0)
{
/*
* Window type not specified, assume all decorations
*/
decorMask = WM_DECOR_ALL;
}
else if (pOLWinAttr->win_type == wmGD.xa_OL_WT_BASE)
{
/*
* Base windows can have all decorations
*/
decorMask = WM_DECOR_ALL;
}
else if (pOLWinAttr->win_type == wmGD.xa_OL_WT_COMMAND)
{
/*
* Command windows have titles, pins (close button), and
* resize handles.
*/
decorMask = WM_DECOR_TITLE | WM_DECOR_SYSTEM | WM_DECOR_RESIZEH;
}
else if (pOLWinAttr->win_type == wmGD.xa_OL_WT_HELP)
{
/*
* Help windows have titles and pins (close button).
* No resize, but give it a border to look nicer.
*/
decorMask = (WM_DECOR_TITLE | WM_DECOR_SYSTEM | WM_DECOR_BORDER);
}
else if ((pOLWinAttr->win_type == wmGD.xa_OL_WT_NOTICE) &&
(pOLWinAttr->win_type == wmGD.xa_OL_WT_OTHER))
{
decorMask = WM_DECOR_NONE;
}
else
{
decorMask = WM_DECOR_ALL;
}
if (GetOLDecorAdd(pCD,&OLdecor))
{
if (OLdecor & OLDecorResizable)
{
decorMask |= WM_DECOR_RESIZEH;
}
if (OLdecor & OLDecorHeader)
{
decorMask |= WM_DECOR_TITLE;
}
if (OLdecor & OLDecorCloseButton)
{
/* OL "close" is same as "Motif" minimize */
decorMask |= MWM_DECOR_MINIMIZE;
}
if (OLdecor & OLDecorPushPin)
{
/*
* windows with pins can't be minimized
*/
decorMask &= ~MWM_DECOR_MINIMIZE;
decorMask |= MWM_DECOR_TITLE | MWM_DECOR_MENU;
}
}
if (GetOLDecorDel(pCD,&OLdecor))
{
if (OLdecor & OLDecorResizable)
{
decorMask &= ~MWM_DECOR_RESIZEH;
}
if (OLdecor & OLDecorHeader)
{
decorMask &= ~WM_DECOR_TITLEBAR;
}
if (OLdecor & OLDecorCloseButton)
{
/* OL "close" is same as "Motif" minimize */
decorMask &= ~MWM_DECOR_MINIMIZE;
}
/* push pin is ignored here */
}
/*
* If the window has a push pin or a limited menu,
* then consider it very similar to a secondary window.
*/
if (((pOLWinAttr->flags & WA_PINSTATE) &&
(pOLWinAttr->pin_initial_state == PIN_IN)) ||
((pOLWinAttr->flags & WA_MENUTYPE) &&
(pOLWinAttr->menu_type == wmGD.xa_OL_MENU_LIMITED)))
{
decorMask &= ~(MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE);
pCD->bPseudoTransient = True;
pCD->dtwmFunctions &= ~DtWM_FUNCTION_OCCUPY_WS;
}
/*
* Reduce decoration on this window according to OL hints
*/
pCD->clientDecoration &= decorMask;
/*
* Reduce client functions if necessary.
*/
if (!(decorMask & MWM_DECOR_MINIMIZE))
{
pCD->clientFunctions &= ~MWM_FUNC_MINIMIZE;
}
if (!(decorMask & MWM_DECOR_MAXIMIZE))
{
pCD->clientFunctions &= ~MWM_FUNC_MAXIMIZE;
}
if (!(decorMask & MWM_DECOR_RESIZEH))
{
pCD->clientFunctions &= ~MWM_FUNC_RESIZE;
}
/*
* Set the clients secondariesOnTop value to false to allow
* open look transient behaviour (transients below primary).
*/
pCD->secondariesOnTop = False;
if (pOLWinAttr)
XFree((char *)pOLWinAttr);
}
} /* END OF FUNCTION ProcessOLDecoration */