source: trunk/athena/etc/xdm/xlogin/SmeBSB.c @ 6043

Revision 6043, 18.7 KB checked in by mar, 33 years ago (diff)
Initial revision
Line 
1/* $XConsortium: SmeBSB.c,v 1.16 91/03/15 15:59:41 gildea Exp $ */
2
3/*
4 * Copyright 1989 Massachusetts Institute of Technology
5 *
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of M.I.T. not be used in advertising or
11 * publicity pertaining to distribution of the software without specific,
12 * written prior permission.  M.I.T. makes no representations about the
13 * suitability of this software for any purpose.  It is provided "as is"
14 * without express or implied warranty.
15 *
16 * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
18 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 */
23
24/*
25 * SmeBSB.c - Source code file for BSB Menu Entry object.
26 *
27 * Date:    September 26, 1989
28 *
29 * By:      Chris D. Peterson
30 *          MIT X Consortium
31 *          kit@expo.lcs.mit.edu
32 */
33
34#include <X11/IntrinsicP.h>
35#include <X11/StringDefs.h>
36#include <X11/Xos.h>
37
38#include <X11/Xmu/Drawing.h>
39
40#include <X11/Xaw/XawInit.h>
41#include <X11/Xaw/SimpleMenu.h>
42#include "SmeBSBP.h"
43#include <X11/Xaw/Cardinals.h>
44
45#include <stdio.h>
46
47#define ONE_HUNDRED 100
48
49#define offset(field) XtOffsetOf(SmeBSBRec, sme_bsb.field)
50
51static XtResource resources[] = {
52  {XtNlabel,  XtCLabel, XtRString, sizeof(String),
53     offset(label), XtRString, NULL},
54  {XtNvertSpace,  XtCVertSpace, XtRInt, sizeof(int),
55     offset(vert_space), XtRImmediate, (XtPointer) 25},
56  {XtNleftBitmap, XtCLeftBitmap, XtRBitmap, sizeof(Pixmap),
57     offset(left_bitmap), XtRImmediate, (XtPointer)None},
58  {XtNjustify, XtCJustify, XtRJustify, sizeof(XtJustify),
59     offset(justify), XtRImmediate, (XtPointer) XtJustifyLeft},
60  {XtNrightBitmap, XtCRightBitmap, XtRBitmap, sizeof(Pixmap),
61     offset(right_bitmap), XtRImmediate, (XtPointer)None},
62  {XtNleftMargin,  XtCHorizontalMargins, XtRDimension, sizeof(Dimension),
63     offset(left_margin), XtRImmediate, (XtPointer) 4},
64  {XtNrightMargin,  XtCHorizontalMargins, XtRDimension, sizeof(Dimension),
65     offset(right_margin), XtRImmediate, (XtPointer) 4},
66  {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
67     offset(foreground), XtRString, XtDefaultForeground},
68  {XtNfont,  XtCFont, XtRFontStruct, sizeof(XFontStruct *),
69     offset(font), XtRString, XtDefaultFont},
70  {XtNflipColors,  XtCFlipColors, XtRBoolean, sizeof(Boolean),
71     offset(flip_colors), XtRImmediate, (XtPointer)True},
72};
73#undef offset
74
75/*
76 * Semi Public function definitions.
77 */
78
79static void Redisplay(), Destroy(), Initialize(), FlipColors();
80static void ClassInitialize();
81static Boolean SetValues();
82static XtGeometryResult QueryGeometry();
83
84/*
85 * Private Function Definitions.
86 */
87
88static void GetDefaultSize(), DrawBitmaps(), GetBitmapInfo();
89static void CreateGCs(), DestroyGCs();
90   
91#define superclass (&smeClassRec)
92SmeBSBClassRec smeBSBClassRec = {
93  {
94    /* superclass         */    (WidgetClass) superclass,
95    /* class_name         */    "SmeBSB",
96    /* size               */    sizeof(SmeBSBRec),
97    /* class_initializer  */    ClassInitialize,
98    /* class_part_initialize*/  NULL,
99    /* Class init'ed      */    FALSE,
100    /* initialize         */    Initialize,
101    /* initialize_hook    */    NULL,
102    /* realize            */    NULL,
103    /* actions            */    NULL,
104    /* num_actions        */    ZERO,
105    /* resources          */    resources,
106    /* resource_count     */    XtNumber(resources),
107    /* xrm_class          */    NULLQUARK,
108    /* compress_motion    */    FALSE,
109    /* compress_exposure  */    FALSE,
110    /* compress_enterleave*/    FALSE,
111    /* visible_interest   */    FALSE,
112    /* destroy            */    Destroy,
113    /* resize             */    NULL,
114    /* expose             */    Redisplay,
115    /* set_values         */    SetValues,
116    /* set_values_hook    */    NULL,
117    /* set_values_almost  */    XtInheritSetValuesAlmost, 
118    /* get_values_hook    */    NULL,                   
119    /* accept_focus       */    NULL,
120    /* intrinsics version */    XtVersion,
121    /* callback offsets   */    NULL,
122    /* tm_table           */    NULL,
123    /* query_geometry     */    QueryGeometry,
124    /* display_accelerator*/    NULL,
125    /* extension          */    NULL
126  },{
127    /* Menu Entry Fields */
128     
129    /* highlight */             FlipColors,
130    /* unhighlight */           FlipColors,
131    /* notify */                XtInheritNotify,               
132    /* extension          */    NULL
133  }, {
134    /* BSB Menu entry Fields */ 
135
136    /* extension          */    NULL
137  }
138};
139
140WidgetClass smeBSBObjectClass = (WidgetClass) &smeBSBClassRec;
141
142/************************************************************
143 *
144 * Semi-Public Functions.
145 *
146 ************************************************************/
147
148/*      Function Name: ClassInitialize
149 *      Description: Initializes the SmeBSBObject.
150 *      Arguments: none.
151 *      Returns: none.
152 */
153
154static void
155ClassInitialize()
156{
157    XawInitializeWidgetSet();
158    XtAddConverter( XtRString, XtRJustify, XmuCvtStringToJustify, NULL, 0 );
159}
160
161/*      Function Name: Initialize
162 *      Description: Initializes the simple menu widget
163 *      Arguments: request - the widget requested by the argument list.
164 *                 new     - the new widget with both resource and non
165 *                           resource values.
166 *      Returns: none.
167 */
168
169/* ARGSUSED */
170static void
171Initialize(request, new, args, num_args)
172Widget request, new;
173ArgList args;
174Cardinal *num_args;
175{
176    SmeBSBObject entry = (SmeBSBObject) new;
177
178    if (entry->sme_bsb.label == NULL)
179        entry->sme_bsb.label = XtName(new);
180    else
181        entry->sme_bsb.label = XtNewString( entry->sme_bsb.label );
182
183    GetDefaultSize(new, &(entry->rectangle.width), &(entry->rectangle.height));
184    CreateGCs(new);
185
186    entry->sme_bsb.left_bitmap_width = entry->sme_bsb.left_bitmap_height = 0;
187    entry->sme_bsb.right_bitmap_width = entry->sme_bsb.right_bitmap_height = 0;
188
189    GetBitmapInfo(new, TRUE);   /* Left Bitmap Info */
190    GetBitmapInfo(new, FALSE);  /* Right Bitmap Info */
191}
192
193/*      Function Name: Destroy
194 *      Description: Called at destroy time, cleans up.
195 *      Arguments: w - the simple menu widget.
196 *      Returns: none.
197 */
198
199static void
200Destroy(w)
201Widget w;
202{
203    SmeBSBObject entry = (SmeBSBObject) w;
204
205    DestroyGCs(w);
206    if (entry->sme_bsb.label != XtName(w))
207        XtFree(entry->sme_bsb.label);
208}
209
210/*      Function Name: Redisplay
211 *      Description: Redisplays the contents of the widget.
212 *      Arguments: w - the simple menu widget.
213 *                 event - the X event that caused this redisplay.
214 *                 region - the region the needs to be repainted.
215 *      Returns: none.
216 */
217
218/* ARGSUSED */
219static void
220Redisplay(w, event, region)
221Widget w;
222XEvent * event;
223Region region;
224{
225    GC gc;
226    SmeBSBObject entry = (SmeBSBObject) w;
227    int font_ascent, font_descent, y_loc;
228
229    entry->sme_bsb.set_values_area_cleared = FALSE;   
230    font_ascent = entry->sme_bsb.font->max_bounds.ascent;
231    font_descent = entry->sme_bsb.font->max_bounds.descent;
232
233    y_loc = entry->rectangle.y;
234   
235    if (XtIsSensitive(w) && XtIsSensitive( XtParent(w) ) ) {
236        if ( w == XawSimpleMenuGetActiveEntry(XtParent(w)) ) {
237            XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w),
238                           entry->sme_bsb.norm_gc, 0, y_loc,
239                           (unsigned int) entry->rectangle.width,
240                           (unsigned int) entry->rectangle.height);
241            gc = entry->sme_bsb.rev_gc;
242        }
243        else
244            gc = entry->sme_bsb.norm_gc;
245    }
246    else
247        gc = entry->sme_bsb.norm_gray_gc;
248   
249    if (entry->sme_bsb.label != NULL) {
250        int x_loc = entry->sme_bsb.left_margin;
251        int len = strlen(entry->sme_bsb.label);
252        char * label = entry->sme_bsb.label;
253
254        switch(entry->sme_bsb.justify) {
255            int width, t_width;
256
257        case XtJustifyCenter:
258            t_width = XTextWidth(entry->sme_bsb.font, label, len);
259            width = entry->rectangle.width - (entry->sme_bsb.left_margin +
260                                              entry->sme_bsb.right_margin);
261            x_loc += (width - t_width)/2;
262            break;
263        case XtJustifyRight:
264            t_width = XTextWidth(entry->sme_bsb.font, label, len);
265            x_loc = entry->rectangle.width - (entry->sme_bsb.right_margin +
266                                              t_width);
267            break;
268        case XtJustifyLeft:
269        default:
270            break;
271        }
272
273        y_loc += ((int)entry->rectangle.height -
274                  (font_ascent + font_descent)) / 2 + font_ascent;
275       
276        XDrawString(XtDisplayOfObject(w), XtWindowOfObject(w), gc,
277                    x_loc, y_loc, label, len);
278    }
279
280    DrawBitmaps(w, gc);
281}
282
283
284/*      Function Name: SetValues
285 *      Description: Relayout the menu when one of the resources is changed.
286 *      Arguments: current - current state of the widget.
287 *                 request - what was requested.
288 *                 new - what the widget will become.
289 *      Returns: none
290 */
291
292/* ARGSUSED */
293static Boolean
294SetValues(current, request, new, args, num_args)
295Widget current, request, new;
296ArgList args;
297Cardinal *num_args;
298{
299    SmeBSBObject entry = (SmeBSBObject) new;
300    SmeBSBObject old_entry = (SmeBSBObject) current;
301    Boolean ret_val = FALSE;
302
303    if (old_entry->sme_bsb.label != entry->sme_bsb.label) {
304        if (old_entry->sme_bsb.label != XtName( new ) )
305            XtFree( (char *) old_entry->sme_bsb.label );
306
307        if (entry->sme_bsb.label != XtName(new) )
308            entry->sme_bsb.label = XtNewString( entry->sme_bsb.label );
309
310        ret_val = True;
311    }
312
313    if (entry->rectangle.sensitive != old_entry->rectangle.sensitive )
314        ret_val = TRUE;
315
316    if (entry->sme_bsb.left_bitmap != old_entry->sme_bsb.left_bitmap) {
317        GetBitmapInfo(new, TRUE);
318        ret_val = TRUE;
319    }
320
321    if (entry->sme_bsb.right_bitmap != old_entry->sme_bsb.right_bitmap) {
322        GetBitmapInfo(new, FALSE);
323        ret_val = TRUE;
324    }
325
326    if ( (old_entry->sme_bsb.font != entry->sme_bsb.font) ||
327         (old_entry->sme_bsb.foreground != entry->sme_bsb.foreground) ) {
328        DestroyGCs(current);
329        CreateGCs(new);
330        ret_val = TRUE;
331    }
332
333    if (ret_val) {
334        GetDefaultSize(new,
335                       &(entry->rectangle.width), &(entry->rectangle.height));
336        entry->sme_bsb.set_values_area_cleared = TRUE;
337    }
338    return(ret_val);
339}
340
341/*      Function Name: QueryGeometry.
342 *      Description: Returns the preferred geometry for this widget.
343 *      Arguments: w - the menu entry object.
344 *                 itended, return_val - the intended and return geometry info.
345 *      Returns: A Geometry Result.
346 *
347 * See the Intrinsics manual for details on what this function is for.
348 *
349 * I just return the height and width of the label plus the margins.
350 */
351
352static XtGeometryResult
353QueryGeometry(w, intended, return_val)
354Widget w;
355XtWidgetGeometry *intended, *return_val;
356{
357    SmeBSBObject entry = (SmeBSBObject) w;
358    Dimension width, height;
359    XtGeometryResult ret_val = XtGeometryYes;
360    XtGeometryMask mode = intended->request_mode;
361
362    GetDefaultSize(w, &width, &height );   
363
364    if ( ((mode & CWWidth) && (intended->width != width)) ||
365         !(mode & CWWidth) ) {
366        return_val->request_mode |= CWWidth;
367        return_val->width = width;
368        ret_val = XtGeometryAlmost;
369    }
370
371    if ( ((mode & CWHeight) && (intended->height != height)) ||
372         !(mode & CWHeight) ) {
373        return_val->request_mode |= CWHeight;
374        return_val->height = height;
375        ret_val = XtGeometryAlmost;
376    }
377
378    if (ret_val == XtGeometryAlmost) {
379        mode = return_val->request_mode;
380       
381        if ( ((mode & CWWidth) && (width == entry->rectangle.width)) &&
382             ((mode & CWHeight) && (height == entry->rectangle.height)) )
383            return(XtGeometryNo);
384    }
385
386    return(ret_val);
387}
388   
389/*      Function Name: FlipColors
390 *      Description: Invert the colors of the current entry.
391 *      Arguments: w - the bsb menu entry widget.
392 *      Returns: none.
393 */
394
395static void
396FlipColors(w)
397Widget w;
398{
399    SmeBSBObject entry = (SmeBSBObject) w;
400
401    if (entry->sme_bsb.set_values_area_cleared) return;
402
403    if (! entry->sme_bsb.flip_colors) return;
404
405    XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w),
406                   entry->sme_bsb.invert_gc, 0, (int) entry->rectangle.y,
407                   (unsigned int) entry->rectangle.width,
408                   (unsigned int) entry->rectangle.height);
409}
410
411/************************************************************
412 *
413 * Private Functions.
414 *
415 ************************************************************/
416
417/*      Function Name: GetDefaultSize
418 *      Description: Calculates the Default (preferred) size of
419 *                   this menu entry.
420 *      Arguments: w - the menu entry widget.
421 *                 width, height - default sizes (RETURNED).
422 *      Returns: none.
423 */
424
425static void
426GetDefaultSize(w, width, height)
427Widget w;
428Dimension * width, * height;
429{
430    SmeBSBObject entry = (SmeBSBObject) w;
431
432    if (entry->sme_bsb.label == NULL)
433        *width = 0;
434    else
435        *width = XTextWidth(entry->sme_bsb.font, entry->sme_bsb.label,
436                            strlen(entry->sme_bsb.label));
437
438    *width += entry->sme_bsb.left_margin + entry->sme_bsb.right_margin;
439   
440    *height = (entry->sme_bsb.font->max_bounds.ascent +
441               entry->sme_bsb.font->max_bounds.descent);
442
443    *height = ((int)*height * ( ONE_HUNDRED +
444                                entry->sme_bsb.vert_space )) / ONE_HUNDRED;
445}
446
447/*      Function Name: DrawBitmaps
448 *      Description: Draws left and right bitmaps.
449 *      Arguments: w - the simple menu widget.
450 *                 gc - graphics context to use for drawing.
451 *      Returns: none
452 */
453
454static void
455DrawBitmaps(w, gc)
456Widget w;
457GC gc;
458{
459    int x_loc, y_loc;
460    SmeBSBObject entry = (SmeBSBObject) w;
461   
462    if ( (entry->sme_bsb.left_bitmap == None) &&
463         (entry->sme_bsb.right_bitmap == None) ) return;
464
465/*
466 * Draw Left Bitmap.
467 */
468
469  if (entry->sme_bsb.left_bitmap != None) {
470    x_loc = (int)(entry->sme_bsb.left_margin -
471                  entry->sme_bsb.left_bitmap_width) / 2;
472
473    y_loc = entry->rectangle.y + (int)(entry->rectangle.height -
474                                       entry->sme_bsb.left_bitmap_height) / 2;
475
476    XCopyPlane(XtDisplayOfObject(w), entry->sme_bsb.left_bitmap,
477               XtWindowOfObject(w), gc, 0, 0,
478               entry->sme_bsb.left_bitmap_width,
479               entry->sme_bsb.left_bitmap_height, x_loc, y_loc, 1);
480  }
481
482/*
483 * Draw Right Bitmap.
484 */
485
486
487  if (entry->sme_bsb.right_bitmap != None) {
488    x_loc = entry->rectangle.width -
489              (int)(entry->sme_bsb.right_margin +
490                    entry->sme_bsb.right_bitmap_width) / 2;
491
492    y_loc = entry->rectangle.y + (int)(entry->rectangle.height -
493                                       entry->sme_bsb.right_bitmap_height) / 2;
494
495    XCopyPlane(XtDisplayOfObject(w), entry->sme_bsb.right_bitmap,
496               XtWindowOfObject(w), gc, 0, 0,
497               entry->sme_bsb.right_bitmap_width,
498               entry->sme_bsb.right_bitmap_height, x_loc, y_loc, 1);
499  }
500}
501
502/*      Function Name: GetBitmapInfo
503 *      Description: Gets the bitmap information from either of the bitmaps.
504 *      Arguments: w - the bsb menu entry widget.
505 *                 is_left - TRUE if we are testing left bitmap,
506 *                           FALSE if we are testing the right bitmap.
507 *      Returns: none
508 */
509
510static void
511GetBitmapInfo(w, is_left)
512Widget w;
513Boolean is_left;
514{
515    SmeBSBObject entry = (SmeBSBObject) w;   
516    unsigned int depth, bw;
517    Window root;
518    int x, y;
519    unsigned int width, height;
520    char buf[BUFSIZ];
521   
522    if (is_left) {
523        if (entry->sme_bsb.left_bitmap != None) {
524            if (!XGetGeometry(XtDisplayOfObject(w),
525                              entry->sme_bsb.left_bitmap, &root,
526                              &x, &y, &width, &height, &bw, &depth)) {
527                sprintf(buf, "SmeBSB Object: %s %s \"%s\".", "Could not",
528                        "get Left Bitmap geometry information for menu entry ",
529                        XtName(w));
530                XtAppError(XtWidgetToApplicationContext(w), buf);
531            }
532            if (depth != 1) {
533                sprintf(buf, "SmeBSB Object: %s \"%s\"%s.",
534                        "Left Bitmap of entry ",
535                        XtName(w), " is not one bit deep.");
536                XtAppError(XtWidgetToApplicationContext(w), buf);
537            }
538            entry->sme_bsb.left_bitmap_width = (Dimension) width;
539            entry->sme_bsb.left_bitmap_height = (Dimension) height;
540        }
541    }
542    else if (entry->sme_bsb.right_bitmap != None) {
543        if (!XGetGeometry(XtDisplayOfObject(w),
544                          entry->sme_bsb.right_bitmap, &root,
545                          &x, &y, &width, &height, &bw, &depth)) {
546            sprintf(buf, "SmeBSB Object: %s %s \"%s\".", "Could not",
547                    "get Right Bitmap geometry information for menu entry ",
548                    XtName(w));
549            XtAppError(XtWidgetToApplicationContext(w), buf);
550        }
551        if (depth != 1) {
552            sprintf(buf, "SmeBSB Object: %s \"%s\"%s.",
553                    "Right Bitmap of entry ", XtName(w),
554                    " is not one bit deep.");
555            XtAppError(XtWidgetToApplicationContext(w), buf);
556        }
557        entry->sme_bsb.right_bitmap_width = (Dimension) width;
558        entry->sme_bsb.right_bitmap_height = (Dimension) height;
559    }
560}     
561
562/*      Function Name: CreateGCs
563 *      Description: Creates all gc's for the simple menu widget.
564 *      Arguments: w - the simple menu widget.
565 *      Returns: none.
566 */
567
568static void
569CreateGCs(w)
570Widget w;
571{
572    SmeBSBObject entry = (SmeBSBObject) w;   
573    XGCValues values;
574    XtGCMask mask;
575   
576    values.foreground = XtParent(w)->core.background_pixel;
577    values.background = entry->sme_bsb.foreground;
578    values.font = entry->sme_bsb.font->fid;
579    values.graphics_exposures = FALSE;
580    mask        = GCForeground | GCBackground | GCFont | GCGraphicsExposures;
581    entry->sme_bsb.rev_gc = XtGetGC(w, mask, &values);
582   
583    values.foreground = entry->sme_bsb.foreground;
584    values.background = XtParent(w)->core.background_pixel;
585    entry->sme_bsb.norm_gc = XtGetGC(w, mask, &values);
586   
587    values.fill_style = FillTiled;
588    values.tile   = XmuCreateStippledPixmap(XtScreenOfObject(w),
589                                            entry->sme_bsb.foreground,
590                                            XtParent(w)->core.background_pixel,
591                                            XtParent(w)->core.depth);
592    values.graphics_exposures = FALSE;
593    mask |= GCTile | GCFillStyle;
594    entry->sme_bsb.norm_gray_gc = XtGetGC(w, mask, &values);
595   
596    values.foreground ^= values.background;
597    values.background = 0;
598    values.function = GXxor;
599    mask = GCForeground | GCBackground | GCGraphicsExposures | GCFunction;
600    entry->sme_bsb.invert_gc = XtGetGC(w, mask, &values);
601}
602
603/*      Function Name: DestroyGCs
604 *      Description: Removes all gc's for the simple menu widget.
605 *      Arguments: w - the simple menu widget.
606 *      Returns: none.
607 */
608
609static void
610DestroyGCs(w)
611Widget w;
612{
613    SmeBSBObject entry = (SmeBSBObject) w;   
614
615    XtReleaseGC(w, entry->sme_bsb.norm_gc);
616    XtReleaseGC(w, entry->sme_bsb.norm_gray_gc);
617    XtReleaseGC(w, entry->sme_bsb.rev_gc);
618    XtReleaseGC(w, entry->sme_bsb.invert_gc);
619}
620
621#ifdef apollo
622
623/*
624 * The apollo compiler that we have optomizes out my code for
625 * FlipColors() since it is static. and no one executes it in this
626 * file.  I am setting the function pointer into the class structure so
627 * that it can be called by my parent who will tell me to when to
628 * highlight and unhighlight.
629 */
630
631void _XawSmeBSBApolloHack ()
632{
633    FlipColors();
634}
635#endif /* apollo */
Note: See TracBrowser for help on using the repository browser.