Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtcm / dtcm / deskset.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /*******************************************************************************
24 **
25 **  deskset.c
26 **
27 **  $TOG: deskset.c /main/4 1999/02/03 15:35:56 mgreess $
28 **
29 **  RESTRICTED CONFIDENTIAL INFORMATION:
30 **
31 **  The information in this document is subject to special
32 **  restrictions in a confidential disclosure agreement between
33 **  HP, IBM, Sun, USL, SCO and Univel.  Do not distribute this
34 **  document outside HP, IBM, Sun, USL, SCO, or Univel without
35 **  Sun's specific written approval.  This document and all copies
36 **  and derivative works thereof must be returned or destroyed at
37 **  Sun's request.
38 **
39 **  Copyright 1993 Sun Microsystems, Inc.  All rights reserved.
40 **
41 *******************************************************************************/
42
43 /*                                                                      *
44  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
45  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
46  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
47  * (c) Copyright 1993, 1994 Novell, Inc.                                *
48  */
49
50 #ifndef lint
51 static  char sccsid[] = "@(#)deskset.c 1.11 94/12/22 Copyr 1993 Sun Microsystems, Inc.";
52 #endif
53
54 #include <EUSCompat.h>
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <sys/stat.h>
58 #include <sys/param.h>
59 #include <string.h>
60 #ifndef SVR4
61 #include <strings.h>
62 #endif /* SVR4 */
63 #include <ctype.h>
64 #include <pwd.h>
65 #include <unistd.h>
66 #include <X11/X.h>
67 #include <X11/Intrinsic.h>
68 #include <X11/Xutil.h>
69 #include <Xm/Xm.h>
70 #include <Dt/Dt.h>
71 #include "deskset.h"
72 #include "revision.h"
73
74 #define DS_TITLE_LINE_HEIGHT    25
75
76 /******************************************************************************
77 **
78 **  Function:           ds_relname
79 **
80 **  Description:        Return revision name.
81 **              
82 **  Parameters:         None
83 **
84 **  Returns:            Revision name (char *)
85 **
86 ******************************************************************************/
87 extern char *
88 ds_relname()
89 {
90         static char     buf[MAXNAMELEN];
91
92         sprintf(buf, "Version %d.%d.%d Revision %d",
93                 DtVERSION, DtREVISION, DtUPDATE_LEVEL,
94                 DTCM_INTERNAL_REV);
95         return buf;
96 }
97
98 /*
99  * Function:       ds_position_popup
100  *
101  * Description:    Position a popup relative to the parent frame
102  *                 making sure it doesn't go off of the screen.
103  *
104  * Parameters:     base            Popup's parent widget
105  *                 popup           Popup widget
106  *                 location_op     Where you would like the popup to
107  *                                 appear.  Location_op may be any
108  *                                 the following:
109  *
110  * DS_POPUP_LEFT   Place the popup to the left of base with the tops flush
111  * DS_POPUP_RIGHT  Place the popup to the right of base with the tops flush
112  * DS_POPUP_ABOVE  Place the popup above base with the left edges flush
113  * DS_POPUP_BELOW  Place the popup below base with the left edges flush
114  * DS_POPUP_LOR    Place the popup either to the left or right of base
115  *                 depending on which side has the most space.
116  * DS_POPUP_AOF    Place the popup either above or below base
117  *                 depending on which side has the most space.
118  * DS_POPUP_CENTERED       Center popup within baseframe
119  *
120  * Returns:        0       Could not get screen size
121  *                 1       All is well
122  */
123 extern int
124 ds_position_popup(Widget base, Widget popup, ds_location_op location_op) {
125   int bh, bw, bx, by, ph, pw, px, py ;
126   int screen_width, screen_height ;
127   Position base_x, base_y, popup_x, popup_y ;
128   Dimension base_width, base_height, popup_width, popup_height ;
129
130   XtVaGetValues(base,
131                 XmNx,      &base_x,
132                 XmNy,      &base_y,
133                 XmNwidth,  &base_width,
134                 XmNheight, &base_height,
135                 0) ;
136   bx = (int) base_x ;
137   by = (int) base_y ;
138   bw = (int) base_width ;
139   bh = (int) base_height ;
140
141   XtVaGetValues(popup,
142                 XmNx,      &popup_x,
143                 XmNy,      &popup_y,
144                 XmNwidth,  &popup_width,
145                 XmNheight, &popup_height,
146                 0) ;
147
148   px = (int) popup_x ;
149   py = (int) popup_y ;
150   pw = (int) popup_width ;
151   ph = (int) popup_height ;
152
153   ds_get_screen_size(popup, &screen_width, &screen_height) ;
154  
155   if (location_op == DS_POPUP_LOR)
156     {
157       if (bx >= screen_width - bw - bx) location_op = DS_POPUP_LEFT ;
158       else                              location_op = DS_POPUP_RIGHT ;
159     }
160   else if (location_op == DS_POPUP_AOB)
161     {
162       if (by > screen_height - bh - by) location_op = DS_POPUP_ABOVE ;
163       else                              location_op = DS_POPUP_BELOW ;
164     }
165
166   switch (location_op)
167     {
168       case DS_POPUP_RIGHT    : px = bx + bw + 5 ;
169                                py = by - DS_TITLE_LINE_HEIGHT ;
170                                break ;
171       case DS_POPUP_LEFT     : px = bx - pw - 5 ;
172                                py = by - DS_TITLE_LINE_HEIGHT ;
173                                break ;
174       case DS_POPUP_ABOVE    : px = bx - 5 ;
175                                py = by - ph - 10 ;
176                                break ;
177       case DS_POPUP_BELOW    : px = bx - 5 ;
178                                py = by + bh + 5 ;
179                                break ;
180       case DS_POPUP_CENTERED :
181       default                : px = bx + (bw - pw) / 2 ;
182                                py = by + (bh - ph) / 2 ;
183     }
184   ds_force_popup_on_screen(popup, &px, &py) ;
185   return 1;
186 }
187
188
189 /*  Function:       ds_force_popup_on_screen
190  *
191  *  Description:    Make sure that the specified widget appears entirely
192  *                  on the screen.
193  *
194  *                  You specify the x and y where you would like the
195  *                  popup to appear.  If this location would cause any
196  *                  portion of the popup to appear off of the screen
197  *                  then the routine makes the minimum adjustments
198  *                  necessary to move it onto the screen.
199  *
200  *                  NOTE:   The following coordinates must be specified
201  *                          relative to the screen origin *not* the
202  *                          parent widget!
203  *
204  *  Parameters:     popup_x_p       Pointer to x location where you would
205  *                                  like the popup to appear.  If the popup
206  *                                  is moved this is updated to reflect
207  *                                  the new position.
208  *                  popup_y_p       Pointer to y location where you would
209  *                                  like the popup to appear.  If the popup
210  *                                  is moved this is updated to reflect
211  *                                  the new position.
212  *
213  *                  popup           Popup`s widget.
214  *
215  *  Returns:        TRUE    The popup was moved
216  *                  FALSE   The popup was not moved
217  */
218 extern int
219 ds_force_popup_on_screen(Widget popup, int *popup_x_p, int *popup_y_p) {
220   Dimension popup_width, popup_height ;
221   Position left, top ;
222   int popup_x, popup_y ;
223   int n, rcode, screen_width, screen_height ;
224
225   popup_x = *popup_x_p ;
226   popup_y = *popup_y_p ;
227
228 /* Get the screen size */
229
230   ds_get_screen_size(popup, &screen_width, &screen_height) ;
231
232   XtVaGetValues(popup,
233                 XmNwidth,  &popup_width,
234                 XmNheight, &popup_height,
235                 0) ;
236
237 /* Make sure frame does not go off side of screen */
238
239   n = popup_x + (int) popup_width ;
240   if (n > screen_width) popup_x -= (n - screen_width) ;
241   else if (popup_x < 0) popup_x = 0 ;
242
243 /* Make sure frame doen't go off top or bottom */
244
245   n = popup_y + (int) popup_height ;
246   if (n > screen_height) popup_y -= n - screen_height ;
247   else if (popup_y < 0) popup_y = 0 ;
248
249 /* Set location and return */
250
251   left = (Position) popup_x ;
252   top  = (Position) popup_y ;
253   XtVaSetValues(popup,
254                 XmNx, left,
255                 XmNy, top,
256                 0) ;
257
258   if (popup_x != *popup_x_p || popup_y != *popup_y_p) rcode = TRUE ;
259   else                                                rcode = FALSE ;
260   *popup_x_p = popup_x ;
261   *popup_y_p = popup_y ;
262   return(rcode) ;
263 }
264
265
266 /*  Function:       ds_get_screen_size
267  *
268  *  Description:    Get the width and height of the screen in pixels
269  *
270  *  Parameters:     width_p         Pointer to an integer to place width
271  *                  height_p        Pointer to an integer to place height
272  *        
273  *  Returns:        None.
274  */
275 extern void
276 ds_get_screen_size(Widget widget, int *width_p, int *height_p) {
277   Display *dpy  = XtDisplay(widget) ;
278   int screen    = DefaultScreen(dpy) ;
279  
280   *width_p  = DisplayWidth(dpy, screen) ;
281   *height_p = DisplayHeight(dpy, screen) ;
282 }