dtcm: Coverity 88353
[oweals/cde.git] / cde / programs / dtwm / WmCDInfo.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 libraries 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  * (c) Copyright 1989, 1990, 1991, 1992, 1993 OPEN SOFTWARE FOUNDATION, INC. 
25  * ALL RIGHTS RESERVED 
26 */ 
27 /* 
28  * Motif Release 1.2.3
29 */
30 /*
31  * (c) Copyright 1987, 1988, 1989, 1990 HEWLETT-PACKARD COMPANY */
32
33 /*
34  * Included Files:
35  */
36
37 #include "WmGlobal.h"
38 #include "WmCDInfo.h"
39
40
41 \f
42 /*************************************<->*************************************
43  *
44  *  unsigned int TitleTextHeight (pcd)
45  *
46  *
47  *  Description:
48  *  -----------
49  *  Returns the height of the title text plus padding
50  *
51  *  Inputs:
52  *  ------
53  *  pcd                 - pointer to client data record
54  * 
55  *  Outputs:
56  *  -------
57  *  TitleTextHeight     -  Height of title text plus padding
58  *
59  *  Comments:
60  *  --------
61  * 
62  *************************************<->***********************************/
63 unsigned int TitleTextHeight (ClientData *pcd)
64 {
65     unsigned int ttextheight;
66
67     if (DECOUPLE_TITLE_APPEARANCE(pcd))
68     {
69         ttextheight = CLIENT_TITLE_APPEARANCE(pcd).titleHeight;
70     }
71     else
72     {
73         ttextheight = CLIENT_APPEARANCE(pcd).titleHeight;
74     }
75     return (ttextheight);
76 }
77
78 \f
79 /*************************************<->*************************************
80  *
81  *  unsigned int InitTitleBarHeight (pcd)
82  *
83  *
84  *  Description:
85  *  -----------
86  *  Used to initialize pCD->frameInfo.titleBarHeight which is used by the new
87  *  macro TitleBarHeight().  Returns the height of the title bar.
88  *
89  *  Inputs:
90  *  ------
91  *  pcd                 - pointer to client data record
92  * 
93  *  Outputs:
94  *  -------
95  *  InitTitleBarHeight  -  height of title bar, 0 if no title bar.
96  *
97  *  Comments:
98  *  --------
99  * 
100  *************************************<->***********************************/
101 unsigned int InitTitleBarHeight (ClientData *pcd)
102 {
103     unsigned int tbarheight;
104
105     if (pcd->decor & MWM_DECOR_TITLE)
106     {
107         tbarheight = TitleTextHeight(pcd);
108     }
109     else
110     {
111         tbarheight = 0;
112     }
113
114     return (tbarheight);
115 }
116
117 \f
118 /*************************************<->*************************************
119  *
120  *  unsigned int UpperBorderWidth (pcd)
121  *
122  *
123  *  Description:
124  *  -----------
125  *  Returns the width of the upper frame border
126  *
127  *  Inputs:
128  *  ------
129  *  pcd                 - pointer to client data record
130  * 
131  *  Outputs:
132  *  -------
133  *  UpperBorderWidth    - width of the upper frame border
134  *
135  *  Comments:
136  *  --------
137  *  The upper border width is thinner if there is a title bar. The
138  *  title bar appears to sit across some of the inside beveling to
139  *  make the frame look more integrated.
140  * 
141  *************************************<->***********************************/
142 unsigned int UpperBorderWidth (ClientData *pcd)
143 {
144     unsigned int uswidth;
145     unsigned int decoration = pcd->decor;
146
147     if (decoration & MWM_DECOR_RESIZEH)
148     {
149         uswidth = RESIZE_BORDER_WIDTH(pcd);
150     }
151     else if (decoration & MWM_DECOR_BORDER)
152     {
153         uswidth = FRAME_BORDER_WIDTH(pcd);
154         if((pcd->clientFlags & FRONT_PANEL_BOX) &&
155            (uswidth > 0))
156         {
157             uswidth -= 1;
158         }
159     }
160     else if ((decoration & MWM_DECOR_TITLE) ||
161              (pcd->matteWidth > 0))
162     {
163         uswidth = 0;
164     }
165     else
166     {
167         uswidth = pcd->xBorderWidth;
168     }
169
170     return (uswidth);
171 }
172
173 \f
174 /*************************************<->*************************************
175  *
176  *  unsigned int LowerBorderWidth (pcd)
177  *
178  *
179  *  Description:
180  *  -----------
181  *  Returns the width of the lower frame border
182  *
183  *  Inputs:
184  *  ------
185  *  pcd                 - pointer to client data record
186  * 
187  *  Outputs:
188  *  -------
189  *  LowerBorderWidth    - width of the lower frame border
190  *
191  *  Comments:
192  *  --------
193  *  The upper border width is thinner than the lower border if there 
194  *  is a title bar. The title bar appears to sit across some of the 
195  *  inside beveling to make the frame look more integrated.
196  * 
197  *************************************<->***********************************/
198 unsigned int LowerBorderWidth (ClientData *pcd)
199 {
200     unsigned int lswidth;
201     unsigned int decoration = pcd->decor;
202
203     if (decoration & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER))
204     {
205         if ((pcd->matteWidth == 0) && (decoration & MWM_DECOR_TITLE) &&
206                 (wmGD.frameStyle == WmRECESSED))
207             lswidth = UpperBorderWidth (pcd) + 
208                       (pcd->internalBevel - JOIN_BEVEL(pcd));
209         else
210             lswidth = UpperBorderWidth (pcd);
211     }
212     else if (pcd->matteWidth > 0)
213     {
214         lswidth = 0;
215     }
216     else
217     {
218         lswidth = pcd->xBorderWidth;
219     }
220
221     return (lswidth);
222 }
223
224 \f
225 /*************************************<->*************************************
226  *
227  *  unsigned int FrameWidth (pcd)
228  *
229  *
230  *  Description:
231  *  -----------
232  *  Returns the width of the frame
233  *
234  *  Inputs:
235  *  ------
236  *  pcd                 - pointer to client data record
237  * 
238  *  Outputs:
239  *  -------
240  *  FrameWidth  - width of frame
241  *
242  *  Comments:
243  *  --------
244  * 
245  *************************************<->***********************************/
246 unsigned int FrameWidth (ClientData *pcd)
247 {
248     unsigned int frameWidth;
249
250     frameWidth = ((pcd->maxConfig) ? pcd->maxWidth : pcd->clientWidth) +
251                   2*pcd->matteWidth + 2*LowerBorderWidth (pcd);
252
253     return (frameWidth);
254 }
255
256 \f
257 /*************************************<->*************************************
258  *
259  *  unsigned int CornerWidth (pcd)
260  *
261  *
262  *  Description:
263  *  -----------
264  *  Returns the width of the corner frame resize handle
265  *
266  *  Inputs:
267  *  ------
268  *  pcd                 - pointer to client data record
269  * 
270  *  Outputs:
271  *  -------
272  *  CornerWidth - width of the corner resize handle
273  *
274  *  Comments:
275  *  --------
276  * 
277  *************************************<->***********************************/
278 unsigned int CornerWidth (ClientData *pcd)
279 {
280     unsigned int cwidth;
281     unsigned int frameWidth = FrameWidth (pcd);
282
283     /* adjust for resize border (default border if no resize wanted) */
284     if (pcd->decor & MWM_DECOR_RESIZEH)
285     {
286         /* corner size is driven by title bar height */
287         cwidth = TitleTextHeight(pcd) + UpperBorderWidth (pcd);
288
289         /* scale down corners to make resize pieces proportional */
290         if (3*cwidth > frameWidth) cwidth = frameWidth / 3;
291     }
292     else {
293         /* no resizing functions */
294         cwidth = 0;
295     }
296
297     return (cwidth);
298 }
299
300 \f
301 /*************************************<->*************************************
302  *
303  *  unsigned int FrameHeight (pcd)
304  *
305  *
306  *  Description:
307  *  -----------
308  *  Returns the height of the frame
309  *
310  *  Inputs:
311  *  ------
312  *  pcd                 - pointer to client data record
313  * 
314  *  Outputs:
315  *  -------
316  *  FrameHeight -  position of frame
317  *
318  *  Comments:
319  *  --------
320  * 
321  *************************************<->***********************************/
322 unsigned int FrameHeight (ClientData *pcd)
323 {
324     unsigned int frameHeight;
325
326     if (pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER))
327     {
328         frameHeight = ((pcd->maxConfig) ? 
329                           pcd->maxHeight : pcd->clientHeight) +
330                       2*pcd->matteWidth + LowerBorderWidth (pcd) + 
331                       UpperBorderWidth (pcd) + TitleBarHeight(pcd);
332     }
333     else 
334     {
335         frameHeight = ((pcd->maxConfig) ? 
336                           pcd->maxHeight : pcd->clientHeight) +
337                       2*pcd->matteWidth + 2*LowerBorderWidth (pcd) + 
338                       TitleBarHeight(pcd);
339     }
340
341     return (frameHeight);
342 }
343
344 \f
345 /*************************************<->*************************************
346  *
347  *  unsigned int CornerHeight (pcd)
348  *
349  *
350  *  Description:
351  *  -----------
352  *  Returns the height of the corner frame resize handle
353  *
354  *  Inputs:
355  *  ------
356  *  pcd                 - pointer to client data record
357  * 
358  *  Outputs:
359  *  -------
360  *  CornerHeight        - Height of the corner resize handle
361  *
362  *  Comments:
363  *  --------
364  * 
365  *************************************<->***********************************/
366 unsigned int CornerHeight (ClientData *pcd)
367 {
368     unsigned int cheight;
369     unsigned int frameHeight = FrameHeight (pcd);
370
371     /* adjust for resize border (default border if no resize wanted) */
372     if (pcd->decor & MWM_DECOR_RESIZEH)
373     {
374         /* corner size is driven by title bar height */
375         cheight = TitleTextHeight(pcd) + UpperBorderWidth (pcd);
376
377         /* scale down corners to make resize pieces proportional */
378         if (3*cheight > frameHeight) cheight = frameHeight / 3;
379     }
380     else {
381         /* produce default border with no resizing functions */
382         cheight = 0;
383     }
384
385     return (cheight);
386 }
387
388 \f
389 /*************************************<->*************************************
390  *
391  *  int BaseWindowX (pcd)
392  *
393  *
394  *  Description:
395  *  -----------
396  *  Returns the X coord of the base window in the frame
397  *
398  *  Inputs:
399  *  ------
400  *  pcd                 - pointer to client data record
401  * 
402  *  Outputs:
403  *  -------
404  *  BaseWindowX
405  *
406  *  Comments:
407  *  --------
408  * 
409  *************************************<->***********************************/
410 int BaseWindowX (ClientData *pcd)
411 {
412     int rval;
413
414     if (pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER))
415         rval = LowerBorderWidth(pcd);
416     else
417         rval = 0;
418     
419     return (rval);
420 }
421
422 \f
423 /*************************************<->*************************************
424  *
425  *  int BaseWindowY (pcd)
426  *
427  *
428  *  Description:
429  *  -----------
430  *  Returns the Y coord of the base window in the frame
431  *
432  *  Inputs:
433  *  ------
434  *  pcd                 - pointer to client data record
435  * 
436  *  Outputs:
437  *  -------
438  *  BaseWindowY
439  *
440  *  Comments:
441  *  --------
442  * 
443  *************************************<->***********************************/
444 int BaseWindowY (ClientData *pcd)
445 {
446     int rval;
447
448     if (pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER))
449         rval = UpperBorderWidth (pcd) + TitleBarHeight(pcd);
450     else
451         rval = TitleBarHeight(pcd);
452     
453     return (rval);
454 }
455
456
457 \f
458 /*************************************<->*************************************
459  *
460  *  int FrameX (pcd)
461  *
462  *
463  *  Description:
464  *  -----------
465  *  Returns the X-coordinate of the frame for the window
466  *
467  *  Inputs:
468  *  ------
469  *  pcd                 - pointer to client data record
470  * 
471  *  Outputs:
472  *  -------
473  *  FrameX              - X position of frame
474  *
475  *  Comments:
476  *  --------
477  * 
478  *************************************<->***********************************/
479 int FrameX (ClientData *pcd)
480 {
481     int frameX;
482
483     frameX = ((pcd->maxConfig) ? pcd->maxX : pcd->clientX)
484              - LowerBorderWidth (pcd)  - pcd->matteWidth;
485
486     return (frameX);
487 }
488
489 \f
490 /*************************************<->*************************************
491  *
492  *  int FrameY (pcd)
493  *
494  *
495  *  Description:
496  *  -----------
497  *  Returns the Y-coordinate of the frame for the window
498  *
499  *  Inputs:
500  *  ------
501  *  pcd                 - pointer to client data record
502  * 
503  *  Outputs:
504  *  -------
505  *  FrameY              - Y position of frame
506  *
507  *  Comments:
508  *  --------
509  * 
510  *************************************<->***********************************/
511 int FrameY (ClientData *pcd)
512 {
513     int frameY;
514
515     frameY = ((pcd->maxConfig) ? pcd->maxY : pcd->clientY) 
516          - UpperBorderWidth (pcd) 
517          - TitleBarHeight (pcd) - pcd->matteWidth;
518
519     if ((pcd->decor & MWM_DECOR_TITLE) && 
520         !(pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER)) &&
521         !(pcd->matteWidth))
522     {
523         frameY -= pcd->xBorderWidth;
524     }
525
526     return (frameY);
527 }
528
529 \f
530 /*************************************<->*************************************
531  *
532  *  unsigned int BaseWindowWidth (pcd)
533  *
534  *
535  *  Description:
536  *  -----------
537  *  Returns the width of the base window 
538  *
539  *  Inputs:
540  *  ------
541  *  pcd                 - pointer to client data record
542  * 
543  *  Outputs:
544  *  -------
545  *  BaseWindowWidth
546  *
547  *  Comments:
548  *  --------
549  *  o Based on code taken out of FrameWidth to make it a little 
550  *    more efficient.
551  * 
552  *************************************<->***********************************/
553 unsigned int BaseWindowWidth (ClientData *pcd)
554 {
555     unsigned int rval;
556
557     if (pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER))
558     {
559         /*
560          *  rval = FrameWidth(pcd) - 2*LowerBorderWidth(pcd);
561          */
562
563         rval = ((pcd->maxConfig) ? pcd->maxWidth : pcd->clientWidth) +
564                   2*pcd->matteWidth;
565     }
566     else
567     {
568         /*
569          *  rval = FrameWidth(pcd);
570          */
571         rval = ((pcd->maxConfig) ? pcd->maxWidth : pcd->clientWidth) +
572                   2*pcd->matteWidth + 2*LowerBorderWidth (pcd);
573     }
574     
575     return (rval);
576 }
577
578
579 \f
580 /*************************************<->*************************************
581  *
582  *  unsigned int BaseWindowHeight (pcd)
583  *
584  *
585  *  Description:
586  *  -----------
587  *  Returns the height of the base window 
588  *
589  *  Inputs:
590  *  ------
591  *  pcd                 - pointer to client data record
592  * 
593  *  Outputs:
594  *  -------
595  *  BaseWindowHeight
596  *
597  *  Comments:
598  *  --------
599  *  o Based on code taken out of FrameHeight to make it a little 
600  *    more efficient.
601  * 
602  *************************************<->***********************************/
603 unsigned int BaseWindowHeight (ClientData *pcd)
604 {
605     unsigned int rval;
606
607     if (pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER))
608     {
609
610         /* 
611          *  rval = FrameHeight(pcd) - LowerBorderWidth(pcd) - 
612          *             UpperBorderWidth(pcd) - TitleBarHeight(pcd);
613          */
614
615         rval = ((pcd->maxConfig) ? pcd->maxHeight : pcd->clientHeight) +
616                       2*pcd->matteWidth;
617     }
618     else
619     {
620         /* 
621          *  rval = FrameHeight(pcd) - TitleBarHeight(pcd); 
622          */
623
624         rval = ((pcd->maxConfig) ? pcd->maxHeight : pcd->clientHeight) +
625                       2*pcd->matteWidth + 2*LowerBorderWidth (pcd);
626     }
627     
628     return (rval);
629 }
630
631
632 \f
633 /*************************************<->*************************************
634  *
635  *  Boolean GetFramePartInfo (pcd, part, pX, pY, pWidth, pHeight)
636  *
637  *
638  *  Description:
639  *  -----------
640  *  Gets frame relative position and size of the specified frame part
641  *
642  *
643  *  Inputs:
644  *  ------
645  *  pcd         - pointer to client data
646  *  part        - part id (e.g. FRAME_TITLE, FRAME_SYSTEM, etc.)
647  *  pX          - pointer to x-coord return value
648  *  pY          - pointer to y-coord return value
649  *  pWidth      - pointer to width return value
650  *  pHeight     - pointer to width return value
651  *
652  * 
653  *  Outputs:
654  *  -------
655  *  Return      - True if values returned, false if no such part for this
656  *                frame (values undefined).
657  *
658  *
659  *  Comments:
660  *  --------
661  * 
662  *************************************<->***********************************/
663 Boolean GetFramePartInfo (ClientData *pcd, int part, int *pX, int *pY, unsigned int *pWidth, unsigned int *pHeight)
664 {
665     unsigned int boxdim = TitleBarHeight (pcd);
666     unsigned long decor = pcd->decor;
667     int vert, horiz;
668     Boolean rval = FALSE;
669     
670     switch (part) 
671     {
672         case FRAME_SYSTEM:
673                 if (decor & MWM_DECOR_MENU) {
674                     *pX = pcd->frameInfo.upperBorderWidth;
675                     *pY = pcd->frameInfo.upperBorderWidth;
676                     *pWidth = boxdim;
677                     *pHeight = boxdim;
678                     rval = TRUE;
679                 }
680                 break;
681
682         case FRAME_TITLE:
683                 if (decor & MWM_DECOR_TITLE) {
684                     *pX = pcd->frameInfo.upperBorderWidth + 
685                             ((decor & MWM_DECOR_MENU) ? boxdim : 0);
686                     *pY = pcd->frameInfo.upperBorderWidth;
687                     *pWidth = pcd->frameInfo.width - 
688                             2*pcd->frameInfo.upperBorderWidth - 
689                             ((decor & MWM_DECOR_MENU) ? boxdim : 0) -
690                             ((decor & MWM_DECOR_MINIMIZE) ? boxdim : 0) -
691                             ((decor & MWM_DECOR_MAXIMIZE) ? boxdim : 0);
692                     *pHeight = boxdim;
693                     rval = TRUE;
694                 }
695                 break;
696
697         case FRAME_TITLEBAR:
698                 if (decor & MWM_DECOR_TITLE) {
699                     *pX = pcd->frameInfo.upperBorderWidth;
700                     *pY = pcd->frameInfo.upperBorderWidth;
701                     *pWidth = pcd->frameInfo.width - 
702                             2*pcd->frameInfo.upperBorderWidth;
703                     *pHeight = boxdim;
704                     rval = TRUE;
705                 }
706                 break;
707
708         case FRAME_MINIMIZE:
709                 if (decor & MWM_DECOR_MINIMIZE) {
710                     *pX = pcd->frameInfo.width - 
711                             pcd->frameInfo.upperBorderWidth - boxdim -
712                             ((decor & MWM_DECOR_MAXIMIZE) ? boxdim : 0);
713                     *pY = pcd->frameInfo.upperBorderWidth;
714                     *pWidth= boxdim;
715                     *pHeight = boxdim;
716                     rval = TRUE;
717                 }
718                 break;
719
720         case FRAME_MAXIMIZE:
721                 if (decor & MWM_DECOR_MAXIMIZE) {
722                     *pX = pcd->frameInfo.width - 
723                             pcd->frameInfo.upperBorderWidth - boxdim;
724                     *pY = pcd->frameInfo.upperBorderWidth;
725                     *pWidth = boxdim;
726                     *pHeight = boxdim;
727                     rval = TRUE;
728                 }
729                 break;
730
731         /*
732          * For very small windows, the resize pieces will shrink
733          * equally until the corner pieces get within two pixels
734          * of the resize border width. At this point the "side" section
735          * is killed off (by giving it a zero length) and the corner
736          * pieces claim the additional space
737          */
738         case FRAME_RESIZE_NW:
739                 if (decor & MWM_DECOR_RESIZEH) {
740                     *pX = 0;
741                     *pY = 0;
742
743                     if ((int)pcd->frameInfo.cornerWidth > 
744                             (int)pcd->frameInfo.lowerBorderWidth+2) {
745                         *pWidth = pcd->frameInfo.cornerWidth;
746                     }
747                     else {
748                         horiz = pcd->frameInfo.width - 
749                                 2*pcd->frameInfo.cornerWidth;
750                         *pWidth = pcd->frameInfo.cornerWidth + 
751                                 horiz/2 + horiz%2;
752                     }
753
754                     if ((int)pcd->frameInfo.cornerHeight > 
755                             (int)pcd->frameInfo.lowerBorderWidth+2) {
756                         *pHeight = pcd->frameInfo.cornerHeight;
757                     }
758                     else {
759                         vert = pcd->frameInfo.height - 
760                                 2*pcd->frameInfo.cornerHeight;
761                         *pHeight = pcd->frameInfo.cornerHeight + 
762                                 vert/2 + vert%2;
763                     }
764                     rval = TRUE;
765                 }
766                 break;
767             
768         case FRAME_RESIZE_N:
769                 if (decor & MWM_DECOR_RESIZEH) {
770                     *pX = pcd->frameInfo.cornerWidth;
771                     *pY = 0;
772                     *pHeight = pcd->frameInfo.upperBorderWidth;
773                     if ((int)pcd->frameInfo.cornerWidth > 
774                             (int)pcd->frameInfo.lowerBorderWidth+2) {
775                         *pWidth = pcd->frameInfo.width - 
776                                 2*pcd->frameInfo.cornerWidth;
777                     }
778                     else {
779                         *pWidth = 0;
780                     }
781                     rval = TRUE;
782                 }
783                 break;
784             
785         case FRAME_RESIZE_NE:
786                 if (decor & MWM_DECOR_RESIZEH) {
787                     if ((int)pcd->frameInfo.cornerWidth > 
788                             (int)pcd->frameInfo.lowerBorderWidth+2) {
789                         *pWidth = pcd->frameInfo.cornerWidth;
790                     }
791                     else {
792                         horiz = pcd->frameInfo.width - 
793                             2*pcd->frameInfo.cornerWidth;
794                         *pWidth = pcd->frameInfo.cornerWidth + horiz/2;
795                     }
796                     *pX = pcd->frameInfo.width - *pWidth;
797
798                     if ((int)pcd->frameInfo.cornerHeight > 
799                            (int)pcd->frameInfo.lowerBorderWidth+2) {
800                         *pHeight = pcd->frameInfo.cornerHeight;
801                     }
802                     else {
803                         vert = pcd->frameInfo.height - 
804                                 2*pcd->frameInfo.cornerHeight;
805                         *pHeight = pcd->frameInfo.cornerHeight + 
806                                 vert/2 + vert%2;
807                     }
808                     *pY = 0;
809                     rval = TRUE;
810                 }
811                 break;
812             
813         case FRAME_RESIZE_E:
814                 if (decor & MWM_DECOR_RESIZEH) {
815                     *pX = pcd->frameInfo.width - 
816                             pcd->frameInfo.lowerBorderWidth;
817                     *pY = pcd->frameInfo.cornerHeight;
818                     *pWidth = pcd->frameInfo.lowerBorderWidth;
819                     if ((int)pcd->frameInfo.cornerHeight > 
820                             (int)pcd->frameInfo.lowerBorderWidth+2) {
821                         *pHeight = pcd->frameInfo.height - 
822                                 2*pcd->frameInfo.cornerHeight;
823                     }
824                     else {
825                         *pHeight = 0;
826                     }
827                     rval = TRUE;
828                 }
829                 break;
830             
831         case FRAME_RESIZE_SE:
832                 if (decor & MWM_DECOR_RESIZEH) {
833                     if ((int)pcd->frameInfo.cornerWidth > 
834                             (int)pcd->frameInfo.lowerBorderWidth+2) {
835                         *pWidth = pcd->frameInfo.cornerWidth;
836                     }
837                     else {
838                         horiz = pcd->frameInfo.width - 
839                                 2*pcd->frameInfo.cornerWidth;
840                         *pWidth = pcd->frameInfo.cornerWidth + horiz/2;
841                     }
842                     *pX = pcd->frameInfo.width - *pWidth;
843
844                     if ((int)pcd->frameInfo.cornerHeight > 
845                             (int)pcd->frameInfo.lowerBorderWidth+2) {
846                         *pHeight = pcd->frameInfo.cornerHeight;
847                     }
848                     else {
849                         vert = pcd->frameInfo.height - 
850                                 2*pcd->frameInfo.cornerHeight;
851                         *pHeight = pcd->frameInfo.cornerHeight + vert/2;
852                     }
853                     *pY = pcd->frameInfo.height - *pHeight;
854                     rval = TRUE;
855                 }
856                 break;
857             
858         case FRAME_RESIZE_S:
859                 if (decor & MWM_DECOR_RESIZEH) {
860                     *pX = pcd->frameInfo.cornerWidth;
861                     *pY = pcd->frameInfo.height - 
862                             pcd->frameInfo.lowerBorderWidth;
863                     if ((int)pcd->frameInfo.cornerWidth > 
864                             (int)pcd->frameInfo.lowerBorderWidth+2) {
865                         *pWidth = pcd->frameInfo.width - 
866                                 2*pcd->frameInfo.cornerWidth;
867                     }
868                     else {
869                         *pWidth = 0;
870                     }
871                     *pHeight = pcd->frameInfo.lowerBorderWidth;
872                     rval = TRUE;
873                 }
874                 break;
875             
876         case FRAME_RESIZE_SW:
877                 if (decor & MWM_DECOR_RESIZEH) {
878                     if ((int)pcd->frameInfo.cornerWidth > 
879                             (int)pcd->frameInfo.lowerBorderWidth+2) {
880                         *pWidth = pcd->frameInfo.cornerWidth;
881                     }
882                     else {
883                         horiz = pcd->frameInfo.width - 
884                                 2*pcd->frameInfo.cornerWidth;
885                         *pWidth = pcd->frameInfo.cornerWidth + 
886                                 horiz/2 + horiz%2;
887                     }
888                     *pX = 0;
889
890                     if ((int)pcd->frameInfo.cornerHeight > 
891                             (int)pcd->frameInfo.lowerBorderWidth+2) {
892                         *pHeight = pcd->frameInfo.cornerHeight;
893                     }
894                     else {
895                         vert = pcd->frameInfo.height - 
896                                 2*pcd->frameInfo.cornerHeight;
897                         *pHeight = pcd->frameInfo.cornerHeight + vert/2;
898                     }
899                     *pY = pcd->frameInfo.height - *pHeight;
900                     rval = TRUE;
901                 }
902                 break;
903             
904         case FRAME_RESIZE_W:
905                 if (decor & MWM_DECOR_RESIZEH) {
906                     *pX = 0;
907                     *pY = pcd->frameInfo.cornerHeight;
908                     *pWidth = pcd->frameInfo.lowerBorderWidth;
909                     if ((int)pcd->frameInfo.cornerHeight > 
910                             (int)pcd->frameInfo.lowerBorderWidth+2) {
911                         *pHeight = pcd->frameInfo.height - 
912                                 2*pcd->frameInfo.cornerHeight;
913                     }
914                     else {
915                         *pHeight = 0;
916                     }
917                     rval = TRUE;
918                 }
919                 break;
920             
921         default:
922                 break;
923     }
924     return(rval);
925 }
926
927
928 \f
929 /*************************************<->*************************************
930  *
931  *  IdentifyFramePart (pCD, x, y)
932  *
933  *
934  *  Description:
935  *  -----------
936  *  Returns an ID representing which part of the frame received the event
937  *
938  *
939  *  Inputs:
940  *  ------
941  *  pCD         - pointer to client data
942  *
943  *  x, y        - client coordinates of event
944  *
945  * 
946  *  Outputs:
947  *  -------
948  *  Return      - ID of frame part where the button event occurred.
949  *
950  *
951  *  Comments:
952  *  --------
953  *************************************<->***********************************/
954
955 int IdentifyFramePart (ClientData *pCD, int x, int y)
956 {
957     unsigned long decor = pCD->decor;
958     int clientWidth = (pCD->maxConfig) ? pCD->maxWidth : pCD->clientWidth;
959     int clientHeight= (pCD->maxConfig) ? pCD->maxHeight : pCD->clientHeight;
960     int rval;
961
962
963     /* check for client window */
964
965     if ( (x >= pCD->clientOffset.x) &&
966          (x <  pCD->clientOffset.x + clientWidth) &&
967          (y >= pCD->clientOffset.y) &&
968          (y <  pCD->clientOffset.y + clientHeight) )
969     {
970         return (FRAME_CLIENT);
971     }
972
973
974     /* check for client matte */
975
976     if (pCD->matteWidth)
977     {
978         if ( (x >= pCD->matteRectangle.x) &&
979              (x <  (int)pCD->matteRectangle.x + (int)pCD->matteRectangle.width) &&
980              (y >= pCD->matteRectangle.y) &&
981              (y <  (int)pCD->matteRectangle.y + (int)pCD->matteRectangle.height) )
982         {
983             return (FRAME_MATTE);
984         }
985     }
986
987
988     /* check title bar */
989
990     if (decor & MWM_DECOR_TITLE)
991     {
992         if ( (x >= pCD->titleRectangle.x) &&
993              (x <  (int)pCD->titleRectangle.x + (int)pCD->titleRectangle.width) &&
994              (y >= pCD->titleRectangle.y) &&
995              (y <  (int)pCD->titleRectangle.y + (int)pCD->titleRectangle.height) )
996         {
997             return(GadgetID(x, y, pCD->pTitleGadgets, 
998                             (unsigned int)pCD->cTitleGadgets));
999         }
1000     }
1001
1002
1003     /* try resize border */
1004
1005     if (decor & MWM_DECOR_RESIZEH)
1006     {
1007         rval = GadgetID(x, y, pCD->pResizeGadgets, STRETCH_COUNT);
1008     }
1009     else
1010     {
1011         rval = FRAME_NONE;
1012     }
1013
1014
1015     /* if not a resize border, but still in bounds return FRAME_NBORDER */
1016
1017     if (rval == FRAME_NONE)
1018     {
1019         if ((x >= 0) && (y >= 0) &&
1020             (x < FrameWidth (pCD)) && (y < FrameHeight (pCD))) 
1021         {
1022             rval = FRAME_NBORDER;
1023         }
1024     }
1025
1026     return (rval);
1027
1028 } /* END OF FUNCTION IdentifyFramePart */
1029
1030
1031
1032 \f
1033 /*************************************<->*************************************
1034  *
1035  *  GadgetID (x, y, pgadget, count)
1036  *
1037  *
1038  *  Description:
1039  *  -----------
1040  *  returns the id of the gadget in the list that the event occurred in
1041  *
1042  *
1043  *  Inputs:
1044  *  ------
1045  *  x           - x coordinate of event
1046  *  y           - y coordinate of event
1047  *  pgadget     - pointer to a list of GadgetRectangles
1048  *  count       - number of elements in the pgadget list
1049  * 
1050  *  Outputs:
1051  *  -------
1052  *  Return      - ID of gadget if found, FRAME_NONE if not found
1053  *
1054  *
1055  *  Comments:
1056  *  --------
1057  *  
1058  * 
1059  *************************************<->***********************************/
1060 int GadgetID (int x, int y, GadgetRectangle *pgadget, unsigned int count)
1061 {
1062     int ix;
1063
1064     for (ix = 0; ix < count; ix++, pgadget++) {
1065         if ( (x >= pgadget->rect.x) &&
1066              (x <  (int)pgadget->rect.x + (int)pgadget->rect.width) &&
1067              (y >= pgadget->rect.y) &&
1068              (y <  (int)pgadget->rect.y + (int)pgadget->rect.height) ) {
1069             return ((unsigned long) pgadget->id);
1070         }
1071     }
1072     return(FRAME_NONE);
1073 }
1074
1075
1076
1077 \f
1078 /*************************************<->*************************************
1079  *
1080  *  FrameToClient (pcd, pX, pY, pWidth, pHeight)
1081  *
1082  *
1083  *  Description:
1084  *  -----------
1085  *  Converts frame position and size to client position and size
1086  *
1087  *
1088  *  Inputs:
1089  *  ------
1090  *  pcd         - pointer to client data
1091  *  pX          - pointer to frame x-coord
1092  *  pY          - pointer to frame y-coord
1093  *  pWidth      - pointer to frame width in pixels
1094  *  pHeight     - pointer to frame height in pixels
1095  * 
1096  *  Outputs:
1097  *  -------
1098  *  *pX         - client x-coord
1099  *  *pY         - client y-coord
1100  *  *pWidth     - client width in pixels
1101  *  *pHeight    - client height in pixels
1102  *
1103  *
1104  *  Comments:
1105  *  --------
1106  * 
1107  *************************************<->***********************************/
1108 void FrameToClient (ClientData *pcd, int *pX, int *pY, unsigned int *pWidth, unsigned int *pHeight)
1109 {
1110     /* compute client window coordinates from frame coordinates */
1111
1112     *pWidth = *pWidth - 2*pcd->clientOffset.x; 
1113     *pHeight = *pHeight - pcd->clientOffset.x - pcd->clientOffset.y; 
1114     *pX =  *pX + pcd->clientOffset.x;
1115     *pY =  *pY + pcd->clientOffset.y;
1116 }
1117
1118 \f
1119 /*************************************<->*************************************
1120  *
1121  *  ClientToFrame (pcd, pX, pY, pWidth, pHeight)
1122  *
1123  *
1124  *  Description:
1125  *  -----------
1126  *  Converts frame position and size to client position and size
1127  *
1128  *
1129  *  Inputs:
1130  *  ------
1131  *  pcd         - pointer to client data
1132  *  pX          - client x-coord
1133  *  pY          - client y-coord
1134  *  pWidth      - client width in pixels
1135  *  pHeight     - client height in pixels
1136  * 
1137  *  Outputs:
1138  *  -------
1139  *  *pX         - frame x-coord
1140  *  *pY         - frame y-coord
1141  *  *pWidth     - frame width in pixels
1142  *  *pHeight    - frame height in pixels
1143  *
1144  *
1145  *  Comments:
1146  *  --------
1147  * 
1148  *************************************<->***********************************/
1149 void ClientToFrame (ClientData *pcd, int *pX, int *pY, unsigned int *pWidth, unsigned int *pHeight)
1150 {
1151     /* compute client window coordinates from frame coordinates */
1152     *pWidth = *pWidth + 2*pcd->clientOffset.x;
1153     *pHeight = *pHeight + pcd->clientOffset.x + pcd->clientOffset.y;
1154     *pX = *pX - pcd->clientOffset.x;
1155     *pY = *pY - pcd->clientOffset.y;
1156 }
1157
1158
1159 \f
1160 /*************************************<->*************************************
1161  *
1162  *  Boolean GetDepressInfo (pcd, part, pX, pY, pWidth, pHeight)
1163  *
1164  *
1165  *  Description:
1166  *  -----------
1167  *  Gets frame relative position, size, and width of the beveling 
1168  *  to show the gadget in its depressed state.
1169  *
1170  *
1171  *  Inputs:
1172  *  ------
1173  *  pcd         - pointer to client data
1174  *  part        - part id (e.g. FRAME_TITLE, FRAME_SYSTEM, etc.)
1175  *  pX          - pointer to x-coord return value
1176  *  pY          - pointer to y-coord return value
1177  *  pWidth      - pointer to width return value
1178  *  pHeight     - pointer to width return value
1179  *  pInverWidth - pointer to inversion width return value
1180  *
1181  * 
1182  *  Outputs:
1183  *  -------
1184  *  Return      - True if values returned, false if no such part for this
1185  *                frame (values undefined).
1186  *
1187  *
1188  *  Comments:
1189  *  --------
1190  *  o The "part" must be a title bar gadget.
1191  * 
1192  *************************************<->***********************************/
1193 Boolean GetDepressInfo (ClientData *pcd, int part, int *pX, int *pY, unsigned int *pWidth, unsigned int *pHeight, unsigned int *pInvertWidth)
1194 {
1195     Boolean rval;
1196     unsigned int exBevel, eBevel;
1197     unsigned int wBevel, sBevel;
1198     unsigned int insideBevel, meBevel;
1199     unsigned int decoration = pcd->decor;
1200     unsigned int tmp;
1201
1202     switch (part)
1203     {
1204         case FRAME_SYSTEM:
1205         case FRAME_TITLE:
1206         case FRAME_MINIMIZE:
1207         case FRAME_MAXIMIZE:
1208             if ((rval = GetFramePartInfo (pcd, part, pX, pY, pWidth, pHeight)))
1209             {
1210                 /*
1211                  * set bevel width based on join bevel
1212                  */
1213                 *pInvertWidth = 1 + (JOIN_BEVEL(pcd) / 2);
1214                 
1215                 /* bevel between title and client (or matte) */
1216                 insideBevel = (pcd->matteWidth > 0) ?  JOIN_BEVEL(pcd) : 
1217                                                    pcd->internalBevel;
1218
1219
1220                 /*
1221                  * Compute beveling around the title area of the
1222                  * title bar.
1223                  */
1224                 if (decoration & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER))
1225                 {
1226                     exBevel = JOIN_BEVEL(pcd);  /* north side */
1227                     sBevel = insideBevel;               /* south side */
1228                     eBevel = JOIN_BEVEL(pcd);   /* east side */
1229                     wBevel = JOIN_BEVEL(pcd);   /* west side */
1230                     meBevel = JOIN_BEVEL(pcd);  /* east of Min */
1231                 }
1232                 else 
1233                 {
1234                     /* borderless window */
1235
1236                     exBevel = EXTERNAL_BEVEL(pcd);
1237
1238                     sBevel = (pcd->matteWidth > 0) ? insideBevel : 
1239                                                       EXTERNAL_BEVEL(pcd);
1240
1241                     eBevel = (decoration & (MWM_DECOR_MINIMIZE | 
1242                                                  MWM_DECOR_MAXIMIZE))?
1243                                       JOIN_BEVEL(pcd) : EXTERNAL_BEVEL(pcd);
1244
1245                     wBevel = (decoration & MWM_DECOR_MENU) ?
1246                                       JOIN_BEVEL(pcd) : EXTERNAL_BEVEL(pcd);
1247
1248                     meBevel = (decoration & (MWM_DECOR_MAXIMIZE)) ?
1249                                       JOIN_BEVEL(pcd) : EXTERNAL_BEVEL(pcd);
1250                 }
1251
1252                 /*
1253                  * Adjust height of all title bar gadgets if necessary.
1254                  * (The bottom bevel is the same for all the pieces.)
1255                  */
1256
1257                 if (sBevel > *pInvertWidth)
1258                 {
1259                     *pHeight -= (sBevel - *pInvertWidth);
1260                 }
1261
1262                 /*
1263                  * Adjust the beveling on the other sides of the 
1264                  * gadgets.
1265                  */
1266                 switch (part)
1267                 {
1268                     case FRAME_SYSTEM:
1269                         /* west and north sides */
1270                         if (exBevel > *pInvertWidth) 
1271                         {
1272                             tmp = exBevel - *pInvertWidth;
1273                             *pX += tmp;
1274                             *pWidth -= tmp;
1275                             *pY += tmp;
1276                             *pHeight -= tmp;
1277                         }
1278
1279                         /* east side */
1280                         if (wBevel > *pInvertWidth) 
1281                         {
1282                             *pWidth -= (wBevel - *pInvertWidth);
1283                         }
1284                         break;
1285
1286                     case FRAME_TITLE:
1287                         /* west side */
1288                         if (wBevel > *pInvertWidth) 
1289                         {
1290                             tmp = wBevel - *pInvertWidth;
1291                             *pX += tmp;
1292                             *pWidth -= tmp;
1293                         }
1294
1295                         /* north side */
1296                         if (exBevel > *pInvertWidth) 
1297                         {
1298                             tmp = exBevel - *pInvertWidth;
1299                             *pY += tmp;
1300                             *pHeight -= tmp;
1301                         }
1302
1303                         /* east side */
1304                         if (eBevel > *pInvertWidth) 
1305                         {
1306                             *pWidth -= eBevel - *pInvertWidth;
1307                         }
1308                         break;
1309
1310                     case FRAME_MINIMIZE:
1311                         /* north side */
1312                         if (exBevel > *pInvertWidth) 
1313                         {
1314                             tmp = exBevel - *pInvertWidth;
1315                             *pY += tmp;
1316                             *pHeight -= tmp;
1317                         }
1318
1319                         /* west side */
1320                         if (eBevel > *pInvertWidth) 
1321                         {
1322                             tmp = eBevel - *pInvertWidth;
1323                             *pX += tmp;
1324                             *pWidth -= tmp;
1325                         }
1326
1327                         /* east side */
1328                         if (meBevel > *pInvertWidth) 
1329                         {
1330                             *pWidth -= meBevel - *pInvertWidth;
1331                         }
1332                         break;
1333
1334                     case FRAME_MAXIMIZE:
1335                         /* north and east sides */
1336                         if (exBevel > *pInvertWidth) 
1337                         {
1338                             tmp = exBevel - *pInvertWidth;
1339                             *pY += tmp;
1340                             *pHeight -= tmp;
1341                             *pWidth -= tmp;
1342                         }
1343
1344                         /* west side */
1345                         if (eBevel > *pInvertWidth) 
1346                         {
1347                             tmp = eBevel - *pInvertWidth;
1348                             *pX += tmp;
1349                             *pWidth -= tmp;
1350                         }
1351                         break;
1352                 } /* end switch */
1353             } /* end case "title bar part" */   
1354             break;
1355
1356         default:
1357             rval = False;
1358             break;
1359
1360     }   /* end switch */
1361
1362     return (rval);
1363 }
1364
1365
1366
1367 \f
1368 /*************************************<->*************************************
1369  *
1370  *  SetFrameInfo (pcd)
1371  *
1372  *
1373  *  Description:
1374  *  -----------
1375  *  Sets frame information into client data structure for easy access.
1376  *
1377  *
1378  *  Inputs:
1379  *  ------
1380  *  pcd         - pointer to client data
1381  * 
1382  *  Outputs:
1383  *  -------
1384  *
1385  *  Comments:
1386  *  --------
1387  *  o Sets values into the FrameInfo component of the client data structure
1388  * 
1389  *************************************<->***********************************/
1390 void SetFrameInfo (ClientData *pcd)
1391 {
1392
1393     /*
1394      * The title bar height value stored in pcd->frameInfo is used by the
1395      * macro TitleBarHeight(pcd).
1396      */
1397
1398     pcd->frameInfo.titleBarHeight = InitTitleBarHeight (pcd);
1399
1400     pcd->frameInfo.x = FrameX (pcd);
1401     pcd->frameInfo.y = FrameY (pcd);
1402     pcd->frameInfo.width = FrameWidth (pcd);
1403     pcd->frameInfo.height = FrameHeight (pcd);
1404     pcd->frameInfo.upperBorderWidth = UpperBorderWidth (pcd);
1405     pcd->frameInfo.lowerBorderWidth = LowerBorderWidth (pcd);
1406     pcd->frameInfo.cornerWidth = CornerWidth (pcd);
1407     pcd->frameInfo.cornerHeight = CornerHeight (pcd);
1408
1409     /* set client offset */
1410      
1411     if ( (pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER)) ||
1412          (pcd->matteWidth > 0) )
1413     {
1414         /*
1415          *  The window has a window manager border.
1416          */
1417         pcd->clientOffset.x = pcd->frameInfo.lowerBorderWidth + 
1418                                   pcd->matteWidth;
1419         pcd->clientOffset.y = pcd->frameInfo.upperBorderWidth + 
1420                                   pcd->frameInfo.titleBarHeight + 
1421                                   pcd->matteWidth;
1422     }
1423     else 
1424     {
1425         /*
1426          * No window manager border, the original X border is showing
1427          * through.
1428          */
1429         pcd->clientOffset.x =  pcd->xBorderWidth + pcd->matteWidth;
1430         pcd->clientOffset.y =  pcd->xBorderWidth + 
1431                                    pcd->frameInfo.titleBarHeight + 
1432                                    pcd->matteWidth;
1433     }
1434
1435 }
1436
1437
1438 \f
1439 /*************************************<->*************************************
1440  *
1441  *  SetClientOffset (pcd)
1442  *
1443  *
1444  *  Description:
1445  *  -----------
1446  *  Sets the client offset into client data structure
1447  *
1448  *
1449  *  Inputs:
1450  *  ------
1451  *  pcd         - pointer to client data
1452  * 
1453  *  Outputs:
1454  *  -------
1455  *
1456  *  Comments:
1457  *  --------
1458  *  This can be called before SetFrameInfo to set up the client offset
1459  *  without the danger of using uninitialized variables during 
1460  *  extraneous computation.
1461  *
1462  *************************************<->***********************************/
1463 void SetClientOffset (ClientData *pcd)
1464 {
1465     /*
1466      * The title bar height value stored in pcd->frameInfo is used by the
1467      * macro TitleBarHeight(pcd).
1468      */
1469
1470     pcd->frameInfo.titleBarHeight = InitTitleBarHeight (pcd);
1471
1472     pcd->frameInfo.upperBorderWidth = UpperBorderWidth (pcd);
1473     pcd->frameInfo.lowerBorderWidth = LowerBorderWidth (pcd);
1474
1475     /* set client offset */
1476      
1477     if ( (pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER)) ||
1478          (pcd->matteWidth > 0) )
1479     {
1480         /*
1481          *  The window has a window manager border.
1482          */
1483         pcd->clientOffset.x = pcd->frameInfo.lowerBorderWidth + 
1484                                   pcd->matteWidth;
1485         pcd->clientOffset.y = pcd->frameInfo.upperBorderWidth + 
1486                                   pcd->frameInfo.titleBarHeight + 
1487                                   pcd->matteWidth;
1488     }
1489     else 
1490     {
1491         /*
1492          * No window manager border, the original X border is showing
1493          * through.
1494          */
1495         pcd->clientOffset.x =  pcd->xBorderWidth + pcd->matteWidth;
1496         pcd->clientOffset.y =  pcd->xBorderWidth + 
1497                                    pcd->frameInfo.titleBarHeight + 
1498                                    pcd->matteWidth;
1499     }
1500 }
1501
1502
1503 \f
1504 /*************************************<->*************************************
1505  *
1506  *  XBorderIsShowing (pcd)
1507  *
1508  *
1509  *  Description:
1510  *  -----------
1511  *  Returns true if the X border is showing.
1512  *
1513  *
1514  *  Inputs:
1515  *  ------
1516  *  pcd         - pointer to client data
1517  * 
1518  *  Outputs:
1519  *  -------
1520  *  XBorderIsShowing    - True if no window manager border & x border is 
1521  *                        visible, False otherwise
1522  *
1523  *  Comments:
1524  *  --------
1525  *
1526  *************************************<->***********************************/
1527 Boolean XBorderIsShowing (ClientData *pcd)
1528 {
1529     Boolean rval;
1530
1531     if ( (pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER)) ||
1532          (pcd->matteWidth > 0) )
1533     {
1534         rval = False;   /* hidden by window manager */
1535     }
1536     else 
1537     {
1538         rval = True;    /* it's showing */
1539     }
1540     return(rval);
1541 }