home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / XfeWidgets / Xfe / MenuUtil.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  19.3 KB  |  748 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/MenuUtil.c>                                        */
  21. /* Description:    Menu/RowColum misc utilities source.                    */
  22. /* Author:        Ramiro Estrugo <ramiro@netscape.com>                    */
  23. /*                                                                        */
  24. /*----------------------------------------------------------------------*/
  25.  
  26.  
  27. #include <Xfe/XfeP.h>
  28. #include <Xfe/ManagerP.h>
  29. #include <Xfe/CascadeP.h>
  30. #include <Xfe/BmCascadeP.h>
  31. #include <Xfe/BmButtonP.h>
  32.  
  33. #include <Xm/RowColumnP.h>
  34.  
  35. #include <Xm/DisplayP.h>
  36.  
  37. #include <Xm/CascadeBGP.h>
  38. #include <Xm/CascadeBP.h>
  39.  
  40. /*----------------------------------------------------------------------*/
  41. /*                                                                        */
  42. /* Menus                                                                */
  43. /*                                                                        */
  44. /*----------------------------------------------------------------------*/
  45. /* extern */ Widget
  46. XfeCascadeGetSubMenu(Widget w)
  47. {
  48.     assert( w != NULL );
  49.     assert( (XmIsCascadeButton(w) || 
  50.              XmIsCascadeButtonGadget(w) || 
  51.              XfeIsCascade(w)) );
  52.  
  53.     if (XmIsCascadeButton(w))
  54.     {
  55.         return ((XmCascadeButtonWidget) w) -> cascade_button . submenu;
  56.     }
  57.     else if (XfeIsCascade(w))
  58.     {
  59.         return ((XfeCascadeWidget) w) -> xfe_cascade . sub_menu_id;
  60.     }
  61.  
  62.     return ((XmCascadeButtonGadget) w) -> cascade_button . submenu;
  63. }
  64. /*----------------------------------------------------------------------*/
  65. /* extern */ void
  66. XfeMenuPositionXY(Widget menu,Position x_root,Position y_root)
  67. {
  68.     XButtonPressedEvent be;
  69.  
  70.     assert( _XfeIsAlive(menu) );
  71.     assert( XmIsRowColumn(menu) );
  72.  
  73.     /* In the motif source code, only the x_root and y_root members are used */
  74.     be.x_root = x_root;
  75.     be.y_root = y_root;
  76.  
  77.     XmMenuPosition(menu,&be);
  78. }
  79. /*----------------------------------------------------------------------*/
  80. /* extern */ int
  81. XfeMenuItemPositionIndex(Widget item)
  82. {
  83.     XmRowColumnConstraintRec * rccp;
  84.  
  85.     assert( _XfeIsAlive(item) );
  86.     assert( XmIsRowColumn(_XfeParent(item)) );
  87.     assert( XtIsObject(item) );
  88.  
  89.     rccp = (XmRowColumnConstraintRec *) (item -> core . constraints);
  90.  
  91.     return (int) rccp -> row_column . position_index;
  92. }
  93. /*----------------------------------------------------------------------*/
  94. /* extern */ Widget
  95. XfeMenuItemAtPosition(Widget menu,int position)
  96. {
  97.     Widget item = NULL;
  98. #if 0
  99.     XmRowColumnConstraintRec * rccp;
  100.  
  101.     assert( _XfeIsAlive(item) );
  102.     assert( XmIsRowColumn(_XfeParent(item)) );
  103.  
  104.     rccp = (XmRowColumnConstraintRec *) (item -> core . constraints);
  105.  
  106.     return (int) rccp -> row_column . position_index;
  107. #endif
  108.  
  109.     return item;
  110. }
  111. /*----------------------------------------------------------------------*/
  112. /* extern */ Boolean
  113. XfeMenuIsFull(Widget menu)
  114. {
  115.     Dimension    screen_height;
  116.     Widget        last;
  117.  
  118.     assert( _XfeIsAlive(menu) );
  119.     assert( XmIsRowColumn(menu) );
  120.  
  121.     screen_height = XfeScreenHeight(menu);
  122.  
  123.     last = XfeChildrenGetLast(menu);
  124.  
  125.     if (!last)
  126.     {
  127.         return False;
  128.     }
  129.  
  130.     /*
  131.      * The menu is "full" if its height plus that of a potential new child
  132.      * are longer than the screen height.  Assume the new child will be
  133.      * the same height as the last child in the menu.
  134.      */
  135.     if ((_XfeHeight(menu) + (3 * _XfeHeight(last))) > XfeScreenHeight(menu))
  136.     {
  137.         return True;
  138.     }
  139.  
  140.     return False;
  141. }
  142. /*----------------------------------------------------------------------*/
  143.  
  144. /*----------------------------------------------------------------------*/
  145. /*                                                                        */
  146. /* Option menus                                                            */
  147. /*                                                                        */
  148. /*----------------------------------------------------------------------*/
  149. /* extern */ Boolean
  150. XfeMenuIsOptionMenu(Widget menu)
  151. {
  152.     return (XmIsRowColumn(menu) && (RC_Type(menu) == XmMENU_OPTION));
  153. }
  154. /*----------------------------------------------------------------------*/
  155. /* extern */ void
  156. XfeOptionMenuSetItem(Widget menu,Cardinal i)
  157. {
  158.     Widget submenu;
  159.  
  160.     assert( _XfeIsAlive(menu) );
  161.     assert( XfeMenuIsOptionMenu(menu) );
  162.  
  163.     submenu = RC_OptionSubMenu(menu);
  164.  
  165.     if (_XfeIsAlive(submenu))
  166.     {
  167.         if ((i >= 0) && (i < _XfemNumChildren(submenu)))
  168.         {
  169.             XtVaSetValues(menu,XmNmenuHistory,_XfeChildrenIndex(submenu,i),NULL);
  170.         }
  171.     }
  172. }
  173. /*----------------------------------------------------------------------*/
  174. /* extern */ int
  175. XfeOptionMenuGetItem(Widget menu)
  176. {
  177.     Cardinal    i;
  178.     Widget        submenu;
  179.  
  180.     assert( _XfeIsAlive(menu) );
  181.     assert( XfeMenuIsOptionMenu(menu) );
  182.  
  183.     submenu = RC_OptionSubMenu(menu);
  184.  
  185.     if (_XfeIsAlive(submenu))
  186.     {
  187.         for (i = 0; i < _XfemNumChildren(submenu); i++) 
  188.         {
  189.             if (_XfeChildrenIndex(submenu,i) == RC_MemWidget(menu))
  190.             {
  191.                 return (int) i;
  192.             }
  193.         }
  194.     }
  195.  
  196.     return -1;
  197. }
  198. /*----------------------------------------------------------------------*/
  199.  
  200. /*----------------------------------------------------------------------*
  201.  *
  202.  * Traverse a menu hierarchy 
  203.  *
  204.  *
  205.  *                                                                    
  206.  *----------------------------------------------------------------------*/
  207. /* extern */ Widget
  208. XfeMenuGetMoreButton(Widget menu,String more_button_name)
  209. {
  210.     Widget last;
  211.  
  212.     assert( _XfeIsAlive(menu) );
  213.     assert( XmIsRowColumn(menu) );
  214.     assert( more_button_name != NULL );
  215.  
  216.     last = XfeChildrenGetLast(menu);
  217.  
  218.     if (_XfeIsAlive(last) && 
  219.         (XmIsCascadeButton(last) || XmIsCascadeButtonGadget(last)) &&
  220.         (strcmp(XtName(last),more_button_name) == 0))
  221.     {
  222.         return last;
  223.     }
  224.  
  225.     return NULL;
  226. }
  227. /*----------------------------------------------------------------------*/
  228. /* extern */ Widget
  229. XfeMenuFindLastMoreMenu(Widget menu,String more_button_name)
  230. {
  231.     Widget more_button;
  232.     Widget submenu;
  233.  
  234.     assert( _XfeIsAlive(menu) );
  235.     assert( XmIsRowColumn(menu) );
  236.     assert( more_button_name != NULL );
  237.  
  238.     /* First check if this menu is not full */
  239.     if (!XfeMenuIsFull(menu))
  240.     {
  241.         return menu;
  242.     }
  243.  
  244.     /* Look for the "More..." button */
  245.     more_button = XfeMenuGetMoreButton(menu,more_button_name);
  246.  
  247.     /* If no more button is found, then this menu is the last one */
  248.     if (!more_button)
  249.     {
  250.         return menu;
  251.     }
  252.  
  253.     /* Get the submenu for the more button */
  254.     submenu = XfeCascadeGetSubMenu(more_button);
  255.  
  256.     assert( _XfeIsAlive(submenu) );
  257.  
  258.     /* Recurse into the submenu */
  259.     return XfeMenuFindLastMoreMenu(submenu,more_button_name);
  260. }
  261. /*----------------------------------------------------------------------*/
  262.  
  263. /*----------------------------------------------------------------------*/
  264. /*                                                                        */
  265. /* Display grabbed access.                                                */
  266. /*                                                                        */
  267. /*----------------------------------------------------------------------*/
  268. /* extern */ Boolean
  269. XfeDisplayIsUserGrabbed(Widget w)
  270. {
  271.     XmDisplayRec *    xm_display;
  272.  
  273.     assert( _XfeIsAlive(w) );
  274.  
  275.     xm_display = (XmDisplayRec *) XmGetXmDisplay(XtDisplay(w));
  276.  
  277.     assert( xm_display != NULL );
  278.  
  279.     return xm_display->display.userGrabbed;    
  280. }
  281. /*----------------------------------------------------------------------*/
  282. /* extern */ void
  283. XfeDisplaySetUserGrabbed(Widget w,Boolean grabbed)
  284. {
  285.     XmDisplayRec *    xm_display;
  286.  
  287.     assert( _XfeIsAlive(w) );
  288.  
  289.     xm_display = (XmDisplayRec *) XmGetXmDisplay(XtDisplay(w));
  290.  
  291.     assert( xm_display != NULL );
  292.  
  293.     xm_display->display.userGrabbed = grabbed;
  294. }
  295. /*----------------------------------------------------------------------*/
  296.  
  297.  
  298. /*----------------------------------------------------------------------*/
  299. /*                                                                        */
  300. /* Menu item functions.                                                    */
  301. /*                                                                        */
  302. /*----------------------------------------------------------------------*/
  303. /* extern */ Widget
  304. XfeMenuItemNextItem(Widget item)
  305. {
  306.     int            position_index;
  307.     Widget        parent;
  308.     Cardinal    num_children;
  309.     Widget        next = NULL;
  310.  
  311.     assert( _XfeIsAlive(item) );
  312.     assert( XtIsObject(item) );
  313.  
  314.     parent = _XfeParent(item);
  315.  
  316.     assert( XmIsRowColumn(_XfeParent(item)) );
  317.  
  318.     position_index = XfeMenuItemPositionIndex(item);
  319.  
  320.     num_children = _XfemNumChildren(parent);
  321.  
  322.     if (position_index < (num_children - 1))
  323.     {
  324.         next = _XfeChildrenIndex(parent,position_index + 1);
  325.     }
  326.  
  327.     return next;
  328. }
  329. /*----------------------------------------------------------------------*/
  330. /* extern */ Widget
  331. XfeMenuItemPreviousItem(Widget item)
  332. {
  333.     int            position_index;
  334.     Widget        parent;
  335.     Cardinal    num_children;
  336.     Widget        previous = NULL;
  337.  
  338.     assert( _XfeIsAlive(item) );
  339.     assert( XtIsObject(item) );
  340.  
  341.     parent = _XfeParent(item);
  342.  
  343.     assert( XmIsRowColumn(_XfeParent(item)) );
  344.  
  345.     position_index = XfeMenuItemPositionIndex(item);
  346.  
  347.     num_children = _XfemNumChildren(parent);
  348.  
  349.     if (position_index > 0)
  350.     {
  351.         previous = _XfeChildrenIndex(parent,position_index - 1);
  352.     }
  353.  
  354.     return previous;
  355. }
  356. /*----------------------------------------------------------------------*/
  357.  
  358. /*----------------------------------------------------------------------*/
  359. /*                                                                        */
  360. /* Private accent functions.                                            */
  361. /*                                                                        */
  362. /*----------------------------------------------------------------------*/
  363. #define ACCENT_DRAW        1
  364. #define ACCENT_ERASE    2
  365.  
  366. static void        AccentBottom    (Widget,GC,GC,Dimension,Dimension,
  367.                                  Dimension,Dimension,int);
  368. static void        AccentAll        (Widget,GC,GC,Dimension,Dimension,
  369.                                  Dimension,Dimension,int);
  370. static void        AccentTop        (Widget,GC,GC,Dimension,Dimension,
  371.                                  Dimension,Dimension,int);
  372.  
  373. /*----------------------------------------------------------------------*/
  374. /*                                                                        */
  375. /* Public accent drawing functions.                                        */
  376. /*                                                                        */
  377. /*----------------------------------------------------------------------*/
  378. /* extern */ void
  379. XfeMenuItemDrawAccent(Widget            item,
  380.                       unsigned char        accent_type,
  381.                       Dimension            offset_left,
  382.                       Dimension            offset_right,
  383.                       Dimension            shadow_thickness,
  384.                       Dimension            accent_thickness)
  385. {
  386.     Widget        pw;
  387.     GC            top_gc;
  388.     GC            bottom_gc;
  389.     XGCValues    values;
  390.     int            top_subwindow_mode;
  391.     int            bottom_subwindow_mode;
  392.  
  393.     /* duh */
  394.     if (accent_type == XmACCENT_NONE)
  395.     {
  396.         return;
  397.     }
  398.  
  399.     assert( _XfeIsAlive(item) );
  400.     assert( XmIsPushButton(item) || XmIsCascadeButton(item) );
  401.  
  402.     pw = _XfeParent(item);
  403.  
  404.     assert( XmIsRowColumn(pw) );
  405.  
  406.     top_gc        = _XfemTopShadowGC(pw);
  407.     bottom_gc    = _XfemBottomShadowGC(pw);
  408.  
  409.     /* Remember the old wubwindow mode values */
  410.     XGetGCValues(XtDisplay(item),top_gc,GCSubwindowMode,&values);
  411.  
  412.     top_subwindow_mode = values.subwindow_mode;
  413.  
  414.     XGetGCValues(XtDisplay(item),bottom_gc,GCSubwindowMode,&values);
  415.  
  416.     bottom_subwindow_mode = values.subwindow_mode;
  417.  
  418.     /* Force the subwindow mode to IncludeInferiors */
  419.     XSetSubwindowMode(XtDisplay(item),top_gc,IncludeInferiors);
  420.     XSetSubwindowMode(XtDisplay(item),bottom_gc,IncludeInferiors);
  421.  
  422.     switch(accent_type)
  423.     {
  424.     case XmACCENT_BOTTOM:
  425.         AccentBottom(item,top_gc,bottom_gc,offset_left,offset_right,
  426.                      shadow_thickness,accent_thickness,ACCENT_DRAW);
  427.         break;
  428.  
  429.     case XmACCENT_ALL:
  430.         AccentAll(item,top_gc,bottom_gc,offset_left,offset_right,
  431.                   shadow_thickness,accent_thickness,ACCENT_DRAW);
  432.         break;
  433.  
  434.     case XmACCENT_TOP:
  435.         AccentTop(item,top_gc,bottom_gc,offset_left,offset_right,
  436.                   shadow_thickness,accent_thickness,ACCENT_DRAW);
  437.         break;
  438.  
  439.     default:
  440.         break;
  441.     }
  442.  
  443.     /* Restore the old subwindow mode */
  444.     XSetSubwindowMode(XtDisplay(item),top_gc,top_subwindow_mode);
  445.     XSetSubwindowMode(XtDisplay(item),bottom_gc,bottom_subwindow_mode);
  446. }
  447. /*----------------------------------------------------------------------*/
  448. /* extern */ void
  449. XfeMenuItemEraseAccent(Widget            item,
  450.                        unsigned char    accent_type,
  451.                        Dimension        offset_left,
  452.                        Dimension        offset_right,
  453.                        Dimension        shadow_thickness,
  454.                        Dimension        accent_thickness)
  455. {
  456.     Widget        pw;
  457.     GC            gc;
  458.     XGCValues    values;
  459.     int            subwindow_mode;
  460.  
  461.     /* duh */
  462.     if (accent_type == XmACCENT_NONE)
  463.     {
  464.         return;
  465.     }
  466.  
  467.     assert( _XfeIsAlive(item) );
  468.     assert( XmIsPushButton(item) || XmIsCascadeButton(item) );
  469.  
  470.     pw = _XfeParent(item);
  471.  
  472.     assert( XmIsRowColumn(pw) );
  473.  
  474.     gc = _XfemBackgroundGC(pw);
  475.  
  476.     /* Remember the old wubwindow mode values */
  477.     XGetGCValues(XtDisplay(item),gc,GCSubwindowMode,&values);
  478.  
  479.     subwindow_mode = values.subwindow_mode;
  480.  
  481.     /* Force the subwindow mode to IncludeInferiors */
  482.     XSetSubwindowMode(XtDisplay(item),gc,IncludeInferiors);
  483.  
  484.     switch(accent_type)
  485.     {
  486.     case XmACCENT_BOTTOM:
  487.         AccentBottom(item,gc,None,offset_left,offset_right,
  488.                      shadow_thickness,accent_thickness,ACCENT_ERASE);
  489.         break;
  490.  
  491.     case XmACCENT_ALL:
  492.         AccentAll(item,gc,None,offset_left,offset_right,
  493.                   shadow_thickness,accent_thickness,ACCENT_ERASE);
  494.         break;
  495.  
  496.     case XmACCENT_TOP:
  497.         AccentTop(item,gc,None,offset_left,offset_right,
  498.                   shadow_thickness,accent_thickness,ACCENT_ERASE);
  499.         break;
  500.  
  501.     default:
  502.         break;
  503.     }
  504.  
  505.     /* Restore the old subwindow mode */
  506.     XSetSubwindowMode(XtDisplay(item),gc,subwindow_mode);
  507. }
  508. /*----------------------------------------------------------------------*/
  509.  
  510. /*----------------------------------------------------------------------*/
  511. /*                                                                        */
  512. /* Private accent functions.                                            */
  513. /*                                                                        */
  514. /*----------------------------------------------------------------------*/
  515. static void
  516. AccentBottom(Widget            w,
  517.              GC                top_gc,
  518.              GC                bottom_gc,
  519.              Dimension        offset_left,
  520.              Dimension        offset_right,
  521.              Dimension        shadow_thickness,
  522.              Dimension        accent_thickness,
  523.              int            code)
  524. {
  525.     Widget        pw = _XfeParent(w);
  526.     int            position_index = XfeMenuItemPositionIndex(w);
  527.     Cardinal    num_children = _XfemNumChildren(pw);
  528.     Position    x;
  529.     Position    y;
  530.     Dimension    width;
  531.     Dimension    height = 2 * shadow_thickness + accent_thickness;
  532.  
  533.     assert( code == ACCENT_DRAW || code == ACCENT_ERASE );
  534.  
  535.     /* Last item */
  536.     if (position_index == (num_children - 1))
  537.     {
  538.         x = _XfeX(w) + offset_left;
  539.         y = _XfeY(w) + _XfeHeight(w) - height;
  540.         
  541.         width = _XfeWidth(w) - offset_left - offset_right;
  542.     }
  543.     /* Any other item */
  544.     else
  545.     {
  546.         x = _XfeX(w) + offset_left;
  547.         y = _XfeY(w) + _XfeHeight(w) - height / 2;
  548.         
  549.         width = _XfeWidth(w) - offset_left - offset_right;
  550.     }
  551.  
  552.     if (code == ACCENT_DRAW)
  553.     {
  554.         /* Draw accent */
  555.         _XmDrawShadows(XtDisplay(pw),_XfeWindow(pw),top_gc,bottom_gc,
  556.                        x,y,width,height,shadow_thickness,XmSHADOW_IN);
  557.     }
  558.     else
  559.     {
  560.         /* Erase accent */
  561.         XfeDrawRectangle(XtDisplay(pw),_XfeWindow(pw),top_gc,
  562.                          x,y,width,height,shadow_thickness);
  563.     }
  564. }
  565. /*----------------------------------------------------------------------*/
  566. static void
  567. AccentTop(Widget            w,
  568.           GC                top_gc,
  569.           GC                bottom_gc,
  570.           Dimension            offset_left,
  571.           Dimension            offset_right,
  572.           Dimension            shadow_thickness,
  573.           Dimension            accent_thickness,
  574.           int                code)
  575. {
  576.     Widget        pw = _XfeParent(w);
  577.     int            position_index = XfeMenuItemPositionIndex(w);
  578.     Position    x;
  579.     Position    y;
  580.     Dimension    width;
  581.     Dimension    height = 2 * shadow_thickness + accent_thickness;
  582.  
  583.     assert( code == ACCENT_DRAW || code == ACCENT_ERASE );
  584.  
  585.     /* First item */
  586.     if (position_index == 0)
  587.     {
  588.         x = _XfeX(w) + offset_left;
  589.         y = _XfeY(w);
  590.         
  591.         width = _XfeWidth(w) - offset_left - offset_right;
  592.     }
  593.     /* Any other item */
  594.     else
  595.     {
  596.         x = _XfeX(w) + offset_left;
  597.         y = _XfeY(w) - height / 2;
  598.         
  599.         width = _XfeWidth(w) - offset_left - offset_right;
  600.     }
  601.  
  602.     if (code == ACCENT_DRAW)
  603.     {
  604.         /* Draw accent */
  605.         _XmDrawShadows(XtDisplay(pw),_XfeWindow(pw),top_gc,bottom_gc,
  606.                        x,y,width,height,shadow_thickness,XmSHADOW_IN);
  607.     }
  608.     else
  609.     {
  610.         /* Erase accent */
  611.         XfeDrawRectangle(XtDisplay(pw),_XfeWindow(pw),top_gc,
  612.                          x,y,width,height,shadow_thickness);
  613.     }
  614. }
  615. /*----------------------------------------------------------------------*/
  616. static void
  617. AccentAll(Widget            w,
  618.           GC                top_gc,
  619.           GC                bottom_gc,
  620.           Dimension            offset_left,
  621.           Dimension            offset_right,
  622.           Dimension            shadow_thickness,
  623.           Dimension            accent_thickness,
  624.           int                code)
  625. {
  626. #if 1    
  627.     if (code == ACCENT_DRAW)
  628.     {
  629.         /* Draw accent */
  630.         _XmDrawShadows(XtDisplay(w),_XfeWindow(w),
  631.                        top_gc,bottom_gc,
  632.                        _XfeHighlightThickness(w),
  633.                        _XfeHighlightThickness(w),
  634.                        _XfeWidth(w) - 2 * _XfeHighlightThickness(w),
  635.                        _XfeHeight(w) - 2 * _XfeHighlightThickness(w),
  636.                        _XfeShadowThickness(w),
  637.                        XmSHADOW_OUT);
  638.     }
  639.     else
  640.     {
  641.         /* Erase accent */
  642.         XfeDrawRectangle(XtDisplay(w),_XfeWindow(w),top_gc,
  643.                          _XfeHighlightThickness(w),
  644.                          _XfeHighlightThickness(w),
  645.                          _XfeWidth(w) - 2 * _XfeHighlightThickness(w),
  646.                          _XfeHeight(w) - 2 * _XfeHighlightThickness(w),
  647.                          _XfeShadowThickness(w));
  648.     }
  649. #else
  650.     Widget        pw = _XfeParent(w);
  651.     int            position_index = XfeMenuItemPositionIndex(w);
  652.     Cardinal    num_children = _XfemNumChildren(pw);
  653.     Position    x;
  654.     Position    y;
  655.     Dimension    width;
  656.     Dimension    height;
  657.     Dimension    total_thickness = shadow_thickness + accent_thickness;
  658.  
  659.     assert( code == ACCENT_DRAW || code == ACCENT_ERASE );
  660.  
  661.     /* One and only */
  662.     if (num_children == 1)
  663.     {
  664.         x = _XfeX(w) + offset_left;
  665.         y = _XfeY(w);
  666.  
  667.         width = _XfeWidth(w) - offset_left - offset_right;
  668.         height = _XfeHeight(w);
  669.     }
  670.     else
  671.     {
  672.         Dimension overlap = (2 * shadow_thickness + accent_thickness) / 2;
  673.  
  674.         /* First item */
  675.         if (position_index == 0)
  676.         {
  677.             x = _XfeX(w) + offset_left;
  678.             y = _XfeY(w);
  679.             
  680.             width = _XfeWidth(w) - offset_left - offset_right;
  681.  
  682.             height = _XfeHeight(w) + overlap;
  683.         }
  684.         /* Last item */
  685.         else if (position_index == (num_children - 1))
  686.         {
  687.             x = _XfeX(w) + offset_left;
  688.             y = _XfeY(w) - overlap;
  689.             
  690.             width = _XfeWidth(w) - offset_left - offset_right;
  691.  
  692.             height = _XfeHeight(w) + overlap;
  693.         }
  694.         /* In between two others */
  695.         else
  696.         {
  697.             x = _XfeX(w) + offset_left;
  698.             y = _XfeY(w) - overlap;
  699.             
  700.             width = _XfeWidth(w) - offset_left - offset_right;
  701.  
  702.             height = _XfeHeight(w) + 2 * total_thickness;
  703.         }
  704.     }
  705.  
  706.     if (code == ACCENT_DRAW)
  707.     {
  708.         /* Draw accent */
  709.         _XmDrawShadows(XtDisplay(pw),_XfeWindow(pw),top_gc,bottom_gc,
  710.                    x,y,width,height,shadow_thickness,XmSHADOW_IN);
  711.         
  712.         x += total_thickness;
  713.         y += total_thickness;
  714.         
  715.         width -= (2 * total_thickness);
  716.         height -= (2 * total_thickness);
  717.                    
  718.         _XmDrawShadows(XtDisplay(pw),_XfeWindow(pw),top_gc,bottom_gc,
  719.                        x,y,width,height,shadow_thickness,XmSHADOW_OUT);
  720.     }
  721.     else
  722.     {
  723.         /* Erase accent */
  724.         XfeDrawRectangle(XtDisplay(pw),_XfeWindow(pw),top_gc,
  725.                          x,y,width,height,shadow_thickness);
  726.         
  727.         x += total_thickness;
  728.         y += total_thickness;
  729.         
  730.         width -= (2 * total_thickness);
  731.         height -= (2 * total_thickness);
  732.                    
  733.         XfeDrawRectangle(XtDisplay(pw),_XfeWindow(pw),top_gc,
  734.                          x,y,width,height,shadow_thickness);
  735.     }
  736. #endif
  737. }
  738. /*----------------------------------------------------------------------*/
  739. /* extern */ unsigned char
  740. XfeMenuType(Widget menu)
  741. {
  742.     assert( _XfeIsAlive(menu) );
  743.     assert( XmIsRowColumn(menu) );
  744.  
  745.     return RC_Type(menu);
  746. }
  747. /*----------------------------------------------------------------------*/
  748.