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