home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / XfeWidgets / Xfe / Primitive.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  46.6 KB  |  1,701 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. /*-----------------------------------------*/
  19. /*                                                                        */
  20. /* Name:        <Xfe/Primitive.c>                                        */
  21. /* Description:    XfePrimitive widget source.                                */
  22. /* Author:        Ramiro Estrugo <ramiro@netscape.com>                    */
  23. /*                                                                        */
  24. /*----------------------------------------------------------------------*/
  25.  
  26.  
  27. #include <stdio.h>
  28.  
  29. #include <Xfe/PrimitiveP.h>
  30.  
  31. /*----------------------------------------------------------------------*/
  32. /*                                                                        */
  33. /* Warnings and messages                                                */
  34. /*                                                                        */
  35. /*----------------------------------------------------------------------*/
  36. #define MESSAGE0 "XfePrimitive is an abstract class and cannot be instanciated."
  37. #define MESSAGE1 "Widget is not XfePrimitive."
  38. #define MESSAGE2 "XmNpreferredHeight is a read-only resource."
  39. #define MESSAGE3 "XmNpreferredWidth is a read-only resource."
  40. #define MESSAGE4 "XmNpointerInside is a read-only resource."
  41. #define MESSAGE5 "XmNnumPopupChildren is a read-only resource."
  42. #define MESSAGE6 "XmNpopupChildren is a read-only resource."
  43. #define MESSAGE7 "Cannot change XmNbufferType after initialization."
  44. #define MESSAGE8 "Widget's width must be greater than 0."
  45. #define MESSAGE9 "Widget's height must be greater than 0."
  46.  
  47. /*----------------------------------------------------------------------*/
  48. /*                                                                        */
  49. /* Core Class Methods                                                    */
  50. /*                                                                        */
  51. /*----------------------------------------------------------------------*/
  52. static void                ClassInitialize    ();
  53. static void                ClassPartInit    (WidgetClass);
  54. static void                Initialize        (Widget,Widget,ArgList,Cardinal *);
  55. static void                Destroy            (Widget);
  56. static void                Redisplay        (Widget,XEvent *,Region);
  57. static void                Realize            (Widget,XtValueMask *,
  58.                                          XSetWindowAttributes *);
  59. static void                Resize            (Widget);
  60. static Boolean            SetValues        (Widget,Widget,Widget,ArgList,
  61.                                          Cardinal *);
  62. static XtGeometryResult    QueryGeometry    (Widget,XtWidgetGeometry *,
  63.                                          XtWidgetGeometry *);
  64.  
  65. /*----------------------------------------------------------------------*/
  66. /*                                                                        */
  67. /* XmPrimitive Extension Methods                                        */
  68. /*                                                                        */
  69. /*----------------------------------------------------------------------*/
  70. static Boolean        WidgetDisplayRect    (Widget,XRectangle  *);
  71.  
  72. /*----------------------------------------------------------------------*/
  73. /*                                                                        */
  74. /* XfePrimitive Class Methods                                            */
  75. /*                                                                        */
  76. /*----------------------------------------------------------------------*/
  77. static void            InitializePostHook    (Widget,Widget);
  78. static Boolean        SetValuesPostHook    (Widget,Widget,Widget);
  79. static void            PreferredGeometry    (Widget,Dimension *,Dimension *);
  80. static void            MinimumGeometry    (Widget,Dimension *,Dimension *);
  81. static void            UpdateRect            (Widget);
  82. static void            DrawShadow            (Widget,XEvent *,Region,XRectangle *);
  83.  
  84. /*----------------------------------------------------------------------*/
  85. /*                                                                        */
  86. /* XfePrimitive Buffer Pixmap functions                                    */
  87. /*                                                                        */
  88. /*----------------------------------------------------------------------*/
  89. static void     BufferAllocate            (Widget);
  90. static void     BufferFree                (Widget);
  91. static void     BufferUpdate            (Widget);
  92.  
  93. /*----------------------------------------------------------------------*/
  94. /*                                                                        */
  95. /* Misc XfePrimitive functions                                            */
  96. /*                                                                        */
  97. /*----------------------------------------------------------------------*/
  98. static Dimension        GetWidth        (Widget);
  99. static Dimension        GetHeight        (Widget);
  100.  
  101. /*----------------------------------------------------------------------*/
  102. /*                                                                        */
  103. /* XfePrimitive Resources                                                */
  104. /*                                                                        */
  105. /*----------------------------------------------------------------------*/
  106. static XtResource resources[] = 
  107. {
  108.     /* Callback resources */
  109.     { 
  110.         XmNenterCallback,
  111.         XmCCallback,
  112.         XmRCallback,
  113.         sizeof(XtCallbackList),
  114.         XtOffsetOf(XfePrimitiveRec , xfe_primitive . enter_callback),
  115.         XmRImmediate, 
  116.         (XtPointer) NULL,
  117.     },
  118.     { 
  119.         XmNfocusCallback,
  120.         XmCCallback,
  121.         XmRCallback,
  122.         sizeof(XtCallbackList),
  123.         XtOffsetOf(XfePrimitiveRec , xfe_primitive . focus_callback),
  124.         XmRImmediate, 
  125.         (XtPointer) NULL,
  126.     },
  127.     { 
  128.         XmNleaveCallback,
  129.         XmCCallback,
  130.         XmRCallback,
  131.         sizeof(XtCallbackList),
  132.         XtOffsetOf(XfePrimitiveRec , xfe_primitive . leave_callback),
  133.         XmRImmediate, 
  134.         (XtPointer) NULL,
  135.     },
  136.     { 
  137.         XmNresizeCallback,
  138.         XmCCallback,
  139.         XmRCallback,
  140.         sizeof(XtCallbackList),
  141.         XtOffsetOf(XfePrimitiveRec , xfe_primitive . resize_callback),
  142.         XmRImmediate, 
  143.         (XtPointer) NULL,
  144.     },
  145.  
  146.     /* Cursor resources */
  147.     { 
  148.         XmNcursor,
  149.         XmCCursor,
  150.         XmRCursor,
  151.         sizeof(Cursor),
  152.         XtOffsetOf(XfePrimitiveRec , xfe_primitive . cursor),
  153.         XmRImmediate, 
  154.         (XtPointer) None
  155.     },
  156.  
  157.     /* Appearance resources */
  158.     { 
  159.         XmNshadowType,
  160.         XmCShadowType,
  161.         XmRShadowType,
  162.         sizeof(unsigned char),
  163.         XtOffsetOf(XfePrimitiveRec , xfe_primitive . shadow_type),
  164.         XmRImmediate, 
  165.         (XtPointer) XfeDEFAULT_SHADOW_TYPE
  166.     },
  167.     { 
  168.         XmNbufferType,
  169.         XmCBufferType,
  170.         XmRBufferType,
  171.         sizeof(unsigned char),
  172.         XtOffsetOf(XfePrimitiveRec , xfe_primitive . buffer_type),
  173.         XmRImmediate, 
  174.         (XtPointer) XfeDEFAULT_BUFFER_TYPE
  175.     },
  176.     { 
  177.         XmNpretendSensitive,
  178.         XmCPretendSensitive,
  179.         XmRBoolean,
  180.         sizeof(Boolean),
  181.         XtOffsetOf(XfePrimitiveRec , xfe_primitive . pretend_sensitive),
  182.         XmRImmediate, 
  183.         (XtPointer) True
  184.     },
  185.  
  186.     /* Geometry resources */
  187.     {
  188.         XmNusePreferredHeight,
  189.         XmCUsePreferredHeight,
  190.         XmRBoolean,
  191.         sizeof(Boolean),
  192.         XtOffsetOf(XfePrimitiveRec , xfe_primitive . use_preferred_height),
  193.         XmRImmediate, 
  194.         (XtPointer) True
  195.     },
  196.     {
  197.         XmNusePreferredWidth,
  198.         XmCUsePreferredWidth,
  199.         XmRBoolean,
  200.         sizeof(Boolean),
  201.         XtOffsetOf(XfePrimitiveRec , xfe_primitive . use_preferred_width),
  202.         XmRImmediate, 
  203.         (XtPointer) True
  204.     },
  205.     { 
  206.         XmNmarginBottom,
  207.         XmCMarginBottom,
  208.         XmRVerticalDimension,
  209.         sizeof(Dimension),
  210.         XtOffsetOf(XfePrimitiveRec , xfe_primitive . margin_bottom),
  211.         XmRImmediate, 
  212.         (XtPointer) XfeDEFAULT_MARGIN_BOTTOM 
  213.     },
  214.     { 
  215.         XmNmarginLeft,
  216.         XmCMarginLeft,
  217.         XmRHorizontalDimension,
  218.         sizeof(Dimension),
  219.         XtOffsetOf(XfePrimitiveRec , xfe_primitive . margin_left),
  220.         XmRImmediate, 
  221.         (XtPointer) XfeDEFAULT_MARGIN_LEFT 
  222.     },
  223.     { 
  224.         XmNmarginRight,
  225.         XmCMarginRight,
  226.         XmRHorizontalDimension,
  227.         sizeof(Dimension),
  228.         XtOffsetOf(XfePrimitiveRec , xfe_primitive . margin_right),
  229.         XmRImmediate, 
  230.         (XtPointer) XfeDEFAULT_MARGIN_RIGHT 
  231.     },
  232.     { 
  233.         XmNmarginTop,
  234.         XmCMarginTop,
  235.         XmRVerticalDimension,
  236.         sizeof(Dimension),
  237.         XtOffsetOf(XfePrimitiveRec , xfe_primitive . margin_top),
  238.         XmRImmediate, 
  239.         (XtPointer) XfeDEFAULT_MARGIN_TOP 
  240.     },
  241.  
  242.     /* For c++ usage */
  243.     { 
  244.         XmNinstancePointer,
  245.         XmCInstancePointer,
  246.         XmRPointer,
  247.         sizeof(XtPointer),
  248.         XtOffsetOf(XfePrimitiveRec , xfe_primitive . instance_pointer),
  249.         XmRImmediate, 
  250.         (XtPointer) NULL
  251.     },
  252.  
  253.  
  254.     /* Read-only resources */
  255.     { 
  256.         XmNpointerInside,
  257.         XmCReadOnly,
  258.         XmRBoolean,
  259.         sizeof(Boolean),
  260.         XtOffsetOf(XfePrimitiveRec , xfe_primitive . pointer_inside),
  261.         XmRImmediate, 
  262.         (XtPointer) False
  263.     },
  264.     { 
  265.         XmNpreferredHeight,
  266.         XmCReadOnly,
  267.         XmRVerticalDimension,
  268.         sizeof(Dimension),
  269.         XtOffsetOf(XfePrimitiveRec , xfe_primitive . preferred_height),
  270.         XmRImmediate, 
  271.         (XtPointer) True
  272.     },
  273.     { 
  274.         XmNpreferredWidth,
  275.         XmCReadOnly,
  276.         XmRHorizontalDimension,
  277.         sizeof(Dimension),
  278.         XtOffsetOf(XfePrimitiveRec , xfe_primitive . preferred_width),
  279.         XmRImmediate, 
  280.         (XtPointer) True
  281.     },
  282.  
  283.     /* Core popup resources */
  284.     { 
  285.         XmNnumPopupChildren,
  286.         XmCReadOnly,
  287.         XmRCardinal,
  288.         sizeof(Cardinal),
  289.         XtOffsetOf(XfePrimitiveRec , core . num_popups),
  290.         XmRImmediate,
  291.         (XtPointer) 0,
  292.     },
  293.     { 
  294.         XmNpopupChildren,
  295.         XmCReadOnly,
  296.         XmRWidgetList,
  297.         sizeof(WidgetList),
  298.         XtOffsetOf(XfePrimitiveRec , core . popup_list),
  299.         XmRImmediate,
  300.         (XtPointer) NULL,
  301.     },
  302.  
  303.     /* Force a default shadow thickness */
  304.     { 
  305.         XmNshadowThickness,
  306.         XmCShadowThickness,
  307.         XmRHorizontalDimension,
  308.         sizeof(Dimension),
  309.         XtOffsetOf(XfePrimitiveRec , primitive . shadow_thickness),
  310.         XmRImmediate, 
  311.         (XtPointer) XfeDEFAULT_SHADOW_THICKNESS 
  312.     },
  313.  
  314.     /* Force the width and height to the preffered values */
  315.     { 
  316.         XmNwidth,
  317.         XmCWidth,
  318.         XmRHorizontalDimension,
  319.         sizeof(Dimension),
  320.         XtOffsetOf(XfePrimitiveRec , core . width),
  321.         XmRImmediate, 
  322.         (XtPointer) XfeDEFAULT_PREFERRED_WIDTH
  323.     },
  324.     { 
  325.         XmNheight,
  326.         XmCHeight,
  327.         XmRVerticalDimension,
  328.         sizeof(Dimension),
  329.         XtOffsetOf(XfePrimitiveRec , core . height),
  330.         XmRImmediate, 
  331.         (XtPointer) XfeDEFAULT_PREFERRED_HEIGHT
  332.     },
  333. };   
  334.  
  335. /*----------------------------------------------------------------------*/
  336. /*                                                                        */
  337. /* XfePrimitive Synthetic Resources                                        */
  338. /*                                                                        */
  339. /*----------------------------------------------------------------------*/
  340. static XmSyntheticResource syn_resources[] =
  341. {
  342.     { 
  343.         XmNmarginBottom,
  344.         sizeof(Dimension),
  345.         XtOffsetOf(XfePrimitiveRec , xfe_primitive . margin_bottom),
  346.         _XmFromVerticalPixels,
  347.         _XmToVerticalPixels 
  348.     },
  349.     {
  350.         XmNmarginLeft,
  351.         sizeof(Dimension),
  352.         XtOffsetOf(XfePrimitiveRec , xfe_primitive . margin_left),
  353.         _XmFromHorizontalPixels,
  354.         _XmToHorizontalPixels 
  355.     },
  356.     { 
  357.         XmNmarginRight,
  358.         sizeof(Dimension),
  359.         XtOffsetOf(XfePrimitiveRec , xfe_primitive . margin_right),
  360.         _XmFromHorizontalPixels,
  361.         _XmToHorizontalPixels 
  362.     },
  363.     { 
  364.         XmNmarginTop,
  365.         sizeof(Dimension),
  366.         XtOffsetOf(XfePrimitiveRec , xfe_primitive . margin_top),
  367.         _XmFromVerticalPixels,
  368.         _XmToVerticalPixels 
  369.     },
  370. };
  371.  
  372. /*----------------------------------------------------------------------*/
  373. /*                                                                        */
  374. /* XfePrimitive Actions                                                    */
  375. /*                                                                        */
  376. /*----------------------------------------------------------------------*/
  377. static XtActionsRec actions[] = 
  378. {
  379.     { "Focus",        _XfePrimitiveFocus    },
  380.     { "Enter",        _XfePrimitiveEnter    },
  381.     { "Leave",        _XfePrimitiveLeave    },
  382. };
  383.  
  384. /*----------------------------------------------------------------------*/
  385. /*                                                                        */
  386. /* XmPrimitive extension record initialization                            */
  387. /*                                                                        */
  388. /*----------------------------------------------------------------------*/
  389. static XmPrimitiveClassExtRec primClassExtRec = 
  390. {
  391.     NULL,                                    /* next_extension            */
  392.     NULLQUARK,                                /* record_type                */
  393.     XmPrimitiveClassExtVersion,                /* version                    */
  394.     sizeof(XmPrimitiveClassExtRec),            /* record_size                */
  395.     NULL,                                    /* widget_baseline            */
  396.     WidgetDisplayRect,                        /* widget_display_rect        */
  397.     NULL,                                    /* widget_margins            */
  398. };
  399.  
  400. /*----------------------------------------------------------------------*/
  401. /*                                                                        */
  402. /* XfePrimitive widget class record initialization                        */
  403. /*                                                                        */
  404. /*----------------------------------------------------------------------*/
  405. _XFE_WIDGET_CLASS_RECORD(primitive,Primitive) =
  406. {
  407.     {
  408.         /* Core Part */
  409.         (WidgetClass) &xmPrimitiveClassRec,    /* superclass                */
  410.         "XfePrimitive",                        /* class_name                */
  411.         sizeof(XfePrimitiveRec),            /* widget_size                */
  412.         ClassInitialize,                    /* class_initialize            */
  413.         ClassPartInit,                        /* class_part_initiali        */
  414.         FALSE,                                /* class_inited                */
  415.         Initialize,                            /* initialize                */
  416.         NULL,                                /* initialize_hook            */
  417.         Realize,                            /* realize                    */
  418.         actions,                            /* actions                    */
  419.         XtNumber(actions),                    /* num_actions                */
  420.         resources,                            /* resources                */
  421.         XtNumber(resources),                /* num_resources            */
  422.         NULLQUARK,                            /* xrm_class                */
  423.         TRUE,                                /* compress_motion            */
  424.         XtExposeCompressMaximal,            /* compress_exposure        */
  425.         TRUE,                                /* compress_enterleave        */
  426.         FALSE,                                /* visible_interest            */
  427.         Destroy,                            /* destroy                    */
  428.         Resize,                                /* resize                    */
  429.         Redisplay,                            /* expose                    */
  430.         SetValues,                            /* set_values                */
  431.         NULL,                                /* set_values_hook            */
  432.         XtInheritSetValuesAlmost,            /* set_values_almost        */
  433.         NULL,                                /* get_values_hook            */
  434.         NULL,                                /* accept_focus                */
  435.         XtVersion,                            /* version                    */
  436.         NULL,                                /* callback_private            */
  437.         _XfePrimitiveDefaultTranslations,    /* tm_table                    */
  438.         QueryGeometry,                        /* query_geometry            */
  439.         XtInheritDisplayAccelerator,        /* display accel            */
  440.         NULL,                                /* extension                */
  441.     },
  442.  
  443.     /* XmPrimitive Part */
  444.     {
  445.         XmInheritBorderHighlight,            /* border_highlight            */
  446.         XmInheritBorderUnhighlight,            /* border_unhighlight        */
  447.         XtInheritTranslations,                /* translations                */
  448.         NULL,                                /* arm_and_activate            */
  449.         syn_resources,                        /* syn resources            */
  450.         XtNumber(syn_resources),            /* num syn_resources        */
  451.         (XtPointer) &primClassExtRec,        /* extension                */
  452.     },
  453.  
  454.     /* XfePrimitive Part */
  455.     {
  456.         ForgetGravity,                        /* bit_gravity                */
  457.         PreferredGeometry,                    /* preferred_geometry        */
  458.         MinimumGeometry,                    /* minimum_geometry        */
  459.         UpdateRect,                            /* update_rect                */
  460.         NULL,                                /* prepare_components        */
  461.         NULL,                                /* layout_components        */
  462.         NULL,                                /* draw_background            */
  463.         DrawShadow,                            /* draw_shadow                */
  464.         NULL,                                /* draw_components            */
  465.         NULL                                /* extension                */
  466.     }
  467. };
  468.  
  469. /*----------------------------------------------------------------------*/
  470. /*                                                                        */
  471. /* xfePrimitiveWidgetClass declaration.                                    */
  472. /*                                                                        */
  473. /*----------------------------------------------------------------------*/
  474. _XFE_WIDGET_CLASS(primitive,Primitive);
  475.  
  476. /*----------------------------------------------------------------------*/
  477. /*                                                                        */
  478. /* Core Class Methods                                                    */
  479. /*                                                                        */
  480. /*----------------------------------------------------------------------*/
  481. static void
  482. ClassInitialize()
  483. {
  484.     /* Register Xfe Converters */
  485.     XfeRegisterConverters();
  486.     
  487.     /* Register Representation Types */
  488.     XfeRegisterRepresentationTypes();
  489. }
  490. /*----------------------------------------------------------------------*/
  491. static void
  492. ClassPartInit(WidgetClass wc)
  493. {
  494.     XfePrimitiveWidgetClass cc = (XfePrimitiveWidgetClass) wc;
  495.     XfePrimitiveWidgetClass sc = (XfePrimitiveWidgetClass) wc->core_class.superclass;
  496.  
  497.     /* Resolve inheritance of all XfePrimitive class methods */
  498.     _XfeResolve(cc,sc,xfe_primitive_class,bit_gravity,
  499.                 XfeInheritBitGravity);
  500.    
  501.     _XfeResolve(cc,sc,xfe_primitive_class,preferred_geometry,
  502.                 XfeInheritPreferredGeometry);
  503.  
  504.     _XfeResolve(cc,sc,xfe_primitive_class,minimum_geometry,
  505.                 XfeInheritMinimumGeometry);
  506.    
  507.     _XfeResolve(cc,sc,xfe_primitive_class,update_rect,
  508.                 XfeInheritUpdateRect);
  509.  
  510.     _XfeResolve(cc,sc,xfe_primitive_class,layout_components,
  511.                 XfeInheritLayoutComponents);
  512.    
  513.     _XfeResolve(cc,sc,xfe_primitive_class,draw_background,
  514.                 XfeInheritDrawBackground);
  515.    
  516.     _XfeResolve(cc,sc,xfe_primitive_class,draw_shadow,
  517.                 XfeInheritDrawShadow);
  518.    
  519.     _XfeResolve(cc,sc,xfe_primitive_class,draw_components,
  520.                 XfeInheritDrawComponents);
  521. }
  522. /*----------------------------------------------------------------------*/
  523. static void
  524. Initialize(Widget rw,Widget nw,ArgList args,Cardinal *nargs)
  525. {
  526.     /* Make sure the shadow is ok */
  527.     XfeRepTypeCheck(nw,XmRShadowType,&_XfeShadowType(nw),XfeDEFAULT_SHADOW_TYPE);
  528.     
  529.     /* Make sure the buffer is ok */
  530.     XfeRepTypeCheck(nw,XmRBufferType,&_XfeBufferType(nw),XfeDEFAULT_BUFFER_TYPE);
  531.  
  532.     /* Initialize private members */
  533.     _XfeBufferPixmap(nw) = XmUNSPECIFIED_PIXMAP;
  534.     _XfeBackgroundGC(nw) = NULL;
  535.  
  536.     /* Allocate the background gc if needed */
  537.     if (_XfeBufferType(nw) != XmBUFFER_NONE)
  538.     {
  539.         _XfePrimitiveAllocateBackgroundGC(nw);
  540.     }
  541.  
  542.     /* Finish initialization */
  543.     _XfePrimitiveChainInitialize(rw,nw,xfePrimitiveWidgetClass);
  544. }
  545. /*----------------------------------------------------------------------*/
  546. static void
  547. Destroy(Widget w)
  548. {
  549.     /* Remove all CallBacks */
  550.     /* XtRemoveAllCallbacks(w,XmNenterCallback); */
  551.     /* XtRemoveAllCallbacks(w,XmNfocusCallback); */
  552.     /* XtRemoveAllCallbacks(w,XmNleaveCallback); */
  553.     /* XtRemoveAllCallbacks(w,XmNresizeCallback); */
  554.     
  555.     /* Free or release a possible buffer */
  556.     BufferFree(w);
  557.  
  558.     /* Free background gc if needed */
  559.     if (_XfeBackgroundGC(w))
  560.     {
  561.         _XfePrimitiveReleaseBackgroundGC(w);
  562.     }
  563. }
  564. /*----------------------------------------------------------------------*/
  565. static void
  566. Redisplay(Widget w,XEvent *event,Region region)
  567. {
  568.    /* Make sure the widget is realized before drawing ! */
  569.    if (!XtIsRealized(w))
  570.    {
  571.       return;
  572.    }
  573.  
  574.    switch(_XfeBufferType(w))
  575.    {
  576.        /* No buffer: simply re-draw everything */
  577.    case XmBUFFER_NONE:
  578.        _XfePrimitiveDrawEverything(w,event,region);
  579.        break;
  580.        
  581.        /* Single buffer: draw the buffer only */
  582.    case XmBUFFER_PRIVATE:
  583.        _XfePrimitiveDrawBuffer(w,event,region);
  584.        break;
  585.        
  586.        /* Multiple buffer: update the buffer and draw it */
  587.    case XmBUFFER_SHARED:
  588.        _XfePrimitiveDrawEverything(w,event,region);
  589.        _XfePrimitiveDrawBuffer(w,event,region);
  590.        break;
  591.    }
  592. }
  593. /*----------------------------------------------------------------------*/
  594. static void
  595. Realize(Widget w,XtValueMask * mask,XSetWindowAttributes* wa)
  596. {
  597.     XSetWindowAttributes attr;
  598.  
  599.     /* Make sure only subclasses of XfePrimitive get instanciated */
  600.     if ((XtClass(w) == xfePrimitiveWidgetClass))
  601.     {
  602.         _XfeWarning(w,MESSAGE0);
  603.  
  604.         return;
  605.     }
  606.  
  607.     /* Let XmPrimitive create the window */
  608.     (*xmPrimitiveWidgetClass->core_class.realize)(w,mask,wa);
  609.     
  610.     /* Set the Bit Gravity */
  611.     attr.bit_gravity = _XfePrimitiveAccessBitGravity(w);
  612.     
  613.     XChangeWindowAttributes(XtDisplay(w),_XfeWindow(w),CWBitGravity,&attr);
  614.  
  615.     /* Define the cursor if needed */
  616.     if (_XfeCursorGood(_XfeCursor(w)) && _XfePointerInside(w))
  617.     {
  618.         XfeCursorDefine(w,_XfeCursor(w));
  619.     }
  620. }
  621. /*----------------------------------------------------------------------*/
  622. static void
  623. Resize(Widget w)
  624. {
  625.     /*printf("%s: Resize to (%d,%d)\n",XtName(w),_XfeWidth(w),_XfeHeight(w));*/
  626.  
  627.     /* Obtain the Prefered Geometry */
  628.     _XfePrimitivePreferredGeometry(w,
  629.                                    &_XfePreferredWidth(w),
  630.                                    &_XfePreferredHeight(w));
  631.     
  632.     /* Force the preferred dimensions if required */
  633.     if (_XfeUsePreferredWidth(w))
  634.     {
  635.         _XfeWidth(w) = _XfePreferredWidth(w);
  636.     }
  637.     
  638.     if (_XfeUsePreferredHeight(w))
  639.     {
  640.         _XfeHeight(w) = _XfePreferredHeight(w);
  641.     }
  642.     
  643.     /* Update the widget rect */
  644.     _XfePrimitiveUpdateRect(w);
  645.     
  646.     /* Layout the components */
  647.     _XfePrimitiveLayoutComponents(w);
  648.     
  649.     switch(_XfeBufferType(w))
  650.     {
  651.         /* No buffer: nothing */
  652.     case XmBUFFER_NONE:
  653.         break;
  654.     
  655.         /* Single buffer: update the buffer size and contents */
  656.     case XmBUFFER_PRIVATE:
  657.         BufferUpdate(w);
  658.         _XfePrimitiveDrawEverything(w,NULL,NULL);
  659.         break;
  660.     
  661.     /* Multiple buffer: update the buffer size only */
  662.     case XmBUFFER_SHARED:
  663.         BufferUpdate(w);
  664.         break;
  665.     }
  666.     
  667.     /* Invoke Resize Callbacks */
  668.     _XfeInvokeCallbacks(w,_XfeResizeCallbacks(w),XmCR_RESIZE,NULL,True);
  669. }
  670. /*----------------------------------------------------------------------*/
  671. static XtGeometryResult
  672. QueryGeometry(Widget w,XtWidgetGeometry    *req,XtWidgetGeometry *reply)
  673. {
  674.     assert( req != NULL );
  675.     assert( reply != NULL );
  676.  
  677.     reply->request_mode    = CWWidth | CWHeight;
  678.  
  679.     /* Set the reply dimensions */
  680.     reply->width  = GetWidth(w);
  681.  
  682.     reply->height = GetHeight(w);
  683.  
  684.     /* XtGeometryYes: Request matches Prefered Geometry. */
  685.     if (((req->request_mode & CWWidth) && (req->width == reply->width)) &&
  686.         ((req->request_mode & CWHeight) && (req->height == reply->height)))
  687.     {
  688.         return XtGeometryYes;
  689.     }
  690.    
  691.     /* XtGeometryNo: Reply matches current Geometry. */
  692.     if ((reply->width == _XfeWidth(w)) && (reply->height == _XfeHeight(w)))
  693.     {
  694.         return XtGeometryNo; 
  695.     }
  696.    
  697.     /* XtGeometryAlmost: One of reply fields doesn't match cur/req Geometry. */
  698.     return XtGeometryAlmost; 
  699. }
  700. /*----------------------------------------------------------------------*/
  701. static Boolean
  702. SetValues(Widget ow,Widget rw,Widget nw,ArgList args,Cardinal *nargs)
  703. {
  704.     /* Reset the configuration Flags */
  705.     _XfeConfigFlags(nw) = XfeConfigNone;
  706.     
  707.     /* Reset the preparation Flags */
  708.     _XfePrepareFlags(nw) = XfePrepareNone;
  709.     
  710.     /* buffer_type */
  711.     if (_XfeBufferType(nw) != _XfeBufferType(ow))
  712.     {
  713.         _XfeBufferType(nw) = _XfeBufferType(ow);
  714.     
  715.         _XfeWarning(nw,MESSAGE7);
  716.     }
  717.     
  718.     /* preferred_height */
  719.     if (_XfePreferredHeight(nw) != _XfePreferredHeight(ow))
  720.     {
  721.         _XfePreferredHeight(nw) = _XfePreferredHeight(ow);
  722.     
  723.         _XfeWarning(nw,MESSAGE2);
  724.     }
  725.     
  726.     /* preferred_width */
  727.     if (_XfePreferredWidth(nw) != _XfePreferredWidth(ow))
  728.     {
  729.         _XfePreferredWidth(nw) = _XfePreferredWidth(ow);
  730.     
  731.         _XfeWarning(nw,MESSAGE3);
  732.     }
  733.     
  734.     /* pointer_inside */
  735.     if (_XfePointerInside(nw) != _XfePointerInside(ow))
  736.     {
  737.         _XfePointerInside(nw) = _XfePointerInside(ow);
  738.     
  739.         _XfeWarning(nw,MESSAGE4);
  740.     }
  741.     
  742.     /* num_popups */
  743.     if (_XfeNumPopups(nw) != _XfeNumPopups(ow))
  744.     {
  745.         _XfeNumPopups(nw) = _XfeNumPopups(ow);
  746.     
  747.         _XfeWarning(nw,MESSAGE5);
  748.     }
  749.     
  750.     /* popup_list */
  751.     if (_XfePopupList(nw) != _XfePopupList(ow))
  752.     {
  753.         _XfePopupList(nw) = _XfePopupList(ow);
  754.     
  755.         _XfeWarning(nw,MESSAGE6);
  756.     }
  757.  
  758.     /* resize_width */
  759.     if (_XfeUsePreferredWidth(nw) != _XfeUsePreferredWidth(ow))
  760.     {
  761.         if(_XfeUsePreferredWidth(nw))
  762.         {
  763.             _XfeConfigFlags(nw) |= (XfeConfigLayout|
  764.                                     XfeConfigGeometry|
  765.                                     XfeConfigExpose);
  766.         }
  767.     }
  768.  
  769.     /* resize_height */
  770.     if (_XfeUsePreferredHeight(nw) != _XfeUsePreferredHeight(ow))
  771.     {
  772.         if(_XfeUsePreferredHeight(nw))
  773.         {
  774.             _XfeConfigFlags(nw) |= (XfeConfigLayout|
  775.                                     XfeConfigGeometry|
  776.                                     XfeConfigExpose);
  777.         }
  778.     }
  779.     
  780.     /* height */
  781.     if (_XfeHeight(nw) != _XfeHeight(ow))
  782.     {
  783.         /* if resize_heigh is True, we dont allow width changes */
  784.         if (_XfeUsePreferredHeight(nw)) 
  785.         {
  786.             _XfeHeight(nw) = _XfeHeight(ow);
  787.         }
  788.         else
  789.         {
  790.             _XfeConfigFlags(nw) |= (XfeConfigLayout|XfeConfigExpose);
  791.         }
  792.     }
  793.     
  794.     /* width */
  795.     if (_XfeWidth(nw) != _XfeWidth(ow))
  796.     {
  797.         /* if resize_width is True, we dont allow width changes */
  798.         if (_XfeUsePreferredWidth(nw)) 
  799.         {
  800.             _XfeWidth(nw) = _XfeWidth(ow);
  801.         }
  802.         else
  803.         {
  804.             _XfeConfigFlags(nw) |= (XfeConfigLayout|XfeConfigExpose);
  805.         }
  806.     }
  807.     
  808.     /* cursor */
  809.     if (_XfeCursor(nw) != _XfeCursor(ow))
  810.     {
  811.         /* If the new cursor is good, define it */
  812.         if (_XfeCursorGood(_XfeCursor(nw)))
  813.         {
  814.             XfeCursorDefine(nw,_XfeCursor(nw));
  815.         }
  816.         else
  817.         {
  818.             XfeCursorUndefine(nw);
  819.         }
  820.     }
  821.     
  822.     /* Changes that affect the layout and geometry */
  823.     if ((_XfeHighlightThickness(nw)    != _XfeHighlightThickness(ow)) ||
  824.         (_XfeMarginTop(nw)        != _XfeMarginTop(ow)) ||
  825.         (_XfeMarginBottom(nw)        != _XfeMarginBottom(ow)) ||
  826.         (_XfeMarginLeft(nw)        != _XfeMarginLeft(ow)) ||
  827.         (_XfeMarginRight(nw)        != _XfeMarginRight(ow)) ||       
  828.         (_XfeShadowThickness(nw)        != _XfeShadowThickness(ow)) ||
  829.         (_XfeUnitType(nw)            != _XfeUnitType(ow)))
  830.     {
  831.         _XfeConfigFlags(nw) |= (XfeConfigLayout|XfeConfigGeometry|XfeConfigExpose);
  832.     }
  833.     
  834.     /* shadow_type */
  835.     if (_XfeShadowType(nw) != _XfeShadowType(ow))
  836.     {
  837.         /* Make sure the new shadow type is ok */
  838.         XfeRepTypeCheck(nw,XmRShadowType,&_XfeShadowType(nw),XfeDEFAULT_SHADOW_TYPE);
  839.     
  840.         _XfeConfigFlags(nw) |= XfeConfigExpose;
  841.     }
  842.     
  843.     /* sensitive */
  844.     if (_XfeSensitive(nw) != _XfeSensitive(ow))
  845.     {
  846.         _XfeConfigFlags(nw) |= XfeConfigExpose;
  847.     }
  848.  
  849.     /* pretend_sensitive */
  850.     if (_XfeIsSensitive(nw) != _XfeIsSensitive(ow))
  851.     {
  852.         _XfeConfigFlags(nw) |= XfeConfigExpose;
  853.     }
  854.     
  855.     /* background_pixel or background_pixmap */
  856.     if (((_XfeBackgroundPixel(nw) != _XfeBackgroundPixel(ow)) ||
  857.          (_XfeBackgroundPixmap(nw) != _XfeBackgroundPixmap(ow))) &&
  858.         (_XfeBufferType(nw) != XmBUFFER_NONE))
  859.     {
  860.         /* Release the old background GC */
  861.         _XfePrimitiveReleaseBackgroundGC(nw);
  862.         
  863.         /* Allocate the new background GC */
  864.         _XfePrimitiveAllocateBackgroundGC(nw);
  865.     }
  866.     
  867.     return _XfePrimitiveChainSetValues(ow,rw,nw,xfePrimitiveWidgetClass);
  868. }
  869. /*----------------------------------------------------------------------*/
  870.  
  871. /*----------------------------------------------------------------------*/
  872. /*                                                                        */
  873. /* XmPrimitive Extension Methods                                        */
  874. /*                                                                        */
  875. /*----------------------------------------------------------------------*/
  876. static Boolean
  877. WidgetDisplayRect(Widget w,XRectangle *rect)
  878. {
  879.     rect->x    = _XfeRectX(w);
  880.     rect->y    = _XfeRectY(w);
  881.     rect->height = _XfeRectHeight(w);
  882.     rect->width    = _XfeRectWidth(w);
  883.  
  884.     return (rect->width && rect->height);
  885. }
  886. /*----------------------------------------------------------------------*/
  887.  
  888. /*----------------------------------------------------------------------*/
  889. /*                                                                        */
  890. /* XfePrimitive Class Methods                                            */
  891. /*                                                                        */
  892. /*----------------------------------------------------------------------*/
  893. static void
  894. InitializePostHook(Widget rw,Widget nw)
  895. {
  896.     /* Set preparation flag so that all components get prepared */
  897.     _XfePrepareFlags(nw) = XfePrepareAll;
  898.     
  899.     /* Prepare the Widget */
  900.     _XfePrimitivePrepareComponents(nw,_XfePrepareFlags(nw));
  901.  
  902.     /* Obtain the preferred dimensions for the first time. */
  903.     _XfePrimitivePreferredGeometry(nw,
  904.                                    &_XfePreferredWidth(nw),
  905.                                    &_XfePreferredHeight(nw));
  906.  
  907.     /* Set the new dimensions */
  908.     _XfeWidth(nw)  = GetWidth(nw);
  909.  
  910.     _XfeHeight(nw) = GetHeight(nw);
  911.  
  912.     /* Update the widget rect */
  913.     _XfePrimitiveUpdateRect(nw);
  914.     
  915.     /* Layout the Widget */
  916.     _XfePrimitiveLayoutComponents(nw);
  917.     
  918.     switch(_XfeBufferType(nw))
  919.     {
  920.         /* No buffer: nothing */
  921.     case XmBUFFER_NONE:
  922.         break;
  923.     
  924.         /* Single buffer: update the buffer size and contents */
  925.     case XmBUFFER_PRIVATE:
  926.         BufferUpdate(nw);
  927.         _XfePrimitiveDrawEverything(nw,NULL,NULL);
  928.         break;
  929.     
  930.     /* Multiple buffer: update the buffer size only */
  931.     case XmBUFFER_SHARED:
  932.         BufferUpdate(nw);
  933.         break;
  934.     }
  935.     
  936.     /* Dont need to prepare components any more */
  937.     _XfePrepareFlags(nw) = XfePrepareNone;
  938. }
  939. /*----------------------------------------------------------------------*/
  940. static Boolean
  941. SetValuesPostHook(Widget ow,Widget rw,Widget nw)
  942. {
  943.     Boolean result = False;
  944.  
  945.     /* Prepare the widget components if needed */
  946.     if (_XfePrepareFlags(nw))
  947.     {
  948.         _XfePrimitivePrepareComponents(nw,_XfePrepareFlags(nw));
  949.     }
  950.     
  951.     /* Update the widget's geometry if needed */
  952.     if (_XfeConfigFlags(nw) & XfeConfigGeometry)
  953.     {
  954.         /* Obtain the preferred dimensions */
  955.         _XfePrimitivePreferredGeometry(nw,
  956.                                        &_XfePreferredWidth(nw),
  957.                                        &_XfePreferredHeight(nw));
  958.  
  959.         /* Set the new dimensions */
  960.         _XfeWidth(nw)  = GetWidth(nw);
  961.  
  962.         _XfeHeight(nw) = GetHeight(nw);
  963.     }
  964.     
  965.     /* Update the widget rect */
  966.     _XfePrimitiveUpdateRect(nw);
  967.     
  968.     /* Layout the Widget if needed */
  969.     if (_XfeConfigFlags(nw) & XfeConfigLayout)
  970.     {
  971.         _XfePrimitiveLayoutComponents(nw);
  972.  
  973.         switch(_XfeBufferType(nw))
  974.         {
  975.             /* No buffer: nothing */
  976.         case XmBUFFER_NONE:
  977.             break;
  978.         
  979.             /* Single buffer: update the buffer size and contents */
  980.         case XmBUFFER_PRIVATE:
  981.             BufferUpdate(nw);
  982.             _XfePrimitiveDrawEverything(nw,NULL,NULL);
  983.             break;
  984.         
  985.             /* Multiple buffer: update the buffer size only */
  986.         case XmBUFFER_SHARED:
  987.             BufferUpdate(nw);
  988.             break;
  989.         }
  990.     }
  991.     
  992.     /* Draw everything (into the buffer) */
  993.     if (_XfeBufferType(nw) != XmBUFFER_NONE)
  994.     {
  995.         if ((_XfeConfigFlags(nw) & XfeConfigLayout) || 
  996.             (_XfeConfigFlags(nw) & XfeConfigExpose))
  997.         {
  998.             /* Redraw the buffer */
  999.             _XfePrimitiveDrawEverything(nw,NULL,NULL);
  1000.         
  1001.             /* Draw the buffer onto the window */
  1002.             XfeExpose(nw,NULL,NULL);
  1003.         }
  1004.     }
  1005.     else
  1006.     {
  1007.         result = (_XfeConfigFlags(nw) & XfeConfigExpose);
  1008.     }
  1009.  
  1010.     return result;
  1011. }
  1012. /*----------------------------------------------------------------------*/
  1013. static void
  1014. PreferredGeometry(Widget w,Dimension *width,Dimension *height)
  1015. {
  1016.     *width  = _XfeOffsetLeft(w) + _XfeOffsetRight(w);
  1017.     *height = _XfeOffsetTop(w)  + _XfeOffsetBottom(w);
  1018. }
  1019. /*----------------------------------------------------------------------*/
  1020. static void
  1021. MinimumGeometry(Widget w,Dimension *width,Dimension *height)
  1022. {
  1023.     *width  = _XfeOffsetLeft(w) + _XfeOffsetRight(w);
  1024.     *height = _XfeOffsetTop(w)  + _XfeOffsetBottom(w);
  1025. }
  1026. /*----------------------------------------------------------------------*/
  1027. static void
  1028. DrawShadow(Widget w,XEvent * event,Region region,XRectangle * clip_rect)
  1029. {
  1030.     /* Draw the shadow */
  1031.     _XmDrawShadows(XtDisplay(w),
  1032.                    _XfePrimitiveDrawable(w),
  1033.                    _XfeTopShadowGC(w),_XfeBottomShadowGC(w),
  1034.                    _XfeHighlightThickness(w),
  1035.                    _XfeHighlightThickness(w),
  1036.                    _XfeWidth(w) - 2 * _XfeHighlightThickness(w),
  1037.                    _XfeHeight(w) - 2 * _XfeHighlightThickness(w),
  1038.                    _XfeShadowThickness(w),
  1039.                    _XfeShadowType(w));
  1040. }
  1041. /*----------------------------------------------------------------------*/
  1042. static void
  1043. UpdateRect(Widget w)
  1044. {
  1045.     /* Assign the rect coordinates */
  1046.     XfeRectSet(&_XfeWidgetRect(w),
  1047.                
  1048.                _XfeOffsetLeft(w),
  1049.                
  1050.                _XfeOffsetTop(w),
  1051.                
  1052.                _XfeWidth(w) - _XfeOffsetLeft(w) - _XfeOffsetRight(w),
  1053.                
  1054.                _XfeHeight(w) - _XfeOffsetTop(w) - _XfeOffsetBottom(w));
  1055. }
  1056. /*----------------------------------------------------------------------*/
  1057.  
  1058. /*----------------------------------------------------------------------*/
  1059. /*                                                                        */
  1060. /* XfePrimitive Buffer Pixmap functions                                    */
  1061. /*                                                                        */
  1062. /*----------------------------------------------------------------------*/
  1063. static void
  1064. BufferAllocate(Widget w)
  1065. {
  1066.     assert( _XfeBufferType(w) != XmBUFFER_NONE );
  1067.  
  1068.     switch(_XfeBufferType(w))
  1069.     {
  1070.         /* Single buffer: allocate a buffer big enough for widget */
  1071.     case XmBUFFER_PRIVATE:
  1072.  
  1073.         _XfeBufferPixmap(w) = XCreatePixmap(XtDisplay(w),
  1074.                                             DefaultRootWindow(XtDisplay(w)),
  1075.                                             _XfeWidth(w),
  1076.                                             _XfeHeight(w),
  1077.                                             _XfeDepth(w));
  1078.  
  1079.  
  1080. #if 0
  1081.         printf("%s: Allocating a private buffer at (%d,%d)\n",
  1082.                XtName(w),
  1083.                _XfeWidth(w),_XfeHeight(w));
  1084. #endif
  1085.  
  1086.         break;
  1087.  
  1088.         /* Multiple buffer: ask the buffer manager for a buffer */
  1089.     case XmBUFFER_SHARED:
  1090.  
  1091. #if 0
  1092.         printf("%s: Allocating a shared buffer at (%d,%d)\n",
  1093.                XtName(w),
  1094.                _XfeWidth(w),_XfeHeight(w));
  1095. #endif
  1096.  
  1097.         _XfeBufferPixmap(w) = _XfePixmapBufferAllocate(w);
  1098.  
  1099.         break;
  1100.     }
  1101.  
  1102. }
  1103. /*----------------------------------------------------------------------*/
  1104. static void
  1105. BufferFree(Widget w)
  1106. {
  1107.     /*if (_XfeBufferType(w) != XmBUFFER_NONE );*/
  1108.  
  1109.     switch(_XfeBufferType(w))
  1110.     {
  1111.         /* Single buffer: Free the buffer pixmap only if needed */
  1112.     case XmBUFFER_PRIVATE:
  1113.  
  1114.         if (_XfePixmapGood(_XfeBufferPixmap(w)))
  1115.         {
  1116.             XFreePixmap(XtDisplay(w),_XfeBufferPixmap(w));
  1117.         }
  1118.  
  1119.         break;
  1120.  
  1121.         /* Multiple buffer: release the shared buffer */
  1122.     case XmBUFFER_SHARED:
  1123.  
  1124.         /*_XfePixmapBufferRelease(w,_XfeBufferPixmap(w));*/
  1125.  
  1126.         break;
  1127.  
  1128.         /* Nothing */
  1129.     case XmBUFFER_NONE:
  1130.         break;
  1131.     }
  1132. }
  1133. /*----------------------------------------------------------------------*/
  1134. static void
  1135. BufferUpdate(Widget w)
  1136. {
  1137.     assert( _XfeBufferType(w) != XmBUFFER_NONE );
  1138.  
  1139.     BufferFree(w);
  1140.     BufferAllocate(w);
  1141. }
  1142. /*----------------------------------------------------------------------*/
  1143.  
  1144. /*----------------------------------------------------------------------*/
  1145. /*                                                                        */
  1146. /* Misc XfePrimitive functions                                            */
  1147. /*                                                                        */
  1148. /*----------------------------------------------------------------------*/
  1149.  
  1150. /*
  1151.  * The preferred width is computed as follows.  The criteria is listed in
  1152.  * order of precedence.
  1153.  *
  1154.  *  min_width        := (2 * shadow + 2 * highlight) -    this is the min
  1155.  *                                                        width set by the
  1156.  *                                                        XmPrimitive class'
  1157.  *                                                        Initialize()
  1158.  *
  1159.  *  default_width    := XfeDEFAULT_PREFERRED_WIDTH -        Defined to 0 (zero)
  1160.  *
  1161.  *
  1162.  * 1.    If (XmNusePreferredWidth == true) then force the preferred width
  1163.  *
  1164.  * 2.    If (XmNusePreferredWidth == false) and 
  1165.  *        (width == XfeDEFAULT_PREFERRED_WIDTH) or (width <= min_width)
  1166.  *        then force the preferred width.
  1167.  *
  1168.  * 3.    If (XmNusePreferredWidth == false) and (width > min_width) then
  1169.  *        use the dimension given by w->core.width;
  1170.  *
  1171.  * The same logic applies to the height.  This assumes the preferred 
  1172.  * width is something reasonable; but that is up to the subclasses.
  1173.  *
  1174.  */
  1175.  
  1176. static Dimension
  1177. GetWidth(Widget w)
  1178. {
  1179.     Dimension    min_width;
  1180.     Dimension    width;
  1181.  
  1182.     /* Compute the min possible width */
  1183.     min_width = 2 * _XfeHighlightThickness(w) + 2 * _XfeShadowThickness(w);
  1184.  
  1185.     /* A reasonable preferred width is needed */
  1186.     assert( _XfePreferredWidth(w) > 0 );
  1187.     assert( _XfePreferredWidth(w) >= min_width );
  1188.  
  1189.     /* Force the preferred width if needed */
  1190.     if (_XfeUsePreferredWidth(w) || 
  1191.         (_XfeWidth(w) == XfeDEFAULT_PREFERRED_WIDTH) ||
  1192.         (_XfeWidth(w) <= min_width))
  1193.     {
  1194.         width = _XfePreferredWidth(w);
  1195.     }
  1196.     else
  1197.     {
  1198.         width = _XfeWidth(w);
  1199.     }
  1200.  
  1201.     return width;
  1202. }
  1203. /*----------------------------------------------------------------------*/
  1204. static Dimension
  1205. GetHeight(Widget w)
  1206. {
  1207.     Dimension    min_height;
  1208.     Dimension    height;
  1209.  
  1210.     /* Compute the min possible height */
  1211.     min_height = 2 * _XfeHighlightThickness(w) + 2 * _XfeShadowThickness(w);
  1212.  
  1213.     /* A reasonable preferred height is needed */
  1214.     assert( _XfePreferredHeight(w) > 0 );
  1215.     assert( _XfePreferredHeight(w) >= min_height );
  1216.  
  1217.     /* Force the preferred height if needed */
  1218.     if (_XfeUsePreferredHeight(w) || 
  1219.         (_XfeHeight(w) == XfeDEFAULT_PREFERRED_HEIGHT) ||
  1220.         (_XfeHeight(w) <= min_height))
  1221.     {
  1222.         height = _XfePreferredHeight(w);
  1223.     }
  1224.     else
  1225.     {
  1226.         height = _XfeHeight(w);
  1227.     }
  1228.  
  1229.     return height;
  1230. }
  1231. /*----------------------------------------------------------------------*/
  1232.  
  1233. /*----------------------------------------------------------------------*/
  1234. /*                                                                        */
  1235. /* XfePrimitive Method invocation functions                                */
  1236. /*                                                                        */
  1237. /*----------------------------------------------------------------------*/
  1238. void
  1239. _XfePrimitivePreferredGeometry(Widget w,Dimension *width,Dimension *height)
  1240. {
  1241.     XfePrimitiveWidgetClass pc = (XfePrimitiveWidgetClass) XtClass(w);
  1242.  
  1243.     if (pc->xfe_primitive_class.preferred_geometry)
  1244.     {
  1245.         (*pc->xfe_primitive_class.preferred_geometry)(w,width,height);
  1246.     }
  1247.  
  1248.     /* Make sure preferred width is greater than zero */
  1249.     if (*width == 0)
  1250.     {
  1251.         *width = XfePRIMITIVE_DEFAULT_WIDTH;
  1252.     }
  1253.  
  1254.     /* Make sure preferred height is greater than zero */
  1255.     if (*height == 0)
  1256.     {
  1257.         *height = XfePRIMITIVE_DEFAULT_HEIGHT;
  1258.     }
  1259. }
  1260. /*----------------------------------------------------------------------*/
  1261. void
  1262. _XfePrimitiveMinimumGeometry(Widget w,Dimension *width,Dimension *height)
  1263. {
  1264.     XfePrimitiveWidgetClass pc = (XfePrimitiveWidgetClass) XtClass(w);
  1265.  
  1266.     if (pc->xfe_primitive_class.minimum_geometry)
  1267.     {
  1268.         (*pc->xfe_primitive_class.minimum_geometry)(w,width,height);
  1269.     }
  1270.  
  1271.     /* Make sure preferred width is greater than zero */
  1272.     if (*width == 0)
  1273.     {
  1274.         *width = XfePRIMITIVE_DEFAULT_WIDTH;
  1275.     }
  1276.  
  1277.     /* Make sure preferred height is greater than zero */
  1278.     if (*height == 0)
  1279.     {
  1280.         *height = XfePRIMITIVE_DEFAULT_HEIGHT;
  1281.     }
  1282. }
  1283. /*----------------------------------------------------------------------*/
  1284. void
  1285. _XfePrimitivePrepareComponents(Widget w,int flags)
  1286. {
  1287.     WidgetClass                    cc;
  1288.     XfePrimitiveWidgetClass        pc;
  1289.     Cardinal                    i;
  1290.     Cardinal                    count;
  1291.  
  1292.     /* Someone has to be nuts to have more than 32 subclasses... */
  1293.     static XfePrepareProc        proc_table[32];
  1294.  
  1295.     /* Traverse all classes until we find XmPrimitive */
  1296.     for (cc = XtClass(w),count = 0; 
  1297.          cc != xmPrimitiveWidgetClass; 
  1298.          cc = cc->core_class.superclass)
  1299.     {
  1300.         pc = (XfePrimitiveWidgetClass) cc;
  1301.  
  1302.         /* Add the method to the table as long as it is not NULL */
  1303.         if (pc->xfe_primitive_class.prepare_components)
  1304.         {
  1305.             proc_table[count++] = pc->xfe_primitive_class.prepare_components;
  1306.         }
  1307.     }
  1308.  
  1309.     /* Invoke the methods in reverse order */
  1310.     for (i = count; i; i--)
  1311.     {
  1312.         XfePrepareProc proc = proc_table[i - 1];
  1313.  
  1314.         /* Invoke the prepare components method for this class */
  1315.         (*proc)(w,flags);
  1316.     }
  1317. }
  1318. /*----------------------------------------------------------------------*/
  1319. void
  1320. _XfePrimitiveUpdateRect(Widget w)
  1321. {
  1322.     XfePrimitiveWidgetClass pc = (XfePrimitiveWidgetClass) XtClass(w);
  1323.  
  1324.     if (pc->xfe_primitive_class.update_rect)
  1325.     {
  1326.         (*pc->xfe_primitive_class.update_rect)(w);
  1327.     }
  1328. }
  1329. /*----------------------------------------------------------------------*/
  1330. void
  1331. _XfePrimitiveLayoutComponents(Widget w)
  1332. {
  1333.     XfePrimitiveWidgetClass pc = (XfePrimitiveWidgetClass) XtClass(w);
  1334.  
  1335.     if (pc->xfe_primitive_class.layout_components)
  1336.     {
  1337.         (*pc->xfe_primitive_class.layout_components)(w);
  1338.     }
  1339. }
  1340. /*----------------------------------------------------------------------*/
  1341. void
  1342. _XfePrimitiveDrawBackground(Widget    w,
  1343.                             XEvent *    event,
  1344.                             Region    region,
  1345.                             XRectangle *    clip_rect)
  1346. {
  1347.     XfePrimitiveWidgetClass    pc = (XfePrimitiveWidgetClass) XtClass(w);
  1348.  
  1349.     if (pc->xfe_primitive_class.draw_background)
  1350.     {
  1351.         (*pc->xfe_primitive_class.draw_background)(w,event,region,clip_rect);
  1352.     }
  1353. }
  1354. /*----------------------------------------------------------------------*/
  1355. void
  1356. _XfePrimitiveDrawComponents(Widget    w,
  1357.                             XEvent *    event,
  1358.                             Region    region,
  1359.                             XRectangle *    clip_rect)
  1360. {
  1361.     XfePrimitiveWidgetClass    pc = (XfePrimitiveWidgetClass) XtClass(w);
  1362.  
  1363.     if (pc->xfe_primitive_class.draw_components)
  1364.     {
  1365.         (*pc->xfe_primitive_class.draw_components)(w,event,region,clip_rect);
  1366.     }
  1367. }
  1368. /*----------------------------------------------------------------------*/
  1369. void
  1370. _XfePrimitiveDrawShadow(Widget        w,
  1371.                         XEvent *        event,
  1372.                         Region        region,
  1373.                         XRectangle *    rect)
  1374. {
  1375.     XfePrimitiveWidgetClass pc = (XfePrimitiveWidgetClass) XtClass(w);
  1376.  
  1377.     if (pc->xfe_primitive_class.draw_shadow)
  1378.     {
  1379.         (*pc->xfe_primitive_class.draw_shadow)(w,event,region,rect);
  1380.     }
  1381. }
  1382. /*----------------------------------------------------------------------*/
  1383. void
  1384. _XfePrimitiveBorderHighlight(Widget w)
  1385. {
  1386.     XmPrimitiveWidgetClass pc = (XmPrimitiveWidgetClass) XtClass(w);
  1387.  
  1388.     if (pc->primitive_class.border_highlight)
  1389.     {
  1390.         (*pc->primitive_class.border_highlight)(w);
  1391.     }
  1392. }
  1393. /*----------------------------------------------------------------------*/
  1394. void
  1395. _XfePrimitiveBorderUnhighlight(Widget w)
  1396. {
  1397.     XmPrimitiveWidgetClass pc = (XmPrimitiveWidgetClass) XtClass(w);
  1398.  
  1399.     if (pc->primitive_class.border_unhighlight)
  1400.     {
  1401.         (*pc->primitive_class.border_unhighlight)(w);
  1402.     }
  1403. }
  1404. /*----------------------------------------------------------------------*/
  1405.  
  1406.  
  1407. /*----------------------------------------------------------------------*/
  1408. /*                                                                        */
  1409. /* Private XfePrimitive functions                                        */
  1410. /*                                                                        */
  1411. /*----------------------------------------------------------------------*/
  1412. /* extern */ void
  1413. _XfePrimitiveChainInitialize(Widget rw,Widget nw,WidgetClass wc)
  1414. {
  1415.     assert( nw != NULL );
  1416.  
  1417.     if (XtClass(nw) == wc)
  1418.     {
  1419.         InitializePostHook(rw,nw);
  1420.     }
  1421. }
  1422. /*----------------------------------------------------------------------*/
  1423. /* extern */ Boolean
  1424. _XfePrimitiveChainSetValues(Widget ow,Widget rw,Widget nw,WidgetClass wc)
  1425. {
  1426.     assert( nw != NULL );
  1427.  
  1428.     if (XtClass(nw) == wc)
  1429.     {
  1430.         return SetValuesPostHook(ow,rw,nw);
  1431.     }
  1432.  
  1433.     return False;
  1434. }
  1435. /*----------------------------------------------------------------------*/
  1436. Drawable
  1437. _XfePrimitiveDrawable(Widget w)
  1438. {
  1439.     Drawable d = None;
  1440.  
  1441.     switch(_XfeBufferType(w))
  1442.     {
  1443.     case XmBUFFER_NONE:
  1444.         d = _XfeWindow(w);
  1445.         break;
  1446.  
  1447.     case XmBUFFER_PRIVATE:
  1448.         d = _XfeBufferPixmap(w);
  1449.         break;
  1450.  
  1451.     case XmBUFFER_SHARED:
  1452.         d = _XfePixmapBufferAccess();
  1453.         break;
  1454.     }
  1455.  
  1456.     return d;
  1457. }
  1458. /*----------------------------------------------------------------------*/
  1459. void
  1460. _XfePrimitiveDrawEverything(Widget w,XEvent * event,Region region)
  1461. {
  1462.     static XRectangle rect;
  1463.  
  1464.     /* Clear the buffer background if needed */
  1465.     if (_XfeBufferType(w) != XmBUFFER_NONE)
  1466.     {
  1467.         _XfePrimitiveClearBackground(w);
  1468.     }
  1469.  
  1470.     /* Draw Background */ 
  1471.     XfeRectSet(&rect,
  1472.                _XfeRectX(w) - _XfeMarginLeft(w),
  1473.                _XfeRectY(w) - _XfeMarginTop(w),
  1474.                _XfeRectWidth(w) + _XfeMarginLeft(w) + _XfeMarginRight(w),
  1475.                _XfeRectHeight(w) + _XfeMarginTop(w) + _XfeMarginBottom(w));
  1476.     
  1477.     _XfePrimitiveDrawBackground(w,event,region,&rect);
  1478.     
  1479.     /* Draw -or Erase the Widget's highlight if needed */
  1480.     if (_XfeHighlighted(w) && _XfeHighlightThickness(w))
  1481.     {
  1482.         _XfePrimitiveBorderHighlight(w);
  1483.     }
  1484.     else
  1485.     {
  1486.         _XfePrimitiveBorderUnhighlight(w);
  1487.     }
  1488.     
  1489.     /* Draw Shadow */ 
  1490.     _XfePrimitiveDrawShadow(w,event,region,&_XfeWidgetRect(w));
  1491.     
  1492.     /* Draw Components */ 
  1493.     _XfePrimitiveDrawComponents(w,event,region,&_XfeWidgetRect(w));
  1494. }
  1495. /*----------------------------------------------------------------------*/
  1496. void
  1497. _XfePrimitiveClearBackground(Widget w)
  1498. {
  1499.     /* Clear the widget background including margins */
  1500.     if (_XfeBufferType(w) == XmBUFFER_NONE)
  1501.     {
  1502.         XClearArea(XtDisplay(w),_XfeWindow(w),
  1503.                    _XfeHighlightThickness(w),_XfeHighlightThickness(w),
  1504.                    _XfeWidth(w) - 2 * _XfeHighlightThickness(w),
  1505.                    _XfeHeight(w) - 2 * _XfeHighlightThickness(w),
  1506.                    False);
  1507.  
  1508.         /*XClearWindow(XtDisplay(w),_XfeWindow(w));*/
  1509.     }
  1510.     else
  1511.     {
  1512.         XFillRectangle(XtDisplay(w),
  1513.                        _XfePrimitiveDrawable(w),
  1514.                        _XfeBackgroundGC(w),
  1515.                        0,0,
  1516.                        _XfeWidth(w),_XfeHeight(w));
  1517.     }
  1518. }
  1519. /*----------------------------------------------------------------------*/
  1520. void
  1521. _XfePrimitiveAllocateBackgroundGC(Widget w)
  1522. {
  1523.     /* Make sure the background gc gets allocated only once */
  1524.     if (_XfeBackgroundGC(w))
  1525.     {
  1526.         return;
  1527.     }
  1528.  
  1529.     if (_XfePixmapGood(_XfeBackgroundPixmap(w)))
  1530.     {
  1531.         _XfeBackgroundGC(w) = XfeAllocateTileGc(w,_XfeBackgroundPixmap(w));
  1532.     }
  1533.     else
  1534.     {
  1535.         _XfeBackgroundGC(w) = XfeAllocateColorGc(w,_XfeBackgroundPixel(w),
  1536.                                                  None,True);
  1537.     }
  1538. }
  1539. /*----------------------------------------------------------------------*/
  1540. void
  1541. _XfePrimitiveReleaseBackgroundGC(Widget w)
  1542. {
  1543.     /* Make sure the gc has been allocated */
  1544.     if (!_XfeBackgroundGC(w))
  1545.     {
  1546.         return;
  1547.     }
  1548.  
  1549.     /* Free the background gc */
  1550.     XtReleaseGC(w,_XfeBackgroundGC(w));
  1551. }
  1552. /*----------------------------------------------------------------------*/
  1553. void
  1554. _XfePrimitiveDrawBuffer(Widget w,XEvent * event,Region region)
  1555. {
  1556.     XCopyArea(XtDisplay(w),
  1557.               _XfePrimitiveDrawable(w),
  1558.               _XfeWindow(w),
  1559.               _XfeBackgroundGC(w),
  1560.               _XfeHighlightThickness(w),_XfeHighlightThickness(w),
  1561.               _XfeWidth(w) - 2 * _XfeHighlightThickness(w),
  1562.               _XfeHeight(w) - 2 * _XfeHighlightThickness(w),
  1563.               _XfeHighlightThickness(w),_XfeHighlightThickness(w));
  1564. }
  1565. /*----------------------------------------------------------------------*/
  1566.  
  1567. /*----------------------------------------------------------------------*/
  1568. /*                                                                        */
  1569. /* XfePrimitive Action Procedures                                        */
  1570. /*                                                                        */
  1571. /*----------------------------------------------------------------------*/
  1572. /* extern */ void
  1573. _XfePrimitiveEnter(Widget w,XEvent * event,char ** params,Cardinal * nparams)
  1574. {
  1575.     _XfePointerInside(w) = True;
  1576.  
  1577.     /* Make sure we are not pretending to be insensitive */
  1578.     if (!_XfeIsSensitive(w))
  1579.     {
  1580.         return;
  1581.     }
  1582.  
  1583.     /* Call the XmPrimitive Enter() action */
  1584.     _XmPrimitiveEnter(w,event,params,nparams);
  1585.  
  1586.     /* Define the cursor if needed */
  1587.     if (_XfeCursorGood(_XfeCursor(w)))
  1588.     {
  1589.         XfeCursorDefine(w,_XfeCursor(w));
  1590.     }
  1591.  
  1592.     /* Call enter callbacks */
  1593.     _XfeInvokeCallbacks(w,_XfeEnterCallbacks(w),XmCR_ENTER,event,False);
  1594. }
  1595. /*----------------------------------------------------------------------*/
  1596. /* extern */ void
  1597. _XfePrimitiveLeave(Widget w,XEvent * event,char ** params,Cardinal * nparams)
  1598. {
  1599.     /* Make sure the pointer is indeed inside for this action */
  1600.     if (!_XfePointerInside(w))
  1601.     {
  1602.         return;
  1603.     }
  1604.     
  1605.     _XfePointerInside(w) = False;
  1606.  
  1607.     /* Make sure we are not pretending to be insensitive */
  1608.     if (!_XfeIsSensitive(w))
  1609.     {
  1610.         return;
  1611.     }
  1612.  
  1613.     /* Call the XmPrimitive Leave() action */
  1614.     _XmPrimitiveLeave(w,event,params,nparams);
  1615.  
  1616.     /* Undefine the cursor if needed */
  1617.     if (_XfeCursorGood(_XfeCursor(w)))
  1618.     {
  1619.         XfeCursorUndefine(w);
  1620.     }
  1621.  
  1622.     /* Call leave callbacks */
  1623.     _XfeInvokeCallbacks(w,_XfeLeaveCallbacks(w),XmCR_LEAVE,event,False);
  1624. }
  1625. /*----------------------------------------------------------------------*/
  1626. /* extern */ void
  1627. _XfePrimitiveFocus(Widget w,XEvent * event,char ** params,Cardinal * nparams)
  1628. {
  1629.     /* Make sure we are not pretending to be insensitive */
  1630.     if (!_XfeIsSensitive(w))
  1631.     {
  1632.         return;
  1633.     }
  1634.  
  1635.     XmProcessTraversal(w,XmTRAVERSE_CURRENT);
  1636.  
  1637.     /* Invoke Focus Callbacks */
  1638.     _XfeInvokeCallbacks(w,_XfeFocusCallbacks(w),XmCR_FOCUS,event,False);
  1639. }
  1640. /*----------------------------------------------------------------------*/
  1641.  
  1642. /*----------------------------------------------------------------------*/
  1643. /*                                                                        */
  1644. /* Public pretend sensitive methods                                        */
  1645. /*                                                                        */
  1646. /*----------------------------------------------------------------------*/
  1647. /* extern */ void
  1648. XfeSetPretendSensitive(Widget w,Boolean state)
  1649. {
  1650.     Arg xargs[1];
  1651.  
  1652.     assert( _XfeIsAlive(w) );
  1653.     assert( XfeIsPrimitive(w) );
  1654.  
  1655.     if (!_XfeIsAlive(w))
  1656.     {
  1657.         return;
  1658.     }
  1659.  
  1660.     /* Make sure the state is different */
  1661.     if (_XfePretendSensitive(w) == state)
  1662.     {
  1663.         return;
  1664.     }
  1665.  
  1666.     XtSetArg(xargs[0],XmNpretendSensitive,state);
  1667.  
  1668.     XtSetValues(w,xargs,1);
  1669. }
  1670. /*----------------------------------------------------------------------*/
  1671. /* extern */ Boolean
  1672. XfeIsPretendSensitive(Widget w)
  1673. {
  1674.     assert( XfeIsPrimitive(w) );
  1675.  
  1676.     if (!_XfeIsAlive(w))
  1677.     {
  1678.         return False;
  1679.     }
  1680.  
  1681.     return _XfePretendSensitive(w);
  1682. }
  1683. /*----------------------------------------------------------------------*/
  1684. /* extern */ Boolean
  1685. XfeIsSensitive(Widget w)
  1686. {
  1687.     if (!_XfeIsAlive(w))
  1688.     {
  1689.         return False;
  1690.     }
  1691.  
  1692.     if (XfeIsPrimitive(w))
  1693.     {
  1694.         return _XfeIsSensitive(w);
  1695.     }
  1696.  
  1697.     return _XfeSensitive(w);
  1698. }
  1699. /*----------------------------------------------------------------------*/
  1700.  
  1701.