18108eb18Smrg/* $Xorg: popup.c,v 1.4 2001/02/09 02:06:01 xorgcvs Exp $ */ 28108eb18Smrg 38108eb18Smrg/* 48108eb18Smrg 58108eb18SmrgCopyright 1994, 1998 The Open Group 68108eb18Smrg 78108eb18SmrgPermission to use, copy, modify, distribute, and sell this software and its 88108eb18Smrgdocumentation for any purpose is hereby granted without fee, provided that 98108eb18Smrgthe above copyright notice appear in all copies and that both that 108108eb18Smrgcopyright notice and this permission notice appear in supporting 118108eb18Smrgdocumentation. 128108eb18Smrg 138108eb18SmrgThe above copyright notice and this permission notice shall be included 148108eb18Smrgin all copies or substantial portions of the Software. 158108eb18Smrg 168108eb18SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 178108eb18SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 188108eb18SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 198108eb18SmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 208108eb18SmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 218108eb18SmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 228108eb18SmrgOTHER DEALINGS IN THE SOFTWARE. 238108eb18Smrg 248108eb18SmrgExcept as contained in this notice, the name of The Open Group shall 258108eb18Smrgnot be used in advertising or otherwise to promote the sale, use or 268108eb18Smrgother dealings in this Software without prior written authorization 278108eb18Smrgfrom The Open Group. 288108eb18Smrg 298108eb18Smrg*/ 308108eb18Smrg/* $XFree86: xc/programs/xsm/popup.c,v 1.4 2001/01/17 23:46:30 dawes Exp $ */ 318108eb18Smrg 328108eb18Smrg#include "xsm.h" 338108eb18Smrg#include <X11/Shell.h> 348108eb18Smrg#include "popup.h" 358108eb18Smrg 368108eb18Smrg 378108eb18Smrgvoid 388108eb18SmrgPopupPopup(Widget parent, Widget popup, Bool transient, Bool first_time, 395977a007Smrg int offset_x, int offset_y, const _XtString delAction) 408108eb18Smrg{ 418108eb18Smrg if (!transient && !first_time) 428108eb18Smrg { 438108eb18Smrg /* 448108eb18Smrg * For non-transient windows, if this isn't the first time 458108eb18Smrg * it's being popped up, just pop it up in the old position. 468108eb18Smrg */ 478108eb18Smrg 488108eb18Smrg XtPopup (popup, XtGrabNone); 498108eb18Smrg return; 508108eb18Smrg } 518108eb18Smrg else 528108eb18Smrg { 538108eb18Smrg Position parent_x, parent_y; 548108eb18Smrg Position root_x, root_y; 558108eb18Smrg Position popup_x, popup_y; 568108eb18Smrg Dimension parent_width, parent_height, parent_border; 578108eb18Smrg Dimension popup_width, popup_height, popup_border; 588108eb18Smrg char geom[16]; 598108eb18Smrg Bool repos = 0; 608108eb18Smrg 618108eb18Smrg /* 628108eb18Smrg * The window we pop up must be visible on the screen. We first 638108eb18Smrg * try to position it at the desired location (relative to the 648108eb18Smrg * parent widget). Once we are able to compute the popup's 658108eb18Smrg * geometry (after it's realized), we can determine if we need 668108eb18Smrg * to reposition it. 678108eb18Smrg */ 688108eb18Smrg 698108eb18Smrg XtVaGetValues (parent, 708108eb18Smrg XtNx, &parent_x, 718108eb18Smrg XtNy, &parent_y, 728108eb18Smrg XtNwidth, &parent_width, 738108eb18Smrg XtNheight, &parent_height, 748108eb18Smrg XtNborderWidth, &parent_border, 758108eb18Smrg NULL); 768108eb18Smrg 778108eb18Smrg XtTranslateCoords (parent, parent_x, parent_y, &root_x, &root_y); 788108eb18Smrg 798108eb18Smrg popup_x = root_x + offset_x; 808108eb18Smrg popup_y = root_y + offset_y; 818108eb18Smrg 828108eb18Smrg if (transient) 838108eb18Smrg { 848108eb18Smrg XtVaSetValues (popup, 858108eb18Smrg XtNx, popup_x, 868108eb18Smrg XtNy, popup_y, 878108eb18Smrg NULL); 888108eb18Smrg } 898108eb18Smrg else 908108eb18Smrg { 911a650d1eSmrg snprintf (geom, sizeof(geom), "+%d+%d", popup_x, popup_y); 928108eb18Smrg 938108eb18Smrg XtVaSetValues (popup, 948108eb18Smrg XtNgeometry, geom, 958108eb18Smrg NULL); 968108eb18Smrg } 978108eb18Smrg 988108eb18Smrg if (first_time) 998108eb18Smrg { 1008108eb18Smrg /* 1018108eb18Smrg * Realize it for the first time 1028108eb18Smrg */ 1038108eb18Smrg 1048108eb18Smrg XtRealizeWidget (popup); 1058108eb18Smrg 1068108eb18Smrg 1078108eb18Smrg /* 1088108eb18Smrg * Set support for WM_DELETE_WINDOW 1098108eb18Smrg */ 1108108eb18Smrg 1118108eb18Smrg (void) SetWM_DELETE_WINDOW (popup, delAction); 1128108eb18Smrg } 1138108eb18Smrg 1148108eb18Smrg /* 1158108eb18Smrg * Now make sure it's visible. 1168108eb18Smrg */ 1178108eb18Smrg 1188108eb18Smrg XtVaGetValues (popup, 1198108eb18Smrg XtNwidth, &popup_width, 1208108eb18Smrg XtNheight, &popup_height, 1218108eb18Smrg XtNborderWidth, &popup_border, 1228108eb18Smrg NULL); 1238108eb18Smrg 1248108eb18Smrg popup_border <<= 1; 1258108eb18Smrg 1268108eb18Smrg if ((int) (popup_x + popup_width + popup_border) > 1278108eb18Smrg WidthOfScreen (XtScreen (topLevel))) 1288108eb18Smrg { 1298108eb18Smrg popup_x = WidthOfScreen (XtScreen (topLevel)) - 1308108eb18Smrg popup_width - popup_border - parent_width - parent_border; 1318108eb18Smrg 1328108eb18Smrg repos = 1; 1338108eb18Smrg } 1348108eb18Smrg 1358108eb18Smrg if ((int) (popup_y + popup_height + popup_border) > 1368108eb18Smrg HeightOfScreen (XtScreen (topLevel))) 1378108eb18Smrg { 1388108eb18Smrg popup_y = HeightOfScreen (XtScreen (topLevel)) - 1398108eb18Smrg popup_height - popup_border - parent_height - parent_border; 1408108eb18Smrg 1418108eb18Smrg repos = 1; 1428108eb18Smrg } 1438108eb18Smrg 1448108eb18Smrg if (repos) 1458108eb18Smrg { 1468108eb18Smrg if (transient) 1478108eb18Smrg { 1488108eb18Smrg XtVaSetValues (popup, 1498108eb18Smrg XtNx, popup_x, 1508108eb18Smrg XtNy, popup_y, 1518108eb18Smrg NULL); 1528108eb18Smrg } 1538108eb18Smrg else 1548108eb18Smrg { 1558108eb18Smrg /* 1568108eb18Smrg * The only way we can reposition a non-transient 1578108eb18Smrg * is by unrealizing it, setting the position, then 1588108eb18Smrg * doing a realize. 1598108eb18Smrg */ 1608108eb18Smrg 1618108eb18Smrg XtUnrealizeWidget (popup); 1628108eb18Smrg 1631a650d1eSmrg snprintf (geom, sizeof(geom), "+%d+%d", popup_x, popup_y); 1648108eb18Smrg 1658108eb18Smrg XtVaSetValues (popup, 1668108eb18Smrg XtNgeometry, geom, 1678108eb18Smrg NULL); 1688108eb18Smrg 1698108eb18Smrg XtRealizeWidget (popup); 1708108eb18Smrg 1718108eb18Smrg (void) SetWM_DELETE_WINDOW (popup, delAction); 1728108eb18Smrg } 1738108eb18Smrg } 1748108eb18Smrg 1758108eb18Smrg XtPopup (popup, XtGrabNone); 1768108eb18Smrg } 1778108eb18Smrg} 178