Popup.c revision 444c061a
1/* $Xorg: Popup.c,v 1.4 2001/02/09 02:03:56 xorgcvs Exp $ */
2
3/***********************************************************
4
5Copyright 1987, 1988, 1994, 1998  The Open Group
6
7Permission to use, copy, modify, distribute, and sell this software and its
8documentation for any purpose is hereby granted without fee, provided that
9the above copyright notice appear in all copies and that both that
10copyright notice and this permission notice appear in supporting
11documentation.
12
13The above copyright notice and this permission notice shall be included in
14all copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23Except as contained in this notice, the name of The Open Group shall not be
24used in advertising or otherwise to promote the sale, use or other dealings
25in this Software without prior written authorization from The Open Group.
26
27
28Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
29
30                        All Rights Reserved
31
32Permission to use, copy, modify, and distribute this software and its
33documentation for any purpose and without fee is hereby granted,
34provided that the above copyright notice appear in all copies and that
35both that copyright notice and this permission notice appear in
36supporting documentation, and that the name of Digital not be
37used in advertising or publicity pertaining to distribution of the
38software without specific, written prior permission.
39
40DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
41ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
42DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
43ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
44WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
45ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
46SOFTWARE.
47
48******************************************************************/
49/* $XFree86$ */
50
51#ifdef HAVE_CONFIG_H
52#include <config.h>
53#endif
54#include "IntrinsicI.h"
55#include "ShellP.h"
56
57void _XtPopup(
58    Widget      widget,
59    XtGrabKind  grab_kind,
60    _XtBoolean  spring_loaded)
61{
62    register ShellWidget shell_widget = (ShellWidget) widget;
63
64    if (! XtIsShell(widget)) {
65	XtAppErrorMsg(XtWidgetToApplicationContext(widget),
66		"invalidClass","xtPopup",XtCXtToolkitError,
67                "XtPopup requires a subclass of shellWidgetClass",
68                  (String *)NULL, (Cardinal *)NULL);
69    }
70
71    if (! shell_widget->shell.popped_up) {
72	XtGrabKind call_data = grab_kind;
73	XtCallCallbacks(widget, XtNpopupCallback, (XtPointer)&call_data);
74	shell_widget->shell.popped_up = TRUE;
75	shell_widget->shell.grab_kind = grab_kind;
76	shell_widget->shell.spring_loaded = spring_loaded;
77	if (shell_widget->shell.create_popup_child_proc != NULL) {
78	    (*(shell_widget->shell.create_popup_child_proc))(widget);
79	}
80	if (grab_kind == XtGrabExclusive) {
81	    XtAddGrab(widget, TRUE, spring_loaded);
82	} else if (grab_kind == XtGrabNonexclusive) {
83	    XtAddGrab(widget, FALSE, spring_loaded);
84	}
85	XtRealizeWidget(widget);
86	XMapRaised(XtDisplay(widget), XtWindow(widget));
87    } else
88	XRaiseWindow(XtDisplay(widget), XtWindow(widget));
89
90} /* _XtPopup */
91
92void XtPopup (Widget widget, XtGrabKind grab_kind)
93{
94    Widget hookobj;
95
96    switch (grab_kind) {
97
98      case XtGrabNone:
99      case XtGrabExclusive:
100      case XtGrabNonexclusive:
101	break;
102
103      default:
104	XtAppWarningMsg(
105		XtWidgetToApplicationContext(widget),
106		"invalidGrabKind","xtPopup",XtCXtToolkitError,
107		"grab kind argument has invalid value; XtGrabNone assumed",
108		(String *)NULL, (Cardinal *)NULL);
109	grab_kind = XtGrabNone;
110    }
111
112    _XtPopup(widget, grab_kind, FALSE);
113
114    hookobj = XtHooksOfDisplay(XtDisplay(widget));
115    if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
116	XtChangeHookDataRec call_data;
117
118	call_data.type = XtHpopup;
119	call_data.widget = widget;
120	call_data.event_data = (XtPointer)grab_kind;
121	XtCallCallbackList(hookobj,
122		((HookObject)hookobj)->hooks.changehook_callbacks,
123		(XtPointer)&call_data);
124    }
125} /* XtPopup */
126
127void XtPopupSpringLoaded (
128    Widget widget)
129{
130    Widget hookobj;
131
132    _XtPopup(widget, XtGrabExclusive, True);
133
134    hookobj = XtHooksOfDisplay(XtDisplay(widget));
135    if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
136	XtChangeHookDataRec call_data;
137
138	call_data.type = XtHpopupSpringLoaded;
139	call_data.widget = widget;
140	XtCallCallbackList(hookobj,
141		((HookObject)hookobj)->hooks.changehook_callbacks,
142		(XtPointer)&call_data);
143    }
144}
145
146void XtPopdown(
147    Widget  widget)
148{
149    /* Unmap a shell widget if it is mapped, and remove from grab list */
150    Widget hookobj;
151    ShellWidget shell_widget = (ShellWidget) widget;
152    XtGrabKind grab_kind;
153
154    if (! XtIsShell(widget)) {
155	XtAppErrorMsg(XtWidgetToApplicationContext(widget),
156		"invalidClass","xtPopdown",XtCXtToolkitError,
157            "XtPopdown requires a subclass of shellWidgetClass",
158              (String *)NULL, (Cardinal *)NULL);
159    }
160
161#ifndef X_NO_XT_POPDOWN_CONFORMANCE
162    if (!shell_widget->shell.popped_up)
163        return;
164#endif
165
166    grab_kind = shell_widget->shell.grab_kind;
167    XWithdrawWindow(XtDisplay(widget), XtWindow(widget),
168		    XScreenNumberOfScreen(XtScreen(widget)));
169    if (grab_kind != XtGrabNone)
170	XtRemoveGrab(widget);
171    shell_widget->shell.popped_up = FALSE;
172    XtCallCallbacks(widget, XtNpopdownCallback, (XtPointer)&grab_kind);
173
174    hookobj = XtHooksOfDisplay(XtDisplay(widget));
175    if (XtHasCallbacks(hookobj, XtNchangeHook) == XtCallbackHasSome) {
176	XtChangeHookDataRec call_data;
177
178	call_data.type = XtHpopdown;
179	call_data.widget = widget;
180	XtCallCallbackList(hookobj,
181		((HookObject)hookobj)->hooks.changehook_callbacks,
182		(XtPointer)&call_data);
183    }
184} /* XtPopdown */
185
186/* ARGSUSED */
187void XtCallbackPopdown(
188    Widget  widget,
189    XtPointer closure,
190    XtPointer call_data)
191{
192    register XtPopdownID id = (XtPopdownID) closure;
193
194    XtPopdown(id->shell_widget);
195    if (id->enable_widget != NULL) {
196	XtSetSensitive(id->enable_widget, TRUE);
197    }
198} /* XtCallbackPopdown */
199