home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / Microline3.0 / XmL / Folder.c next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  105.3 KB  |  3,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.  * The following source code is part of the Microline Widget Library.
  21.  * The Microline widget library is made available to Mozilla developers
  22.  * under the Netscape Public License (NPL) by Neuron Data.  To learn
  23.  * more about Neuron Data, please visit the Neuron Data Home Page at
  24.  * http://www.neurondata.com.
  25.  */
  26.  
  27. #include "FolderP.h"
  28. #include <X11/StringDefs.h>
  29. #include <Xm/DrawnB.h>
  30. #include <Xm/Label.h>
  31. #include <Xm/Form.h>
  32.  
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35.  
  36. #ifdef SUNOS4
  37. int fprintf(FILE *, char *, ...);
  38. #endif
  39.  
  40. /* Create and Destroy */
  41. static void ClassInitialize();
  42. static void Initialize(Widget req, Widget newW, 
  43.     ArgList args, Cardinal *nargs);
  44. static void Destroy(Widget w);
  45.  
  46. /* Geometry, Drawing, Entry and Picking */
  47. static void Realize(Widget w, XtValueMask *valueMask,
  48.     XSetWindowAttributes *attr);
  49. static void Redisplay(Widget w, XExposeEvent *event, Region region);
  50. static void Layout(XmLFolderWidget f, int resizeIfNeeded);
  51. static void LayoutTopBottom(XmLFolderWidget f, int resizeIfNeeded);
  52. static void LayoutLeftRight(XmLFolderWidget f, int resizeIfNeeded);
  53. static void Resize(Widget w);
  54. static XtGeometryResult GeometryManager(Widget w, XtWidgetGeometry *request,
  55.     XtWidgetGeometry *);
  56. static void ChangeManaged(Widget w);
  57. static void ConstraintInitialize(Widget, Widget w,
  58.     ArgList args, Cardinal *nargs);
  59. static void ConstraintDestroy(Widget w);
  60. static void SetActiveTab(XmLFolderWidget f, Widget w, XEvent *event,
  61.     Boolean notify);
  62. static void DrawTabPixmap(XmLFolderWidget f, Widget tab, int active);
  63. static void DrawManagerShadowLeftRight(XmLFolderWidget f, XRectangle *rect);
  64. static void DrawManagerShadowTopBottom(XmLFolderWidget f, XRectangle *rect);
  65. static void DrawTabHighlight(XmLFolderWidget f, Widget w);
  66. static void SetTabPlacement(XmLFolderWidget f, Widget tab);
  67. static void GetTabRect(XmLFolderWidget f, Widget tab, XRectangle *rect,
  68.     int includeShadow);
  69. static void DrawTabShadowArcTopBottom(XmLFolderWidget f, Widget w);
  70. static void DrawTabShadowArcLeftRight(XmLFolderWidget f, Widget w);
  71. static void DrawTabShadowLineTopBottom(XmLFolderWidget f, Widget w);
  72. static void DrawTabShadowLineLeftRight(XmLFolderWidget f, Widget w);
  73. static void DrawTabShadowNoneTopBottom(XmLFolderWidget f, Widget w);
  74. static void DrawTabShadowNoneLeftRight(XmLFolderWidget f, Widget w);
  75. static void SetGC(XmLFolderWidget f, int type);
  76.  
  77. /* Getting and Setting Values */
  78. static Boolean SetValues(Widget curW, Widget reqW, Widget newW, 
  79.     ArgList args, Cardinal *nargs);
  80. static Boolean ConstraintSetValues(Widget curW, Widget, Widget newW,
  81.     ArgList, Cardinal *); 
  82. static void CopyFontList(XmLFolderWidget f);
  83. static Boolean CvtStringToCornerStyle(Display *dpy, XrmValuePtr args,
  84.     Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
  85.     XtPointer *data);
  86. static Boolean CvtStringToFolderResizePolicy(Display *dpy, XrmValuePtr args,
  87.     Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
  88.     XtPointer *data);
  89. static Boolean CvtStringToTabPlacement(Display *dpy, XrmValuePtr args,
  90.     Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
  91.     XtPointer *data);
  92.  
  93. /* Utility */
  94. static void GetCoreBackground(Widget w, int, XrmValue *value);
  95. static void GetDefaultTabWidgetClass(Widget w, int, XrmValue *value);
  96. static void GetManagerForeground(Widget w, int, XrmValue *value);
  97. static Boolean ServerDrawsArcsLarge(Display *dpy, int debug);
  98.  
  99. /* Actions, Callbacks and Handlers */
  100. static void Activate(Widget w, XEvent *event, String *, Cardinal *);
  101. static void PrimActivate(Widget w, XtPointer, XtPointer);
  102. static void PrimFocusIn(Widget w, XEvent *event, String *, Cardinal *);
  103. static void PrimFocusOut(Widget w, XEvent *event, String *, Cardinal *);
  104.  
  105. static XtActionsRec actions[] =
  106.     {
  107.     { "XmLFolderActivate",      Activate     },
  108.     { "XmLFolderPrimFocusIn",   PrimFocusIn  },
  109.     { "XmLFolderPrimFocusOut",  PrimFocusOut },
  110.     };
  111.  
  112. #define MAX_TAB_ROWS 64
  113.  
  114. #define GC_SHADOWBOT  0
  115. #define GC_SHADOWTOP  1
  116. #define GC_BLANK      2
  117. #define GC_UNSET      3
  118.  
  119. /* Folder Translations */
  120.  
  121. static char translations[] =
  122. "<Btn1Down>: XmLFolderActivate()\n\
  123. <EnterWindow>:   ManagerEnter()\n\
  124. <LeaveWindow>:   ManagerLeave()\n\
  125. <FocusOut>:      ManagerFocusOut()\n\
  126. <FocusIn>:       ManagerFocusIn()";
  127.  
  128. /* Primitive Child Translations */
  129.  
  130. static char primTranslations[] =
  131. "<FocusIn>: XmLFolderPrimFocusIn() PrimitiveFocusIn()\n\
  132. <FocusOut>: XmLFolderPrimFocusOut() PrimitiveFocusOut()";
  133.  
  134. static XtResource resources[] =
  135.     {
  136.         /* Folder Resources */
  137.         {
  138.         XmNtabWidgetClass, XmCTabWidgetClass,
  139.         XmRWidgetClass, sizeof(WidgetClass),
  140.         XtOffset(XmLFolderWidget, folder.tabWidgetClass),
  141.         XmRCallProc, (XtPointer)GetDefaultTabWidgetClass,
  142.         },
  143.         {
  144.         XmNactivateCallback, XmCCallback,
  145.         XmRCallback, sizeof(XtCallbackList),
  146.         XtOffset(XmLFolderWidget, folder.activateCallback),
  147.         XmRImmediate, (XtPointer)0,
  148.         },
  149.         {
  150.         XmNactiveTab, XmCActiveTab,
  151.         XmRInt, sizeof(int),
  152.         XtOffset(XmLFolderWidget, folder.activeTab),
  153.         XmRImmediate, (XtPointer)-1,
  154.         },
  155.         {
  156.         XmNautoSelect, XmCAutoSelect,
  157.         XmRBoolean, sizeof(Boolean),
  158.         XtOffset(XmLFolderWidget, folder.autoSelect),
  159.         XmRImmediate, (XtPointer)True,
  160.         },
  161.         {
  162.         XmNblankBackground, XmCBlankBackground,
  163.         XmRPixel, sizeof(Pixel),
  164.         XtOffset(XmLFolderWidget, folder.blankBg),
  165.         XmRCallProc, (XtPointer)GetCoreBackground,
  166.         },
  167.         {
  168.         XmNblankBackgroundPixmap, XmCBlankBackgroundPixmap,
  169.         XmRManForegroundPixmap, sizeof(Pixmap),
  170.         XtOffset(XmLFolderWidget, folder.blankPix),
  171.         XmRImmediate, (XtPointer)XmUNSPECIFIED_PIXMAP,
  172.         },
  173.         {
  174.         XmNcornerDimension, XmCCornerDimension,
  175.         XmRDimension, sizeof(Dimension),
  176.         XtOffset(XmLFolderWidget, folder.cornerDimension),
  177.         XmRImmediate, (XtPointer)2,
  178.         },
  179.         {
  180.         XmNcornerStyle, XmCCornerStyle,
  181.         XmRCornerStyle, sizeof(unsigned char),
  182.         XtOffset(XmLFolderWidget, folder.cornerStyle),
  183.         XmRImmediate, (XtPointer)XmCORNER_ARC,
  184.         },
  185.         {
  186.         XmNfontList, XmCFontList,
  187.         XmRFontList, sizeof(XmFontList),
  188.         XtOffset(XmLFolderWidget, folder.fontList),
  189.         XmRImmediate, (XtPointer)0,
  190.         },
  191.         {
  192.         XmNhighlightThickness, XmCHighlightThickness,
  193.         XmRDimension, sizeof(Dimension),
  194.         XtOffset(XmLFolderWidget, folder.highlightThickness),
  195.         XmRImmediate, (XtPointer)2,
  196.         },
  197.         {
  198.         XmNinactiveBackground, XmCInactiveBackground,
  199.         XmRPixel, sizeof(Pixel),
  200.         XtOffset(XmLFolderWidget, folder.inactiveBg),
  201.         XmRCallProc, (XtPointer)GetCoreBackground,
  202.         },
  203.         {
  204.         XmNinactiveForeground, XmCInactiveForeground,
  205.         XmRPixel, sizeof(Pixel),
  206.         XtOffset(XmLFolderWidget, folder.inactiveFg),
  207.         XmRCallProc, (XtPointer)GetManagerForeground,
  208.         },
  209.         {
  210.         XmNmarginHeight, XmCMarginHeight,
  211.         XmRDimension, sizeof(Dimension),
  212.         XtOffset(XmLFolderWidget, folder.marginHeight),
  213.         XmRImmediate, (XtPointer)0,
  214.         },
  215.         {
  216.         XmNmarginWidth, XmCMarginWidth,
  217.         XmRDimension, sizeof(Dimension),
  218.         XtOffset(XmLFolderWidget, folder.marginWidth),
  219.         XmRImmediate, (XtPointer)0,
  220.         },
  221.         {
  222.         XmNpixmapMargin, XmCPixmapMargin,
  223.         XmRDimension, sizeof(Dimension),
  224.         XtOffset(XmLFolderWidget, folder.pixmapMargin),
  225.         XmRImmediate, (XtPointer)2,
  226.         },
  227.         {
  228.         XmNresizePolicy, XmCFolderResizePolicy,
  229.         XmRFolderResizePolicy, sizeof(unsigned char),
  230.         XtOffset(XmLFolderWidget, folder.resizePolicy),
  231.         XmRImmediate, (XtPointer)XmRESIZE_STATIC,
  232.         },
  233.         {
  234.         XmNrotateWhenLeftRight, XmCRotateWhenLeftRight,
  235.         XmRBoolean, sizeof(Boolean),
  236.         XtOffset(XmLFolderWidget, folder.allowRotate),
  237.         XmRImmediate, (XtPointer)True,
  238.         },
  239.         {
  240.         XmNspacing, XmCSpacing,
  241.         XmRDimension, sizeof(Dimension),
  242.         XtOffset(XmLFolderWidget, folder.spacing),
  243.         XmRImmediate, (XtPointer)0,
  244.         },
  245.         {
  246.         XmNtabBarHeight, XmCTabBarHeight,
  247.         XmRDimension, sizeof(Dimension),
  248.         XtOffset(XmLFolderWidget, folder.tabBarHeight),
  249.         XmRImmediate, (XtPointer)0,
  250.         },
  251.         {
  252.         XmNtabCount, XmCTabCount,
  253.         XmRInt, sizeof(int),
  254.         XtOffset(XmLFolderWidget, folder.tabCount),
  255.         XmRImmediate, (XtPointer)0,
  256.         },
  257.         {
  258.         XmNtabPlacement, XmCTabPlacement,
  259.         XmRTabPlacement, sizeof(unsigned char),
  260.         XtOffset(XmLFolderWidget, folder.tabPlacement),
  261.         XmRImmediate, (XtPointer)XmFOLDER_TOP,
  262.         },
  263.         {
  264.         XmNtabsPerRow, XmCTabsPerRow,
  265.         XmRInt, sizeof(int),
  266.         XtOffset(XmLFolderWidget, folder.tabsPerRow),
  267.         XmRImmediate, (XtPointer)0,
  268.         },
  269.         {
  270.         XmNtabWidgetList, XmCReadOnly,
  271.         XmRPointer, sizeof(XtPointer),
  272.         XtOffset(XmLFolderWidget, folder.tabs),
  273.         XmRImmediate, (XtPointer)0,
  274.         },
  275.         {
  276.         XmNtabTranslations, XmCTranslations,
  277.         XmRTranslationTable, sizeof(XtTranslations),
  278.         XtOffset(XmLFolderWidget, folder.primTrans),
  279.         XmRString, (XtPointer)primTranslations,
  280.         },
  281.         {
  282.         XmNdebugLevel, XmCDebugLevel,
  283.         XmRInt, sizeof(int),
  284.         XtOffset(XmLFolderWidget, folder.debugLevel),
  285.         XmRImmediate, (XtPointer)0,
  286.         },
  287.         /* Overridden inherited resources */
  288.         {
  289.         XmNshadowThickness, XmCShadowThickness,
  290.         XmRHorizontalDimension, sizeof(Dimension),
  291.         XtOffset(XmLFolderWidget, manager.shadow_thickness),
  292.         XmRImmediate, (XtPointer)2,
  293.         },
  294.     };
  295.  
  296. static XtResource constraint_resources[] =
  297.     {
  298.         /* Folder Constraint Resources */
  299.         {
  300.         XmNtabFreePixmaps, XmCTabFreePixmaps,
  301.         XmRBoolean, sizeof(Boolean),
  302.         XtOffset(XmLFolderConstraintPtr, folder.freePix),
  303.         XmRImmediate, (XtPointer)False,
  304.         },
  305.         {
  306.         XmNtabInactivePixmap, XmCTabInactivePixmap,
  307.         XmRPrimForegroundPixmap, sizeof(Pixmap),
  308.         XtOffset(XmLFolderConstraintPtr, folder.inactPix),
  309.         XmRImmediate, (XtPointer)XmUNSPECIFIED_PIXMAP,
  310.         },
  311.         {
  312.         XmNtabManagedName, XmCTabManagedName,
  313.         XmRString, sizeof(char *),
  314.         XtOffset(XmLFolderConstraintPtr, folder.managedName),
  315.         XmRImmediate, (XtPointer)0,
  316.         },
  317.         {
  318.         XmNtabManagedWidget, XmCTabManagedWidget,
  319.         XmRWidget, sizeof(Widget),
  320.         XtOffset(XmLFolderConstraintPtr, folder.managedW),
  321.         XmRImmediate, (XtPointer)0,
  322.         },
  323.         {
  324.         XmNtabPixmap, XmCTabPixmap,
  325.         XmRPrimForegroundPixmap, sizeof(Pixmap),
  326.         XtOffset(XmLFolderConstraintPtr, folder.pix),
  327.         XmRImmediate, (XtPointer)XmUNSPECIFIED_PIXMAP,
  328.         },
  329.     };
  330.  
  331. XmLFolderClassRec xmlFolderClassRec =
  332.     {
  333.         { /* core_class */
  334.         (WidgetClass)&xmManagerClassRec,          /* superclass         */
  335.         "XmLFolder",                              /* class_name         */
  336.         sizeof(XmLFolderRec),                     /* widget_size        */
  337.         ClassInitialize,                          /* class_init         */
  338.         0,                                        /* class_part_init    */
  339.         FALSE,                                    /* class_inited       */
  340.         (XtInitProc)Initialize,                   /* initialize         */
  341.         0,                                        /* initialize_hook    */
  342.         (XtRealizeProc)Realize,                   /* realize            */
  343.         (XtActionList)actions,                    /* actions            */
  344.         (Cardinal)XtNumber(actions),              /* num_actions        */
  345.         resources,                                /* resources          */
  346.         XtNumber(resources),                      /* num_resources      */
  347.         NULLQUARK,                                /* xrm_class          */
  348.         TRUE,                                     /* compress_motion    */
  349.         XtExposeCompressMultiple,                 /* compress_exposure  */
  350.         TRUE,                                     /* compress_enterlv   */
  351.         TRUE,                                     /* visible_interest   */
  352.         (XtWidgetProc)Destroy,                    /* destroy            */
  353.         (XtWidgetProc)Resize,                     /* resize             */
  354.         (XtExposeProc)Redisplay,                  /* expose             */
  355.         (XtSetValuesFunc)SetValues,               /* set_values         */
  356.         0,                                        /* set_values_hook    */
  357.         XtInheritSetValuesAlmost,                 /* set_values_almost  */
  358.         0,                                        /* get_values_hook    */
  359.         0,                                        /* accept_focus       */
  360.         XtVersion,                                /* version            */
  361.         0,                                        /* callback_private   */
  362.         translations,                             /* tm_table           */
  363.         0,                                        /* query_geometry     */
  364.         0,                                        /* display_acceleratr */
  365.         0,                                        /* extension          */
  366.         },
  367.         { /* composite_class */
  368.         (XtGeometryHandler)GeometryManager,       /* geometry_manager   */
  369.         (XtWidgetProc)ChangeManaged,              /* change_managed     */
  370.         XtInheritInsertChild,                     /* insert_child       */
  371.         XtInheritDeleteChild,                     /* delete_child       */
  372.         0,                                        /* extension          */
  373.         },
  374.         { /* constraint_class */
  375.         constraint_resources,                      /* subresources       */
  376.         XtNumber(constraint_resources),           /* subresource_count  */
  377.         sizeof(XmLFolderConstraintRec),           /* constraint_size    */
  378.         (XtInitProc)ConstraintInitialize,         /* initialize         */
  379.         (XtWidgetProc)ConstraintDestroy,          /* destroy            */
  380.         (XtSetValuesFunc)ConstraintSetValues,     /* set_values         */
  381.         0,                                        /* extension          */
  382.         },
  383.         { /* manager_class */
  384.         XtInheritTranslations,                    /* translations       */
  385.         0,                                        /* syn resources      */
  386.         0,                                        /* num syn_resources  */
  387.         0,                                        /* get_cont_resources */
  388.         0,                                        /* num_get_cont_resrc */
  389.         XmInheritParentProcess,                   /* parent_process     */
  390.         0,                                        /* extension          */
  391.         },
  392.         { /* folder_class */
  393.         0,                                        /* unused             */
  394.         }
  395.     };
  396.  
  397. WidgetClass xmlFolderWidgetClass = (WidgetClass)&xmlFolderClassRec;
  398.  
  399. /*
  400.    Create and Destroy
  401. */
  402.  
  403. static void 
  404. ClassInitialize(void)
  405. {
  406.   XmLInitialize();
  407.   
  408.   XtSetTypeConverter(XmRString, XmRCornerStyle,
  409.              CvtStringToCornerStyle, 0, 0, XtCacheNone, 0);
  410.   XtSetTypeConverter(XmRString, XmRFolderResizePolicy,
  411.              CvtStringToFolderResizePolicy, 0, 0, XtCacheNone, 0);
  412.   XtSetTypeConverter(XmRString, XmRTabPlacement,
  413.              CvtStringToTabPlacement, 0, 0, XtCacheNone, 0);
  414. }
  415.  
  416. static void 
  417. Initialize(Widget req, 
  418.        Widget newW, 
  419.        ArgList args, 
  420.        Cardinal *narg) 
  421. {
  422.   Display *dpy;
  423.   /*  Window root;*/
  424.   XmLFolderWidget f, request;
  425.   
  426.   f = (XmLFolderWidget)newW;
  427.   dpy = XtDisplay((Widget)f);
  428.   request = (XmLFolderWidget)req;
  429.   
  430.   if (f->core.width <= 0) 
  431.     f->core.width = 100;
  432.   if (f->core.height <= 0) 
  433.     f->core.height = 100;
  434.   
  435.   f->folder.gc = 0;
  436.   
  437.   f->folder.tabAllocCount = 32;
  438.   f->folder.tabs = (Widget *)malloc(sizeof(Widget) * 32);
  439.   f->folder.tabHeight = 0;
  440.   f->folder.tabWidth = 0;
  441.   f->folder.activeW = 0;
  442.   f->folder.focusW = 0;
  443.   f->folder.allowLayout = 1;
  444.   f->folder.activeRow = -1;
  445.   CopyFontList(f);
  446.   
  447.   if (f->folder.tabBarHeight)
  448.     {
  449.       XmLWarning((Widget)f, "Initialize() - can't set tabBarHeight");
  450.       f->folder.tabBarHeight = 0;
  451.     }
  452.   if (f->folder.tabCount)
  453.     {
  454.       XmLWarning((Widget)f, "Initialize() - can't set tabCount");
  455.       f->folder.tabCount = 0;
  456.     }
  457.   if (f->folder.activeTab != -1)
  458.     {
  459.       XmLWarning((Widget)f, "Initialize() - can't set activeTab");
  460.       f->folder.activeTab = -1;
  461.     }
  462.   if (f->folder.cornerDimension < 1)
  463.     {
  464.       XmLWarning((Widget)f, "Initialize() - cornerDimension can't be < 1");
  465.       f->folder.cornerDimension = 1;
  466.     }
  467.   f->folder.serverDrawsArcsLarge = ServerDrawsArcsLarge(dpy,
  468.                             f->folder.debugLevel);
  469. }
  470.  
  471. static void 
  472. Destroy(Widget w)
  473. {
  474.   XmLFolderWidget f;
  475.   Display *dpy;
  476.   
  477.   f = (XmLFolderWidget)w;
  478.   dpy = XtDisplay(w);
  479.   if (f->folder.debugLevel)
  480.     fprintf(stderr, "Folder destroy: \n");
  481.   if (f->folder.tabs)
  482.     free((char *)f->folder.tabs);
  483.   if (f->folder.gc)
  484.     XFreeGC(dpy, f->folder.gc);
  485.   XmFontListFree(f->folder.fontList);
  486. }
  487.  
  488. /*
  489.   Geometry, Drawing, Entry and Picking
  490.   */
  491.  
  492. static void 
  493. Realize(Widget w, 
  494.     XtValueMask *valueMask, 
  495.     XSetWindowAttributes *attr)
  496. {
  497.   XmLFolderWidget f;
  498.   Display *dpy;
  499.   WidgetClass superClass;
  500.   XtRealizeProc realize;
  501.   XGCValues values;
  502.   XtGCMask mask;
  503.   
  504.   f = (XmLFolderWidget)w;
  505.   dpy = XtDisplay(f);
  506.   superClass = xmlFolderWidgetClass->core_class.superclass;
  507.   realize = superClass->core_class.realize;
  508.   (*realize)(w, valueMask, attr);
  509.   
  510.   if (!f->folder.gc)
  511.     {
  512.       values.foreground = f->manager.foreground;
  513.       mask = GCForeground;
  514.       f->folder.gc = XCreateGC(dpy, XtWindow(f), mask, &values);
  515.       if (f->folder.autoSelect == True && f->folder.tabCount)
  516.     XmLFolderSetActiveTab(w, 0, False);
  517.     }
  518. }
  519.  
  520. static void 
  521. Redisplay(Widget w, 
  522.       XExposeEvent *event, 
  523.       Region region)
  524. {
  525.   Display *dpy;
  526.   Window win;
  527.   XmLFolderWidget f;
  528.   XmLFolderConstraintRec *fc;
  529.   XRectangle eRect, rRect, rect;
  530.   /* XSegment *topSeg, *botSeg; */
  531.   /*  int tCount, bCount; */
  532.   Widget tab;
  533.   int i, st, ht; /*, x, y; */
  534.   
  535.   f = (XmLFolderWidget)w;
  536.   if (!XtIsRealized(w))
  537.     return;
  538.   if (!f->core.visible)
  539.     return;
  540.   dpy = XtDisplay(f);
  541.   win = XtWindow(f);
  542.   st = f->manager.shadow_thickness;
  543.   ht = f->folder.highlightThickness;
  544.   
  545.   if (event)
  546.     {
  547.       eRect.x = event->x;
  548.       eRect.y = event->y;
  549.       eRect.width = event->width;
  550.       eRect.height = event->height;
  551.       if (f->folder.debugLevel > 1)
  552.     fprintf(stderr, "XmLFolder: Redisplay x %d y %d w %d h %d\n",
  553.         event->x, event->y, event->width, event->height);
  554.     }
  555.   else
  556.     {
  557.       eRect.x = 0;
  558.       eRect.y = 0;
  559.       eRect.width = f->core.width;
  560.       eRect.height = f->core.height;
  561.     }
  562.   if (!eRect.width || !eRect.height)
  563.     return;
  564.   
  565.   if (f->folder.tabPlacement == XmFOLDER_TOP)
  566.     {
  567.       rRect.x = 0;
  568.       rRect.y = f->folder.tabHeight;
  569.       rRect.width = f->core.width;
  570.       rRect.height = f->core.height - f->folder.tabHeight;
  571.     }
  572.   else if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  573.     {
  574.       rRect.x = 0;
  575.       rRect.y = 0;
  576.       rRect.width = f->core.width;
  577.       rRect.height = f->core.height - f->folder.tabHeight;
  578.     }
  579.   if (f->folder.tabPlacement == XmFOLDER_LEFT)
  580.     {
  581.       rRect.x = f->folder.tabWidth;
  582.       rRect.y = 0;
  583.       rRect.width = f->core.width - f->folder.tabWidth;
  584.       rRect.height = f->core.height;
  585.     }
  586.   if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  587.     {
  588.       rRect.x = 0;
  589.       rRect.y = 0;
  590.       rRect.width = f->core.width - f->folder.tabWidth;
  591.       rRect.height = f->core.height;
  592.     }
  593.   if (XmLRectIntersect(&eRect, &rRect) != XmLRectOutside)
  594.     {
  595.       if (f->folder.tabPlacement == XmFOLDER_TOP ||
  596.       f->folder.tabPlacement == XmFOLDER_BOTTOM)
  597.     DrawManagerShadowTopBottom(f, &rRect);
  598.       else
  599.     DrawManagerShadowLeftRight(f, &rRect);
  600.     }
  601.  
  602.   if (!f->folder.tabCount)
  603.     return;
  604.  
  605.   rRect.x = 0;
  606.   rRect.y = 0;
  607.   rRect.width = 0;
  608.   rRect.height = 0;
  609.  
  610.     /* Draw tabs */
  611.   for (i = 0; i < f->folder.tabCount; i++)
  612.     {
  613.       tab = f->folder.tabs[i];
  614.       if (!XtIsManaged(tab))
  615.     continue;
  616.       fc = (XmLFolderConstraintRec *)(tab->core.constraints);
  617.       GetTabRect(f, tab, &rRect, 0);
  618.  
  619.       /* include spacing in intersect test */
  620.       rect = rRect;
  621.       if (f->folder.tabPlacement == XmFOLDER_TOP ||
  622.       f->folder.tabPlacement == XmFOLDER_BOTTOM)
  623.     rect.width += f->folder.spacing;
  624.       else
  625.     rect.height += f->folder.spacing;
  626.  
  627.       /* include indent in intersect test */
  628.       if (f->folder.tabsPerRow)
  629.     {
  630.       if (rRect.x == 2)
  631.         rect.x = 0;
  632.       if (rRect.y == 2)
  633.         rect.y = 0;
  634.       if (rRect.x + rRect.width == f->core.width - 2)
  635.         rect.width += 2;
  636.       if (rRect.y + rRect.height == f->core.height - 2)
  637.         rect.height += 2;
  638.     }
  639.  
  640.       if (XmLRectIntersect(&eRect, &rect) == XmLRectOutside)
  641.     continue;
  642.       if (event && XRectInRegion(region, rect.x, rect.y,
  643.                  rect.width, rect.height) == RectangleOut)
  644.     continue;
  645.  
  646.       if (f->folder.debugLevel > 1)
  647.     fprintf(stderr, "XmLFolder: Redisplay tab for widget %d\n", i);
  648.       if (tab == f->folder.activeW)
  649.     {
  650.       XtVaSetValues(tab,
  651.             XmNbackground, f->core.background_pixel,
  652.             XmNforeground, f->manager.foreground,
  653.             NULL);
  654.     }
  655.       else
  656.     {
  657.       XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
  658.       XFillRectangle(dpy, win, f->folder.gc,
  659.              rRect.x, rRect.y, rRect.width, rRect.height);
  660.       XtVaSetValues(tab,
  661.             XmNbackground, f->folder.inactiveBg,
  662.             XmNforeground, f->folder.inactiveFg,
  663.             NULL);
  664.     }
  665.  
  666.       if (f->folder.tabPlacement == XmFOLDER_TOP ||
  667.       f->folder.tabPlacement == XmFOLDER_BOTTOM)
  668.     {
  669.       if (f->folder.cornerStyle == XmCORNER_LINE)
  670.         DrawTabShadowLineTopBottom(f, tab);
  671.       else if (f->folder.cornerStyle == XmCORNER_ARC)
  672.         DrawTabShadowArcTopBottom(f, tab);
  673.       else
  674.         DrawTabShadowNoneTopBottom(f, tab);
  675.     }
  676.       else
  677.     {
  678.       if (f->folder.cornerStyle == XmCORNER_LINE)
  679.         DrawTabShadowLineLeftRight(f, tab);
  680.       else if (f->folder.cornerStyle == XmCORNER_ARC)
  681.         DrawTabShadowArcLeftRight(f, tab);
  682.       else
  683.         DrawTabShadowNoneLeftRight(f, tab);
  684.     }
  685.  
  686.       if (f->folder.focusW == tab)
  687.     DrawTabHighlight(f, tab);
  688.  
  689.       if (tab == f->folder.activeW &&
  690.       fc->folder.pix != XmUNSPECIFIED_PIXMAP &&
  691.       (fc->folder.maxPixWidth || fc->folder.maxPixHeight))
  692.     DrawTabPixmap(f, tab, 1);
  693.       else if (tab != f->folder.activeW &&
  694.            fc->folder.inactPix != XmUNSPECIFIED_PIXMAP &&
  695.            (fc->folder.maxPixWidth || fc->folder.maxPixHeight))
  696.     DrawTabPixmap(f, tab, 0);
  697.  
  698.       SetGC(f, GC_BLANK);
  699.  
  700.       /* draw indent */
  701.       if (f->folder.tabsPerRow)
  702.     {
  703.       if (rRect.x == 2)
  704.         {
  705.           rect = rRect;
  706.           rect.x = 0;
  707.           rect.width = 2;
  708.           XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
  709.                  rect.width, rect.height);
  710.         }
  711.       if (rRect.y == 2)
  712.         {
  713.           rect = rRect;
  714.           rect.y = 0;
  715.           rect.height = 2;
  716.           XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
  717.                  rect.width, rect.height);
  718.         }
  719.       if (rRect.x + rRect.width == f->core.width - 2)
  720.         {
  721.           rect = rRect;
  722.           rect.x = f->core.width - 2;
  723.           rect.width = 2;
  724.           XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
  725.                  rect.width, rect.height);
  726.         }
  727.       if (rRect.y + rRect.height == f->core.height - 2)
  728.         {
  729.           rect = rRect;
  730.           rect.y = f->core.height - 2;
  731.           rect.height = 2;
  732.           XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
  733.                  rect.width, rect.height);
  734.         }
  735.     }
  736.  
  737.       if (f->folder.spacing)
  738.     {
  739.       if (f->folder.tabPlacement == XmFOLDER_TOP ||
  740.           f->folder.tabPlacement == XmFOLDER_BOTTOM)
  741.         XFillRectangle(dpy, win, f->folder.gc, rRect.x + rRect.width,
  742.                rRect.y, f->folder.spacing, rRect.height);
  743.       else
  744.         XFillRectangle(dpy, win, f->folder.gc, rRect.x,
  745.                rRect.y + rRect.height, rRect.width, f->folder.spacing);
  746.     }
  747.  
  748.       SetGC(f, GC_UNSET);
  749.     }
  750.  
  751.   /* Draw empty area */
  752.   if (!f->folder.tabsPerRow)
  753.     {
  754.       if (f->folder.tabPlacement == XmFOLDER_TOP ||
  755.       f->folder.tabPlacement == XmFOLDER_BOTTOM)
  756.     {
  757.       rRect.x += rRect.width + f->folder.spacing;
  758.       if ((int)f->core.width > rRect.x)
  759.         {
  760.           if (f->folder.tabPlacement == XmFOLDER_TOP)
  761.         rRect.y = 0;
  762.           else
  763.         rRect.y = f->core.height - f->folder.tabHeight;
  764.           rRect.width = f->core.width - rRect.x;
  765.           rRect.height = f->folder.tabHeight;
  766.           SetGC(f, GC_BLANK);
  767.           XFillRectangle(dpy, win, f->folder.gc,
  768.                  rRect.x, rRect.y, rRect.width, rRect.height);
  769.           SetGC(f, GC_UNSET);
  770.         }
  771.     }
  772.       else
  773.     {
  774.       rRect.y += rRect.height + f->folder.spacing;
  775.       if ((int)f->core.height > rRect.y)
  776.         {
  777.           if (f->folder.tabPlacement == XmFOLDER_LEFT)
  778.         rRect.x = 0;
  779.           else
  780.         rRect.x = f->core.width - f->folder.tabWidth;
  781.           rRect.width = f->folder.tabWidth;
  782.           rRect.height = f->core.height - rRect.y;
  783.           SetGC(f, GC_BLANK);
  784.           XFillRectangle(dpy, win, f->folder.gc,
  785.                  rRect.x, rRect.y, rRect.width, rRect.height);
  786.           SetGC(f, GC_UNSET);
  787.         }
  788.     }
  789.     }
  790. }
  791.  
  792. static void 
  793. Layout(XmLFolderWidget f, 
  794.        int resizeIfNeeded)
  795. {
  796.   /*  Window win;*/
  797.  
  798.   if (!f->folder.allowLayout)
  799.     return;
  800.   f->folder.allowLayout = 0;
  801.   if (f->folder.tabPlacement == XmFOLDER_LEFT ||
  802.       f->folder.tabPlacement == XmFOLDER_RIGHT)
  803.     LayoutLeftRight(f, resizeIfNeeded);
  804.   else
  805.     LayoutTopBottom(f, resizeIfNeeded);
  806.   if (XtIsRealized((Widget)f) && f->core.visible)
  807.     XClearArea(XtDisplay(f), XtWindow(f), 0, 0, 0, 0, True);
  808.   f->folder.allowLayout = 1;
  809. }
  810.  
  811. static void 
  812. LayoutTopBottom(XmLFolderWidget f, 
  813.         int resizeIfNeeded)
  814. {
  815.   Display *dpy;
  816.   Window root;
  817.   int i, tabNum, x, y, w, h, pad1, pad2;
  818.   int rowNum, numRows, rowHeight, rowX, rowY;
  819.   WidgetList children;
  820.   Widget tab, child;
  821.   XmLFolderConstraintRec *fc;
  822.   XtGeometryResult result;
  823.   unsigned int inactPixHeight, pixHeight;
  824.   unsigned int inactPixWidth, pixWidth;
  825.   unsigned int pixBW, pixDepth;
  826.   Dimension height, minHeight;
  827.   Dimension width, minWidth, borderWidth;
  828.   Dimension co;
  829.   int st, ht;
  830.   Boolean map, isManaged;
  831.   struct
  832.   {
  833.     int width, height, numTabs, y;
  834.   } rows[MAX_TAB_ROWS];
  835.  
  836.   dpy = XtDisplay(f);
  837.   children = f->composite.children;
  838.   st = f->manager.shadow_thickness;
  839.   ht = f->folder.highlightThickness;
  840.  
  841.   /* calculate corner offset */
  842.   if (f->folder.cornerStyle == XmCORNER_LINE)
  843.     co = (Dimension)((double)f->folder.cornerDimension * .5 + .99);
  844.   else if (f->folder.cornerStyle == XmCORNER_ARC)
  845.     co = (Dimension)((double)f->folder.cornerDimension * .3 + .99);
  846.   else
  847.     co = 0;
  848.  
  849.   /* caculate tabHeight, minWidth, minHeight, row y positions, */
  850.   /* row heights and tab pixmap dimensions */
  851.   rowX = 0;
  852.   rowY = 0;
  853.   rowHeight = 0;
  854.   rowNum = 0;
  855.   tabNum = 0;
  856.   minWidth = 0;
  857.   for (i = 0; i < f->folder.tabCount; i++)
  858.     {
  859.       tab = f->folder.tabs[i];
  860.       if (!XtIsManaged(tab))
  861.     continue;
  862.       fc = (XmLFolderConstraintRec *)(tab->core.constraints);
  863.  
  864.       /* check for start of a new row */
  865.       fc->folder.firstInRow = False;
  866.       if (!tabNum)
  867.     fc->folder.firstInRow = True;
  868.       if (f->folder.tabsPerRow && tabNum == f->folder.tabsPerRow)
  869.     {
  870.       fc->folder.firstInRow = True;
  871.  
  872.       /* store prev row values and start next row */
  873.       if (rowX)
  874.         rowX -= f->folder.spacing;
  875.       rows[rowNum].y = rowY;
  876.       rows[rowNum].width = rowX;
  877.       rows[rowNum].height = rowHeight;
  878.       rows[rowNum].numTabs = tabNum;
  879.       if (f->folder.debugLevel)
  880.         {
  881.           fprintf(stderr, "XmLFolder: Layout: ");
  882.           fprintf(stderr, "row %d: y %d w %d h %d numTabs %d\n",
  883.               rowNum, rowY, rowX, rowHeight, tabNum);
  884.         }
  885.       rowY += rowHeight;
  886.       rowHeight = 0;
  887.       if (rowX > (int)minWidth)
  888.         minWidth = rowX;
  889.       rowX = 0;
  890.       tabNum = 0;
  891.       rowNum++;
  892.       if (rowNum == MAX_TAB_ROWS - 1)
  893.         {
  894.           XmLWarning((Widget)f, "Layout ERROR - too many rows\n");
  895.           return;
  896.         }
  897.     }
  898.  
  899.       /* make sure row height > maximum tab height */
  900.       height = co + st + tab->core.height + tab->core.border_width * 2 +
  901.     f->folder.marginHeight * 2 + ht * 2;
  902.       if ((int)height > rowHeight)
  903.     rowHeight = height;
  904.  
  905.       /* calc pixmap dimensions/maximum pixmap height */
  906.       fc->folder.pixWidth = 0;
  907.       fc->folder.pixHeight = 0;
  908.       fc->folder.inactPixWidth = 0;
  909.       fc->folder.inactPixHeight = 0;
  910.       fc->folder.maxPixWidth = 0;
  911.       fc->folder.maxPixHeight = 0;
  912.       if (fc->folder.pix != XmUNSPECIFIED_PIXMAP)
  913.     {
  914.       XGetGeometry(dpy, fc->folder.pix, &root,
  915.                &x, &y, &pixWidth, &pixHeight, &pixBW, &pixDepth);
  916.       fc->folder.pixWidth = pixWidth;
  917.       fc->folder.maxPixWidth = pixWidth;
  918.       fc->folder.pixHeight = pixHeight;
  919.       fc->folder.maxPixHeight = pixHeight;
  920.       height = co + st + pixHeight + f->folder.marginHeight * 2 + ht * 2;
  921.       if ((int)height > rowHeight)
  922.         rowHeight = height;
  923.     }
  924.       if (fc->folder.inactPix != XmUNSPECIFIED_PIXMAP)
  925.     {
  926.       XGetGeometry(dpy, fc->folder.inactPix, &root, &x, &y,
  927.                &inactPixWidth, &inactPixHeight, &pixBW, &pixDepth);
  928.       fc->folder.inactPixWidth = inactPixWidth;
  929.       if (inactPixWidth > fc->folder.maxPixWidth)
  930.         fc->folder.maxPixWidth = inactPixWidth;
  931.       fc->folder.inactPixHeight = inactPixHeight;
  932.       if (inactPixHeight > fc->folder.maxPixHeight)
  933.         fc->folder.maxPixHeight = inactPixHeight;
  934.       height = co + st + inactPixHeight +
  935.         f->folder.marginHeight * 2 + ht * 2;
  936.       if ((int)height > rowHeight)
  937.         rowHeight = height;
  938.     }
  939.  
  940.       /* increment rowX to move on to the next tab */
  941.       rowX += st * 2 + co * 2 + f->folder.marginWidth * 2 + ht * 2 +
  942.     XtWidth(tab) + tab->core.border_width * 2;
  943.       if (fc->folder.maxPixWidth)
  944.     rowX += fc->folder.maxPixWidth + f->folder.pixmapMargin;
  945.       rowX += f->folder.spacing;
  946.  
  947.       tabNum++;
  948.       fc->folder.row = rowNum;
  949.     }
  950.  
  951.   /* complete calcuations for last row */
  952.   if (rowX)
  953.     rowX -= f->folder.spacing;
  954.   rows[rowNum].y = rowY;
  955.   rows[rowNum].width = rowX;
  956.   rows[rowNum].height = rowHeight;
  957.   rows[rowNum].numTabs = tabNum;
  958.   numRows = rowNum + 1;
  959.   if (f->folder.debugLevel)
  960.     {
  961.       fprintf(stderr, "XmLFolder: Layout: ");
  962.       fprintf(stderr, "row %d: y %d w %d h %d numTabs %d\n",
  963.           rowNum, rowY, rowX, rowHeight, tabNum);
  964.     }
  965.   f->folder.tabHeight = rowY + rowHeight;
  966.   f->folder.tabBarHeight = f->folder.tabHeight;
  967.   minHeight = f->folder.tabHeight;
  968.   if ((int)minWidth < rowX)
  969.     minWidth = rowX;
  970.  
  971.   /* add space for indent of upper rows */
  972.   if (f->folder.tabsPerRow && minWidth)
  973.     minWidth += 4;
  974.  
  975.   if (f->folder.debugLevel)
  976.     {
  977.       fprintf(stderr, "XmLFolder: Layout: ");
  978.       fprintf(stderr, "tab bar minimum w %d h %d\n",
  979.           (int)minWidth, (int)minHeight);
  980.     }
  981.  
  982.   /* calculate width and height of non-tab children ensure */
  983.   /* minWidth > width and minHeight > height */
  984.   for (i = 0; i < f->composite.num_children; i++)
  985.     {
  986.       child = children[i];
  987.       if (XtIsSubclass(child, xmPrimitiveWidgetClass))
  988.     continue;
  989.  
  990.       height = XtHeight(child) + f->folder.tabHeight + st * 2;
  991.       if (XtIsWidget(child))
  992.     height += child->core.border_width * 2;
  993.       if (height > minHeight)
  994.     minHeight = height;
  995.  
  996.       width = XtWidth(child) + st * 2;
  997.       if (XtIsWidget(child))
  998.     width += child->core.border_width * 2;
  999.       if (width > minWidth)
  1000.     minWidth = width;
  1001.     }
  1002.  
  1003.   if (f->folder.debugLevel)
  1004.     {
  1005.       fprintf(stderr, "XmLFolder: Layout: ");
  1006.       fprintf(stderr, "with non-tabs minimum w %d h %d\n",
  1007.           (int)minWidth, (int)minHeight);
  1008.     }
  1009.  
  1010.   /* Resize folder if needed */
  1011.   if (resizeIfNeeded && f->folder.resizePolicy != XmRESIZE_NONE)
  1012.     {
  1013.       if (minWidth <= 0)
  1014.     minWidth = 1;
  1015.       if (minHeight <= 0)
  1016.     minHeight = 1;
  1017.       result = XtMakeResizeRequest((Widget)f, minWidth, minHeight,
  1018.                    &width, &height);
  1019.       if (result == XtGeometryAlmost)
  1020.     XtMakeResizeRequest((Widget)f, width, height, NULL, NULL);
  1021.     }
  1022.  
  1023.   /* move active row to bottom */
  1024.   tab = f->folder.activeW;
  1025.   if (tab)
  1026.     {
  1027.       fc = (XmLFolderConstraintRec *)(tab->core.constraints);
  1028.       rowNum = fc->folder.row;
  1029.       f->folder.activeRow = rowNum;
  1030.       rows[rowNum].y = f->folder.tabHeight - rows[rowNum].height;
  1031.       for (i = rowNum + 1; i < numRows; i++)
  1032.     rows[i].y -= rows[rowNum].height;
  1033.     }
  1034.   else
  1035.     f->folder.activeRow = -1;
  1036.  
  1037.   /* configure tab children */
  1038.   for (i = 0; i < f->folder.tabCount; i++)
  1039.     {
  1040.       tab = f->folder.tabs[i];
  1041.       if (!XtIsManaged(tab))
  1042.     continue;
  1043.       fc = (XmLFolderConstraintRec *)(tab->core.constraints);
  1044.       rowNum = fc->folder.row;
  1045.  
  1046.       /* calculate tab x */
  1047.       if (fc->folder.firstInRow == True)
  1048.     {
  1049.       if (f->folder.tabsPerRow && rowNum != f->folder.activeRow)
  1050.         x = 2;
  1051.       else
  1052.         x = 0;
  1053.     }
  1054.       fc->folder.x = x;
  1055.       x += st + co + f->folder.marginWidth + ht;
  1056.       if (fc->folder.maxPixWidth)
  1057.     x += fc->folder.maxPixWidth + f->folder.pixmapMargin;
  1058.  
  1059.       /* calculate tab y and tab height */
  1060.       fc->folder.height = rows[rowNum].height;
  1061.       if (f->folder.tabPlacement == XmFOLDER_TOP)
  1062.     {
  1063.       fc->folder.y = rows[rowNum].y;
  1064.       y = fc->folder.y + fc->folder.height - f->folder.marginHeight -
  1065.         ht - XtHeight(tab) - tab->core.border_width * 2;
  1066.     }
  1067.       else
  1068.     {
  1069.       fc->folder.y = f->core.height - rows[rowNum].y -
  1070.         rows[rowNum].height;
  1071.       y = fc->folder.y + f->folder.marginHeight + ht;
  1072.     }
  1073.  
  1074.       /* calculate tab padding */
  1075.       pad1 = 0;
  1076.       pad2 = 0;
  1077.       w = f->core.width - rows[rowNum].width;
  1078.       if (rowNum != f->folder.activeRow)
  1079.     w -= 4;
  1080.       if (f->folder.tabsPerRow && w > 0)
  1081.     {
  1082.       pad1 = w / (rows[rowNum].numTabs * 2);
  1083.       pad2 = pad1;
  1084.       if (fc->folder.firstInRow == True)
  1085.         pad2 += w - (pad1 * rows[rowNum].numTabs * 2);
  1086.     }
  1087.       x += pad1;
  1088.  
  1089.       /* move tab widget into place */
  1090.       XtMoveWidget(tab, x, y);
  1091.  
  1092.       /* calculate tab width and move to next tab */
  1093.       x += pad2 + XtWidth(tab) + tab->core.border_width * 2 + ht +
  1094.     f->folder.marginWidth + co + st;
  1095.       fc->folder.width = x - fc->folder.x; 
  1096.       x += f->folder.spacing;
  1097.     }
  1098.  
  1099.   /* configure non-tab children */
  1100.   for (i = 0; i < f->composite.num_children; i++)
  1101.     {
  1102.       child = children[i];
  1103.       if (XtIsSubclass(child, xmPrimitiveWidgetClass))
  1104.     continue;
  1105.       if (f->folder.resizePolicy == XmRESIZE_NONE)
  1106.     continue;
  1107.  
  1108.       w = (int)f->core.width - st * 2;
  1109.       h = (int)f->core.height - (int)f->folder.tabHeight - st * 2;
  1110.       if (h <= 0 || w <= 0)
  1111.     continue;
  1112.       /* manager widgets will not configure correctly unless they */
  1113.       /* are managed, so manage then unmapped if they are unmanaged */
  1114.       isManaged = True;
  1115.       if (!XtIsManaged(child))
  1116.     {
  1117.       XtVaGetValues(child,
  1118.             XmNmappedWhenManaged, &map,
  1119.             NULL);
  1120.       XtVaSetValues(child,
  1121.             XmNmappedWhenManaged, False,
  1122.             NULL);
  1123.       XtManageChild(child);
  1124.       isManaged = False;
  1125.     }
  1126.       x = st;
  1127.       if (f->folder.tabPlacement == XmFOLDER_TOP)
  1128.     y = f->folder.tabHeight + st;
  1129.       else
  1130.     y = st;
  1131.       width = w;
  1132.       height = h;
  1133.       borderWidth = 0;
  1134.       if (XtIsWidget(child))
  1135.     borderWidth = child->core.border_width;
  1136.       XtConfigureWidget(child, x, y, width, height, borderWidth);
  1137.       if (isManaged == False)
  1138.     {
  1139.       XtUnmanageChild(child);
  1140.       XtVaSetValues(child, XmNmappedWhenManaged, map, NULL);
  1141.     }
  1142.     }
  1143. }
  1144.  
  1145. static void 
  1146. LayoutLeftRight(XmLFolderWidget f, 
  1147.         int resizeIfNeeded)
  1148. {
  1149.   Display *dpy;
  1150.   Window root;
  1151.   int i, tabNum, x, y, w, h, pad1, pad2;
  1152.   int rowNum, numRows, rowWidth, rowX, rowY;
  1153.   WidgetList children;
  1154.   Widget tab, child;
  1155.   XmLFolderConstraintRec *fc;
  1156.   XtGeometryResult result;
  1157.   unsigned int inactPixHeight, pixHeight;
  1158.   unsigned int inactPixWidth, pixWidth;
  1159.   unsigned int pixBW, pixDepth;
  1160.   Dimension height, minHeight;
  1161.   Dimension width, minWidth, borderWidth;
  1162.   Dimension co;
  1163.   int st, ht;
  1164.   Boolean map, isManaged;
  1165.   struct
  1166.   {
  1167.     int width, height, numTabs, x;
  1168.   } rows[MAX_TAB_ROWS];
  1169.  
  1170.   dpy = XtDisplay(f);
  1171.   children = f->composite.children;
  1172.   st = f->manager.shadow_thickness;
  1173.   ht = f->folder.highlightThickness;
  1174.  
  1175.   /* calculate corner offset */
  1176.   if (f->folder.cornerStyle == XmCORNER_LINE)
  1177.     co = (Dimension)((double)f->folder.cornerDimension * .5 + .99);
  1178.   else if (f->folder.cornerStyle == XmCORNER_ARC)
  1179.     co = (Dimension)((double)f->folder.cornerDimension * .3 + .99);
  1180.   else
  1181.     co = 0;
  1182.  
  1183.   /* caculate tabWidth, minWidth, minHeight, row x positions, */
  1184.   /* row widths and tab pixmap dimensions */
  1185.   rowX = 0;
  1186.   rowY = 0;
  1187.   rowWidth = 0;
  1188.   rowNum = 0;
  1189.   tabNum = 0;
  1190.   minHeight = 0;
  1191.   for (i = 0; i < f->folder.tabCount; i++)
  1192.     {
  1193.       tab = f->folder.tabs[i];
  1194.       if (!XtIsManaged(tab))
  1195.     continue;
  1196.       fc = (XmLFolderConstraintRec *)(tab->core.constraints);
  1197.  
  1198.       /* check for start of a new row */
  1199.       fc->folder.firstInRow = False;
  1200.       if (!tabNum)
  1201.     fc->folder.firstInRow = True;
  1202.       if (f->folder.tabsPerRow && tabNum == f->folder.tabsPerRow)
  1203.     {
  1204.       fc->folder.firstInRow = True;
  1205.  
  1206.       /* store prev row values and start next row */
  1207.       if (rowY)
  1208.         rowY -= f->folder.spacing;
  1209.       rows[rowNum].x = rowX;
  1210.       rows[rowNum].height = rowY;
  1211.       rows[rowNum].width = rowWidth;
  1212.       rows[rowNum].numTabs = tabNum;
  1213.       if (f->folder.debugLevel)
  1214.         {
  1215.           fprintf(stderr, "XmLFolder: Layout: ");
  1216.           fprintf(stderr, "row %d: x %d w %d h %d numTabs %d\n",
  1217.               rowNum, rowX, rowWidth, rowY, tabNum);
  1218.         }
  1219.       rowX += rowWidth;
  1220.       rowWidth = 0;
  1221.       if (rowY > (int)minHeight)
  1222.         minHeight = rowY;
  1223.       rowY = 0;
  1224.       tabNum = 0;
  1225.       rowNum++;
  1226.       if (rowNum == MAX_TAB_ROWS - 1)
  1227.         {
  1228.           XmLWarning((Widget)f, "Layout ERROR - too many rows\n");
  1229.           return;
  1230.         }
  1231.     }
  1232.  
  1233.       /* make sure row width > maximum tab width */
  1234.       width = co + st + tab->core.width + tab->core.border_width * 2 +
  1235.     f->folder.marginHeight * 2 + ht * 2;
  1236.       if ((int)width > rowWidth)
  1237.     rowWidth = width;
  1238.  
  1239.       /* calc pixmap dimensions/maximum pixmap width */
  1240.       pixWidth = 0;
  1241.       pixHeight = 0;
  1242.       fc->folder.pixWidth = 0;
  1243.       fc->folder.pixHeight = 0;
  1244.       fc->folder.inactPixWidth = 0;
  1245.       fc->folder.inactPixHeight = 0;
  1246.       fc->folder.maxPixWidth = 0;
  1247.       fc->folder.maxPixHeight = 0;
  1248.       if (fc->folder.pix != XmUNSPECIFIED_PIXMAP)
  1249.     {
  1250.       XGetGeometry(dpy, fc->folder.pix, &root,
  1251.                &x, &y, &pixWidth, &pixHeight, &pixBW, &pixDepth);
  1252.       fc->folder.pixWidth = pixWidth;
  1253.       fc->folder.maxPixWidth = pixWidth;
  1254.       fc->folder.pixHeight = pixHeight;
  1255.       fc->folder.maxPixHeight = pixHeight;
  1256.       width = co + st + pixWidth + f->folder.marginHeight * 2 + ht * 2;
  1257.       if ((int)width > rowWidth)
  1258.         rowWidth = width;
  1259.     }
  1260.       if (fc->folder.inactPix != XmUNSPECIFIED_PIXMAP)
  1261.     {
  1262.       XGetGeometry(dpy, fc->folder.inactPix, &root, &x, &y,
  1263.                &inactPixWidth, &inactPixHeight, &pixBW, &pixDepth);
  1264.       fc->folder.inactPixWidth = inactPixWidth;
  1265.       if (inactPixWidth > fc->folder.maxPixWidth)
  1266.         fc->folder.maxPixWidth = inactPixWidth;
  1267.       fc->folder.inactPixHeight = inactPixHeight;
  1268.       if (inactPixHeight > fc->folder.maxPixHeight)
  1269.         fc->folder.maxPixHeight = inactPixHeight;
  1270.       width = co + st + inactPixWidth + 
  1271.         f->folder.marginHeight * 2 + ht * 2;
  1272.       if ((int)width > rowWidth)
  1273.         rowWidth = width;
  1274.     }
  1275.  
  1276.       /* increment rowY to move on to the next tab */
  1277.       rowY += st * 2 + co * 2 + f->folder.marginWidth * 2 + ht * 2 +
  1278.     XtHeight(tab) + tab->core.border_width * 2;
  1279.  
  1280.       if (fc->folder.maxPixHeight)
  1281.     rowY += fc->folder.maxPixHeight + f->folder.pixmapMargin;
  1282.       rowY += f->folder.spacing;
  1283.  
  1284.       tabNum++;
  1285.       fc->folder.row = rowNum;
  1286.     }
  1287.  
  1288.   /* complete calcuations for last row */
  1289.   if (rowY)
  1290.     rowY -= f->folder.spacing;
  1291.   rows[rowNum].x = rowX;
  1292.   rows[rowNum].height = rowY;
  1293.   rows[rowNum].width = rowWidth;
  1294.   rows[rowNum].numTabs = tabNum;
  1295.   numRows = rowNum + 1;
  1296.   if (f->folder.debugLevel)
  1297.     {
  1298.       fprintf(stderr, "XmLFolder: Layout: ");
  1299.       fprintf(stderr, "row %d: x %d w %d h %d numTabs %d\n",
  1300.           rowNum, rowX, rowWidth, rowY, tabNum);
  1301.     }
  1302.   f->folder.tabWidth = rowX + rowWidth;
  1303.   f->folder.tabBarHeight = f->folder.tabWidth;
  1304.   minWidth = f->folder.tabWidth;
  1305.   if ((int)minHeight < rowY)
  1306.     minHeight = rowY;
  1307.  
  1308.   /* add space for indent of upper rows */
  1309.   if (f->folder.tabsPerRow && minHeight)
  1310.     minHeight += 4;
  1311.  
  1312.   if (f->folder.debugLevel)
  1313.     {
  1314.       fprintf(stderr, "XmLFolder: Layout: ");
  1315.       fprintf(stderr, "tab bar minimum w %d h %d\n",
  1316.           (int)minWidth, (int)minHeight);
  1317.     }
  1318.  
  1319.   /* calculate width and height of non-tab children ensure */
  1320.   /* minWidth > width and minHeight > height */
  1321.   for (i = 0; i < f->composite.num_children; i++)
  1322.     {
  1323.       child = children[i];
  1324.       if (XtIsSubclass(child, xmPrimitiveWidgetClass))
  1325.     continue;
  1326.  
  1327.       height = XtHeight(child) + st * 2;
  1328.       if (XtIsWidget(child))
  1329.     height += f->core.border_width * 2;
  1330.       if (height > minHeight)
  1331.     minHeight = height;
  1332.  
  1333.       width = XtWidth(child) + f->folder.tabWidth + st * 2;
  1334.       if (XtIsWidget(child))
  1335.     width += f->core.border_width * 2;
  1336.       if (width > minWidth)
  1337.     minWidth = width;
  1338.     }
  1339.  
  1340.   if (f->folder.debugLevel)
  1341.     {
  1342.       fprintf(stderr, "XmLFolder: Layout: ");
  1343.       fprintf(stderr, "with non-tabs minimum w %d h %d\n",
  1344.           (int)minWidth, (int)minHeight);
  1345.     }
  1346.  
  1347.   /* Resize folder if needed */
  1348.   if (resizeIfNeeded && f->folder.resizePolicy != XmRESIZE_NONE)
  1349.     {
  1350.       if (minWidth <= 0)
  1351.     minWidth = 1;
  1352.       if (minHeight <= 0)
  1353.     minHeight = 1;
  1354.       result = XtMakeResizeRequest((Widget)f, minWidth, minHeight,
  1355.                    &width, &height);
  1356.       if (result == XtGeometryAlmost)
  1357.     XtMakeResizeRequest((Widget)f, width, height, NULL, NULL);
  1358.     }
  1359.   /* move active row to bottom */
  1360.   tab = f->folder.activeW;
  1361.   if (tab)
  1362.     {
  1363.       fc = (XmLFolderConstraintRec *)(tab->core.constraints);
  1364.       rowNum = fc->folder.row;
  1365.       f->folder.activeRow = rowNum;
  1366.       rows[rowNum].x = f->folder.tabWidth - rows[rowNum].width;
  1367.       for (i = rowNum + 1; i < numRows; i++)
  1368.     rows[i].x -= rows[rowNum].width;
  1369.     }
  1370.   else
  1371.     f->folder.activeRow = -1;
  1372.  
  1373.   /* configure tab children */
  1374.   for (i = 0; i < f->folder.tabCount; i++)
  1375.     {
  1376.       tab = f->folder.tabs[i];
  1377.       if (!XtIsManaged(tab))
  1378.     continue;
  1379.       fc = (XmLFolderConstraintRec *)(tab->core.constraints);
  1380.       rowNum = fc->folder.row;
  1381.  
  1382.       /* calculate tab x */
  1383.       if (fc->folder.firstInRow == True)
  1384.     {
  1385.       if (f->folder.tabsPerRow && rowNum != f->folder.activeRow)
  1386.         y = 2;
  1387.       else
  1388.         y = 0;
  1389.     }
  1390.       fc->folder.y = y;
  1391.       y += st + co + f->folder.marginWidth + ht;
  1392.       if (fc->folder.maxPixHeight)
  1393.     y += fc->folder.maxPixHeight + f->folder.pixmapMargin;
  1394.  
  1395.       /* calculate tab x and tab width */
  1396.       fc->folder.width = rows[rowNum].width;
  1397.       if (f->folder.tabPlacement == XmFOLDER_LEFT)
  1398.     {
  1399.       fc->folder.x = rows[rowNum].x;
  1400.       x = fc->folder.x + fc->folder.width - f->folder.marginHeight -
  1401.         ht - XtWidth(tab) - tab->core.border_width * 2;
  1402.     }
  1403.       else
  1404.     {
  1405.       fc->folder.x = f->core.width - rows[rowNum].x -
  1406.         rows[rowNum].width;
  1407.       x = fc->folder.x + f->folder.marginHeight + ht;
  1408.     }
  1409.  
  1410.       /* calculate tab padding */
  1411.       pad1 = 0;
  1412.       pad2 = 0;
  1413.       h = f->core.height - rows[rowNum].height;
  1414.       if (rowNum != f->folder.activeRow)
  1415.     h -= 4;
  1416.       if (f->folder.tabsPerRow && h > 0)
  1417.     {
  1418.       pad1 = h / (rows[rowNum].numTabs * 2);
  1419.       pad2 = pad1;
  1420.       if (fc->folder.firstInRow == True)
  1421.         pad2 += h - (pad1 * rows[rowNum].numTabs * 2);
  1422.     }
  1423.       y += pad1;
  1424.  
  1425.       /* move tab widget into place */
  1426.       XtMoveWidget(tab, x, y);
  1427.  
  1428.       /* calculate tab height and move to next tab */
  1429.       y += pad2 + XtHeight(tab) + tab->core.border_width * 2 + ht +
  1430.     f->folder.marginWidth + co + st;
  1431.       fc->folder.height = y - fc->folder.y; 
  1432.       y += f->folder.spacing;
  1433.     }
  1434.  
  1435.   /* configure non-tab children */
  1436.   for (i = 0; i < f->composite.num_children; i++)
  1437.     {
  1438.       child = children[i];
  1439.       if (XtIsSubclass(child, xmPrimitiveWidgetClass))
  1440.     continue;
  1441.       if (f->folder.resizePolicy == XmRESIZE_NONE)
  1442.     continue;
  1443.  
  1444.       w = (int)f->core.width - (int)f->folder.tabWidth - st * 2;
  1445.       h = (int)f->core.height - st * 2;
  1446.       if (h <= 0 || w <= 0)
  1447.     continue;
  1448.       /* manager widgets will not configure correctly unless they */
  1449.       /* are managed, so manage then unmapped if they are unmanaged */
  1450.       isManaged = True;
  1451.       if (!XtIsManaged(child))
  1452.     {
  1453.       XtVaGetValues(child,
  1454.             XmNmappedWhenManaged, &map,
  1455.             NULL);
  1456.       XtVaSetValues(child,
  1457.             XmNmappedWhenManaged, False,
  1458.             NULL);
  1459.       XtManageChild(child);
  1460.       isManaged = False;
  1461.     }
  1462.       y = st;
  1463.       if (f->folder.tabPlacement == XmFOLDER_LEFT)
  1464.     x = f->folder.tabWidth + st;
  1465.       else
  1466.     x = st;
  1467.       width = w;
  1468.       height = h;
  1469.       borderWidth = 0;
  1470.       if (XtIsWidget(child))
  1471.     borderWidth = child->core.border_width;
  1472.       XtConfigureWidget(child, x, y, width, height, borderWidth);
  1473.       if (isManaged == False)
  1474.     {
  1475.       XtUnmanageChild(child);
  1476.       XtVaSetValues(child, XmNmappedWhenManaged, map, NULL);
  1477.     }
  1478.     }
  1479. }
  1480.  
  1481. static void 
  1482. Resize(Widget w)
  1483. {
  1484.   XmLFolderWidget f;
  1485.  
  1486.   f = (XmLFolderWidget)w;
  1487.   Layout(f, 0);
  1488. }
  1489.  
  1490. static XtGeometryResult 
  1491. GeometryManager(Widget w, 
  1492.         XtWidgetGeometry *request, 
  1493.         XtWidgetGeometry *allow)
  1494. {
  1495.   XmLFolderWidget f;
  1496.  
  1497.   f = (XmLFolderWidget)XtParent(w);
  1498.   if (f->folder.resizePolicy != XmRESIZE_STATIC ||
  1499.       XtIsSubclass(w, xmPrimitiveWidgetClass))
  1500.     {
  1501.       if (request->request_mode & CWWidth)
  1502.     w->core.width = request->width;
  1503.       if (request->request_mode & CWHeight)
  1504.     w->core.height = request->height;
  1505.       if (request->request_mode & CWX)
  1506.     w->core.x = request->x;
  1507.       if (request->request_mode & CWY)
  1508.     w->core.y = request->y;
  1509.       if (request->request_mode & CWBorderWidth)
  1510.     w->core.border_width = request->border_width;
  1511.       Layout(f, 1);
  1512.       return XtGeometryYes;
  1513.     }
  1514.   return XtGeometryNo;
  1515. }
  1516.  
  1517. static void 
  1518. ChangeManaged(Widget w)
  1519. {
  1520.   XmLFolderWidget f;
  1521.  
  1522.   f = (XmLFolderWidget)w;
  1523.   Layout(f, 1);
  1524.   _XmNavigChangeManaged(w);
  1525. }
  1526.  
  1527. static void 
  1528. ConstraintInitialize(Widget req, 
  1529.              Widget w, 
  1530.              ArgList args, 
  1531.              Cardinal *narg)
  1532. {
  1533.   XmLFolderWidget f;
  1534.   XmLFolderConstraintRec *fc;
  1535.  
  1536.   if (!XtIsRectObj(w))
  1537.     return;
  1538.   f = (XmLFolderWidget)XtParent(w);
  1539.   if (f->folder.debugLevel)
  1540.     fprintf(stderr, "XmLFolder: Constraint Init\n");
  1541.   fc = (XmLFolderConstraintRec *)(w->core.constraints);
  1542.   fc->folder.x = 0;
  1543.   fc->folder.y = 0;
  1544.   fc->folder.width = 0;
  1545.   fc->folder.height = 0;
  1546.   fc->folder.maxPixWidth = 0;
  1547.   fc->folder.maxPixHeight = 0;
  1548.   fc->folder.row = -1;
  1549.   fc->folder.firstInRow = False;
  1550.   if (fc->folder.managedName)
  1551.     fc->folder.managedName = (char *)strdup(fc->folder.managedName);
  1552.   if (XtIsSubclass(w, xmPrimitiveWidgetClass))
  1553.     {
  1554.       XtOverrideTranslations(w, f->folder.primTrans);
  1555.       XtAddCallback(w, XmNactivateCallback, PrimActivate, 0);
  1556.       XtVaSetValues(w,
  1557.             XmNhighlightThickness, 0,
  1558.             XmNshadowThickness, 0,
  1559.             NULL);
  1560.       if (XtIsSubclass(w, xmLabelWidgetClass))
  1561.     XtVaSetValues(w, XmNfillOnArm, False, NULL);
  1562.  
  1563.       /* add child to tabs list */
  1564.       if (f->folder.tabAllocCount < f->folder.tabCount + 1)
  1565.     {
  1566.       f->folder.tabAllocCount *= 2;
  1567.       f->folder.tabs = (Widget *)realloc((char *)f->folder.tabs,
  1568.                          sizeof(Widget) * f->folder.tabAllocCount);
  1569.     }
  1570.       f->folder.tabs[f->folder.tabCount++] = w;
  1571.  
  1572.     }
  1573.   if (XmIsDrawnButton(w))
  1574.     SetTabPlacement(f, w);
  1575.  
  1576. #ifdef XmLEVAL
  1577.   if (f->folder.tabCount > 6)
  1578.     {
  1579.       fprintf(stderr, "XmL: evaluation version only supports <= 6 tabs\n");
  1580.       exit(0);
  1581.     }
  1582. #endif
  1583. }
  1584.  
  1585. static void 
  1586. ConstraintDestroy(Widget w)
  1587. {
  1588.   XmLFolderWidget f;
  1589.   XmLFolderConstraintRec *fc;
  1590.   int i, j, activePos;
  1591.     
  1592.   if (!XtIsRectObj(w))
  1593.     return;
  1594.   f = (XmLFolderWidget)XtParent(w);
  1595.   if (f->folder.debugLevel)
  1596.     fprintf(stderr, "XmLFolder: Constraint Destroy\n");
  1597.   if (f->folder.focusW == w)
  1598.     f->folder.focusW = 0;
  1599.   fc = (XmLFolderConstraintRec *)(w->core.constraints);
  1600.   if (fc->folder.managedName)
  1601.     free((char *)fc->folder.managedName);
  1602.   if (fc->folder.freePix == True)
  1603.     {
  1604.       if (fc->folder.pix != XmUNSPECIFIED_PIXMAP)
  1605.     XFreePixmap(XtDisplay(w), fc->folder.pix);
  1606.       if (fc->folder.inactPix != XmUNSPECIFIED_PIXMAP)
  1607.     XFreePixmap(XtDisplay(w), fc->folder.inactPix);
  1608.     }
  1609.   if (XtIsSubclass(w, xmPrimitiveWidgetClass))
  1610.     {
  1611.       XtRemoveCallback(w, XmNactivateCallback, PrimActivate, 0);
  1612.  
  1613.       /* remove child from tabs list and calculate active pos */
  1614.       activePos = -1;
  1615.       j = 0;
  1616.       for (i = 0; i < f->folder.tabCount; i++)
  1617.     if (f->folder.tabs[i] != w)
  1618.       {
  1619.         if (f->folder.activeW == f->folder.tabs[i])
  1620.           activePos = j;
  1621.         f->folder.tabs[j++] = f->folder.tabs[i];
  1622.       }
  1623.       if (j != f->folder.tabCount - 1)
  1624.     XmLWarning((Widget)f, "ConstraintDestroy() - bad child list");
  1625.       f->folder.tabCount = j;
  1626.       f->folder.activeTab = activePos;
  1627.       if (activePos == -1)
  1628.     f->folder.activeW = 0;
  1629.     }
  1630. }
  1631.  
  1632. static void 
  1633. DrawTabPixmap(XmLFolderWidget f, 
  1634.           Widget tab, 
  1635.           int active)
  1636. {
  1637.   Display *dpy;
  1638.   Window win;
  1639.   int x, y;
  1640.   Pixmap pixmap;
  1641.   Dimension pixWidth, pixHeight, ht; 
  1642.   XmLFolderConstraintRec *fc;
  1643.  
  1644.   x = 0;
  1645.   y = 0;
  1646.   dpy = XtDisplay(f);
  1647.   win = XtWindow(f);
  1648.   fc = (XmLFolderConstraintRec *)(tab->core.constraints);
  1649.   ht = f->folder.highlightThickness;
  1650.   if (active)
  1651.     {
  1652.       pixWidth = fc->folder.pixWidth;
  1653.       pixHeight = fc->folder.pixHeight;
  1654.       pixmap = fc->folder.pix;
  1655.     }
  1656.   else
  1657.     {
  1658.       pixWidth = fc->folder.inactPixWidth;
  1659.       pixHeight = fc->folder.inactPixHeight;
  1660.       pixmap = fc->folder.inactPix;
  1661.     }
  1662.   if (f->folder.tabPlacement == XmFOLDER_TOP)
  1663.     {
  1664.       x = tab->core.x - pixWidth - ht - f->folder.pixmapMargin;
  1665.       y = tab->core.y + tab->core.height - pixHeight; 
  1666.     }
  1667.   else if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  1668.     {
  1669.       x = tab->core.x - fc->folder.pixWidth - ht - f->folder.pixmapMargin;
  1670.       y = tab->core.y;
  1671.     }
  1672.   else if (f->folder.tabPlacement == XmFOLDER_LEFT)
  1673.     {
  1674.       x = tab->core.x + tab->core.width - pixWidth;
  1675.       y = tab->core.y - pixHeight - f->folder.pixmapMargin - ht;
  1676.     }
  1677.   else if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  1678.     {
  1679.       x = tab->core.x;
  1680.       y = tab->core.y - pixHeight - f->folder.pixmapMargin - ht;
  1681.     }
  1682.   XCopyArea(dpy, pixmap, win, f->folder.gc, 0, 0, pixWidth, pixHeight, x, y);
  1683. }
  1684.  
  1685. static void 
  1686. DrawManagerShadowTopBottom(XmLFolderWidget f, 
  1687.                XRectangle *rect)
  1688. {
  1689.   Display *dpy;
  1690.   Window win;
  1691.   XmLFolderConstraintRec *fc;
  1692.   XSegment *topSeg, *botSeg;
  1693.   int i, bCount, tCount, st, botOff;
  1694.  
  1695.   dpy = XtDisplay(f);
  1696.   win = XtWindow(f);
  1697.   st = f->manager.shadow_thickness;
  1698.   if (!st)
  1699.     return;
  1700.   botOff = f->core.height - f->folder.tabHeight - 1;
  1701.  
  1702.   topSeg = (XSegment *)malloc(sizeof(XSegment) * st * 2);
  1703.   botSeg = (XSegment *)malloc(sizeof(XSegment) * st * 2);
  1704.  
  1705.   /* top shadow */
  1706.   fc = 0;
  1707.   if (f->folder.activeW)
  1708.     fc = (XmLFolderConstraintRec *)(f->folder.activeW->core.constraints);
  1709.   tCount = 0;
  1710.   if (fc)
  1711.     for (i = 0; i < st; i++)
  1712.       {
  1713.     topSeg[tCount].x1 = rect->x + i;
  1714.     topSeg[tCount].y1 = rect->y + i;
  1715.     topSeg[tCount].x2 = fc->folder.x + i;
  1716.     topSeg[tCount].y2 = rect->y + i;
  1717.     if (rect->x != fc->folder.x)
  1718.       tCount++;
  1719.     topSeg[tCount].x1 = rect->x + fc->folder.x +
  1720.       fc->folder.width - i - 1;
  1721.     topSeg[tCount].y1 = rect->y + i;
  1722.     topSeg[tCount].x2 = rect->x + rect->width - i - 1;
  1723.     topSeg[tCount].y2 = rect->y + i;
  1724.     if (fc->folder.x + fc->folder.width != rect->width)
  1725.       tCount++;
  1726.       }
  1727.   else
  1728.     for (i = 0; i < st; i++)
  1729.       {
  1730.     topSeg[tCount].x1 = rect->x + i;
  1731.     topSeg[tCount].y1 = rect->y + i;
  1732.     topSeg[tCount].x2 = rect->x + rect->width - i - 1;
  1733.     topSeg[tCount].y2 = rect->y + i;
  1734.     tCount++;
  1735.       }
  1736.   if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  1737.     for (i = 0 ; i < tCount; i++)
  1738.       {
  1739.     topSeg[i].y1 = botOff - topSeg[i].y1;
  1740.     topSeg[i].y2 = botOff - topSeg[i].y2;
  1741.       }
  1742.   if (tCount)
  1743.     {
  1744.       if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  1745.     SetGC(f, GC_SHADOWBOT);
  1746.       else    
  1747.     SetGC(f, GC_SHADOWTOP);
  1748.       XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
  1749.       SetGC(f, GC_UNSET);
  1750.     }
  1751.  
  1752.   /* left shadow */
  1753.   tCount = 0;
  1754.   for (i = 0; i < st; i++)
  1755.     {
  1756.       topSeg[tCount].x1 = rect->x + i;
  1757.       topSeg[tCount].y1 = rect->y + i;
  1758.       topSeg[tCount].x2 = rect->x + i;
  1759.       topSeg[tCount].y2 = rect->y + rect->height - i - 1;
  1760.       tCount++;
  1761.     }
  1762.   if (tCount)
  1763.     {
  1764.       SetGC(f, GC_SHADOWTOP);
  1765.       XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
  1766.       SetGC(f, GC_UNSET);
  1767.     }
  1768.  
  1769.   /* right shadow */
  1770.   bCount = 0;
  1771.   for (i = 0; i < st; i++)
  1772.     {
  1773.       botSeg[bCount].x1 = rect->x + rect->width - i - 1;
  1774.       botSeg[bCount].y1 = rect->y + i;
  1775.       botSeg[bCount].x2 = rect->x + rect->width - i - 1;
  1776.       botSeg[bCount].y2 = rect->y + rect->height - i - 1;
  1777.       bCount++;
  1778.     }
  1779.   if (bCount)
  1780.     {
  1781.       SetGC(f, GC_SHADOWBOT);
  1782.       XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
  1783.       SetGC(f, GC_UNSET);
  1784.     }
  1785.  
  1786.   /* bottom shadow */
  1787.   bCount = 0;
  1788.   for (i = 0; i < st; i++)
  1789.     {
  1790.       botSeg[bCount].x1 = rect->x + i;
  1791.       botSeg[bCount].y1 = rect->y + rect->height - i - 1;
  1792.       botSeg[bCount].x2 = rect->x + rect->width - i - 1;
  1793.       botSeg[bCount].y2 = rect->y + rect->height - i - 1;
  1794.       if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  1795.     {
  1796.       botSeg[bCount].y1 = botOff - botSeg[bCount].y1;
  1797.       botSeg[bCount].y2 = botOff - botSeg[bCount].y2;
  1798.     }
  1799.       bCount++;
  1800.     }
  1801.   if (bCount)
  1802.     {
  1803.       if (f->folder.tabPlacement == XmFOLDER_TOP)
  1804.     SetGC(f, GC_SHADOWBOT);
  1805.       else    
  1806.     SetGC(f, GC_SHADOWTOP);
  1807.       XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
  1808.       SetGC(f, GC_UNSET);
  1809.     }
  1810.   free((char *)topSeg);
  1811.   free((char *)botSeg);
  1812. }
  1813.  
  1814. static void 
  1815. DrawManagerShadowLeftRight(XmLFolderWidget f, 
  1816.                XRectangle *rect)
  1817. {
  1818.   Display *dpy;
  1819.   Window win;
  1820.   XmLFolderConstraintRec *fc;
  1821.   XSegment *topSeg, *botSeg;
  1822.   int i, bCount, tCount, st, rightOff;
  1823.  
  1824.   dpy = XtDisplay(f);
  1825.   win = XtWindow(f);
  1826.   st = f->manager.shadow_thickness;
  1827.   if (!st)
  1828.     return;
  1829.   rightOff = f->core.width - f->folder.tabWidth - 1;
  1830.  
  1831.   topSeg = (XSegment *)malloc(sizeof(XSegment) * st * 2);
  1832.   botSeg = (XSegment *)malloc(sizeof(XSegment) * st * 2);
  1833.  
  1834.   /* left shadow */
  1835.   fc = 0;
  1836.   if (f->folder.activeW)
  1837.     fc = (XmLFolderConstraintRec *)(f->folder.activeW->core.constraints);
  1838.   tCount = 0;
  1839.   if (fc)
  1840.     for (i = 0; i < st; i++)
  1841.       {
  1842.     topSeg[tCount].x1 = rect->x + i;
  1843.     topSeg[tCount].y1 = rect->y + i;
  1844.     topSeg[tCount].x2 = rect->x + i;
  1845.     topSeg[tCount].y2 = fc->folder.y + i;
  1846.     if (rect->y != fc->folder.y)
  1847.       tCount++;
  1848.     topSeg[tCount].x1 = rect->x + i;
  1849.     topSeg[tCount].y1 = rect->y + fc->folder.y +
  1850.       fc->folder.height - i - 1;
  1851.     topSeg[tCount].x2 = rect->x + i;
  1852.     topSeg[tCount].y2 = rect->y + rect->height - i - 1;
  1853.     if (fc->folder.y + fc->folder.height != rect->height)
  1854.       tCount++;
  1855.       }
  1856.   else
  1857.     for (i = 0; i < st; i++)
  1858.       {
  1859.     topSeg[tCount].x1 = rect->x + i;
  1860.     topSeg[tCount].y1 = rect->y + i;
  1861.     topSeg[tCount].x2 = rect->x + i;
  1862.     topSeg[tCount].y2 = rect->y + rect->height - i - 1;
  1863.     tCount++;
  1864.       }
  1865.   if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  1866.     for (i = 0 ; i < tCount; i++)
  1867.       {
  1868.     topSeg[i].x1 = rightOff - topSeg[i].x1;
  1869.     topSeg[i].x2 = rightOff - topSeg[i].x2;
  1870.       }
  1871.   if (tCount)
  1872.     {
  1873.       if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  1874.     SetGC(f, GC_SHADOWBOT);
  1875.       else    
  1876.     SetGC(f, GC_SHADOWTOP);
  1877.       XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
  1878.       SetGC(f, GC_UNSET);
  1879.     }
  1880.  
  1881.   /* top shadow */
  1882.   tCount = 0;
  1883.   for (i = 0; i < st; i++)
  1884.     {
  1885.       topSeg[tCount].x1 = rect->x + i;
  1886.       topSeg[tCount].y1 = rect->y + i;
  1887.       topSeg[tCount].x2 = rect->x + rect->width - i - 1;
  1888.       topSeg[tCount].y2 = rect->y + i;
  1889.       tCount++;
  1890.     }
  1891.   if (tCount)
  1892.     {
  1893.       SetGC(f, GC_SHADOWTOP);
  1894.       XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
  1895.       SetGC(f, GC_UNSET);
  1896.     }
  1897.  
  1898.   /* bottom shadow */
  1899.   bCount = 0;
  1900.   for (i = 0; i < st; i++)
  1901.     {
  1902.       botSeg[bCount].x1 = rect->x + i;
  1903.       botSeg[bCount].y1 = rect->y + rect->height - i - 1;
  1904.       botSeg[bCount].x2 = rect->x + rect->width - i - 1;
  1905.       botSeg[bCount].y2 = rect->y + rect->height - i - 1;
  1906.       bCount++;
  1907.     }
  1908.   if (bCount)
  1909.     {
  1910.       SetGC(f, GC_SHADOWBOT);
  1911.       XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
  1912.       SetGC(f, GC_UNSET);
  1913.     }
  1914.  
  1915.   /* right shadow */
  1916.   bCount = 0;
  1917.   for (i = 0; i < st; i++)
  1918.     {
  1919.       botSeg[bCount].x1 = rect->x + rect->width - i - 1;
  1920.       botSeg[bCount].y1 = rect->y + i;
  1921.       botSeg[bCount].x2 = rect->x + rect->width - i - 1;
  1922.       botSeg[bCount].y2 = rect->y + rect->height - i - 1;
  1923.       if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  1924.     {
  1925.       botSeg[bCount].x1 = rightOff - botSeg[bCount].x1;
  1926.       botSeg[bCount].x2 = rightOff - botSeg[bCount].x2;
  1927.     }
  1928.       bCount++;
  1929.     }
  1930.   if (bCount)
  1931.     {
  1932.       if (f->folder.tabPlacement == XmFOLDER_LEFT)
  1933.     SetGC(f, GC_SHADOWBOT);
  1934.       else    
  1935.     SetGC(f, GC_SHADOWTOP);
  1936.       XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
  1937.       SetGC(f, GC_UNSET);
  1938.     }
  1939.   free((char *)topSeg);
  1940.   free((char *)botSeg);
  1941. }
  1942.  
  1943. static void 
  1944. DrawTabShadowArcTopBottom(XmLFolderWidget f,
  1945.               Widget w)
  1946. {
  1947.   XmLFolderConstraintRec *fc;
  1948.   Display *dpy;
  1949.   Window win;
  1950.   XSegment *topSeg, *botSeg;
  1951.   XRectangle rect, rect2;
  1952.   XArc arc;
  1953.   int tCount, bCount;
  1954.   int i, st, cd, botOff;
  1955.  
  1956.   dpy = XtDisplay(f);
  1957.   win = XtWindow(f);
  1958.   fc = (XmLFolderConstraintRec *)(w->core.constraints);
  1959.   botOff = 2 * fc->folder.y + fc->folder.height - 1;
  1960.   st = f->manager.shadow_thickness;
  1961.   if (!st)
  1962.     return;
  1963.   cd = f->folder.cornerDimension;
  1964.  
  1965.   tCount = 0;
  1966.   bCount = 0;
  1967.   topSeg = (XSegment *)malloc(sizeof(XSegment) * st);
  1968.   botSeg = (XSegment *)malloc(sizeof(XSegment) * st);
  1969.   for (i = 0; i < st; i++)
  1970.     {
  1971.       /* left tab shadow */
  1972.       topSeg[tCount].x1 = fc->folder.x + i;
  1973.       topSeg[tCount].y1 = fc->folder.y + cd + st;
  1974.       topSeg[tCount].x2 = fc->folder.x + i;
  1975.       topSeg[tCount].y2 = fc->folder.y + fc->folder.height - 1;
  1976.       if (w == f->folder.activeW)
  1977.     topSeg[tCount].y2 += i;
  1978.       if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  1979.     {
  1980.       topSeg[tCount].y1 = botOff - topSeg[tCount].y1;
  1981.       topSeg[tCount].y2 = botOff - topSeg[tCount].y2;
  1982.     }
  1983.       tCount++;
  1984.  
  1985.       /* right tab shadow */
  1986.       botSeg[bCount].x1 = fc->folder.x + fc->folder.width - i - 1;
  1987.       botSeg[bCount].y1 = fc->folder.y + cd + st;
  1988.       botSeg[bCount].x2 = fc->folder.x + fc->folder.width - i - 1;
  1989.       botSeg[bCount].y2 = fc->folder.y + fc->folder.height - 1;
  1990.       if (w == f->folder.activeW)
  1991.     botSeg[bCount].y2 += i;
  1992.       if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  1993.     {
  1994.       botSeg[bCount].y1 = botOff - botSeg[bCount].y1;
  1995.       botSeg[bCount].y2 = botOff - botSeg[bCount].y2;
  1996.     }
  1997.       bCount++;
  1998.     }
  1999.   if (tCount)
  2000.     {
  2001.       SetGC(f, GC_SHADOWTOP);
  2002.       XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
  2003.       SetGC(f, GC_UNSET);
  2004.     }
  2005.   if (bCount)
  2006.     {
  2007.       SetGC(f, GC_SHADOWBOT);
  2008.       XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
  2009.       SetGC(f, GC_UNSET);
  2010.     }
  2011.   tCount = 0;
  2012.   for (i = 0; i < st; i++)
  2013.     {
  2014.       /* top tab shadow */
  2015.       topSeg[tCount].x1 = fc->folder.x + cd + st;
  2016.       topSeg[tCount].y1 = fc->folder.y + i;
  2017.       topSeg[tCount].x2 = fc->folder.x + fc->folder.width - cd - st - 1;
  2018.       topSeg[tCount].y2 = fc->folder.y + i;
  2019.       if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  2020.     {
  2021.       topSeg[tCount].y1 = botOff - topSeg[tCount].y1;
  2022.       topSeg[tCount].y2 = botOff - topSeg[tCount].y2;
  2023.     }
  2024.       tCount++;
  2025.     }
  2026.   if (tCount)
  2027.     {
  2028.       if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  2029.     SetGC(f, GC_SHADOWBOT);
  2030.       else
  2031.     SetGC(f, GC_SHADOWTOP);
  2032.       XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
  2033.       SetGC(f, GC_UNSET);
  2034.     }
  2035.   free((char *)topSeg);
  2036.   free((char *)botSeg);
  2037.  
  2038.   /* left corner blank background */
  2039.   rect.x = fc->folder.x;
  2040.   rect.y = fc->folder.y;
  2041.   rect.width = cd + st;
  2042.   rect.height = cd + st;
  2043.   if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  2044.     rect.y = fc->folder.y + fc->folder.height - rect.height;
  2045.   SetGC(f, GC_BLANK);
  2046.   XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
  2047.          rect.width, rect.height);
  2048.   SetGC(f, GC_UNSET);
  2049.  
  2050.   /* left arc */
  2051.   /* various X Servers have problems drawing arcs - so set clip rect */
  2052.   /* and draw two circles, one smaller than the other, for corner */
  2053.   XSetClipRectangles(dpy, f->folder.gc, 0, 0, &rect, 1, Unsorted);
  2054.   arc.x = rect.x;
  2055.   arc.y = rect.y;
  2056.   arc.width = rect.width * 2;
  2057.   arc.height = rect.height * 2;
  2058.   if (f->folder.serverDrawsArcsLarge == True)
  2059.     {
  2060.       arc.width -= 1;
  2061.       arc.height -= 1;
  2062.     }
  2063.   arc.angle1 = 0 * 64;
  2064.   arc.angle2 = 360 * 64;
  2065.   if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  2066.     arc.y = fc->folder.y + fc->folder.height - arc.height;
  2067.   SetGC(f, GC_SHADOWTOP);
  2068.   XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
  2069.        arc.angle1, arc.angle2);
  2070.   XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
  2071.        arc.angle1, arc.angle2);
  2072.   SetGC(f, GC_UNSET);
  2073.  
  2074.   rect2 = rect;
  2075.   rect2.x += st;
  2076.   rect2.width -= st;
  2077.   rect2.height -= st;
  2078.   if (f->folder.tabPlacement == XmFOLDER_TOP)
  2079.     rect2.y += st;
  2080.   XSetClipRectangles(dpy, f->folder.gc, 0, 0, &rect2, 1, Unsorted);
  2081.   if (w == f->folder.activeW)
  2082.     XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
  2083.   else
  2084.     XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
  2085.   arc.x += st;
  2086.   arc.y += st;
  2087.   arc.width -= st * 2;
  2088.   arc.height -= st * 2;
  2089.   XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
  2090.        arc.angle1, arc.angle2);
  2091.   XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
  2092.        arc.angle1, arc.angle2);
  2093.   XSetClipMask(dpy, f->folder.gc, None);
  2094.  
  2095.   /* right corner blank background */
  2096.   rect.x = fc->folder.x + fc->folder.width - cd - st;
  2097.   SetGC(f, GC_BLANK);
  2098.   XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
  2099.          rect.width, rect.height);
  2100.   SetGC(f, GC_UNSET);
  2101.  
  2102.   /* right arc */
  2103.   XSetClipRectangles(dpy, f->folder.gc, 0, 0, &rect, 1, Unsorted);
  2104.   arc.x = rect.x - cd - st;
  2105.   arc.y = rect.y;
  2106.   arc.width = rect.width * 2;
  2107.   arc.height = rect.height * 2;
  2108.   if (f->folder.serverDrawsArcsLarge == True)
  2109.     {
  2110.       arc.width -= 1;
  2111.       arc.height -= 1;
  2112.     }
  2113.   arc.angle1 = 0 * 64;
  2114.   arc.angle2 = 360 * 64;
  2115.   if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  2116.     arc.y = fc->folder.y + fc->folder.height - arc.height;
  2117.   SetGC(f, GC_SHADOWBOT);
  2118.   XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
  2119.        arc.angle1, arc.angle2);
  2120.   XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
  2121.        arc.angle1, arc.angle2);
  2122.   SetGC(f, GC_UNSET);
  2123.  
  2124.   rect2 = rect;
  2125.   rect2.width -= st;
  2126.   rect2.height -= st;
  2127.   if (f->folder.tabPlacement == XmFOLDER_TOP)
  2128.     rect2.y += st;
  2129.   XSetClipRectangles(dpy, f->folder.gc, 0, 0, &rect2, 1, Unsorted);
  2130.   if (w == f->folder.activeW)
  2131.     XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
  2132.   else
  2133.     XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
  2134.   arc.x += st;
  2135.   arc.y += st;
  2136.   arc.width -= st * 2;
  2137.   arc.height -= st * 2;
  2138.   XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
  2139.        arc.angle1, arc.angle2);
  2140.   XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
  2141.        arc.angle1, arc.angle2);
  2142.   XSetClipMask(dpy, f->folder.gc, None);
  2143. }
  2144.  
  2145. static void 
  2146. DrawTabShadowArcLeftRight(XmLFolderWidget f,
  2147.               Widget w)
  2148. {
  2149.   XmLFolderConstraintRec *fc;
  2150.   Display *dpy;
  2151.   Window win;
  2152.   XSegment *topSeg, *botSeg;
  2153.   XRectangle rect, rect2;
  2154.   XArc arc;
  2155.   int tCount, bCount;
  2156.   int i, st, cd, rightOff;
  2157.  
  2158.   dpy = XtDisplay(f);
  2159.   win = XtWindow(f);
  2160.   fc = (XmLFolderConstraintRec *)(w->core.constraints);
  2161.   rightOff = 2 * fc->folder.x + fc->folder.width - 1;
  2162.   st = f->manager.shadow_thickness;
  2163.   if (!st)
  2164.     return;
  2165.   cd = f->folder.cornerDimension;
  2166.  
  2167.   tCount = 0;
  2168.   bCount = 0;
  2169.   topSeg = (XSegment *)malloc(sizeof(XSegment) * st);
  2170.   botSeg = (XSegment *)malloc(sizeof(XSegment) * st);
  2171.   for (i = 0; i < st; i++)
  2172.     {
  2173.       /* top tab shadow */
  2174.       topSeg[tCount].x1 = fc->folder.x + cd + st;
  2175.       topSeg[tCount].y1 = fc->folder.y + i;
  2176.       topSeg[tCount].x2 = fc->folder.x + fc->folder.width - 1;
  2177.       if (w == f->folder.activeW)
  2178.     topSeg[tCount].x2 += i;
  2179.       topSeg[tCount].y2 = fc->folder.y + i;
  2180.       if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  2181.     {
  2182.       topSeg[tCount].x1 = rightOff - topSeg[tCount].x1;
  2183.       topSeg[tCount].x2 = rightOff - topSeg[tCount].x2;
  2184.     }
  2185.       tCount++;
  2186.  
  2187.       /* bottom tab shadow */
  2188.       botSeg[bCount].x1 = fc->folder.x + cd + st;
  2189.       botSeg[bCount].y1 = fc->folder.y + fc->folder.height - i - 1;
  2190.       botSeg[bCount].x2 = fc->folder.x + fc->folder.width - 1;
  2191.       if (w == f->folder.activeW)
  2192.     botSeg[bCount].x2 += i;
  2193.       botSeg[bCount].y2 = fc->folder.y + fc->folder.height - i - 1;
  2194.       if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  2195.     {
  2196.       botSeg[bCount].x1 = rightOff - botSeg[bCount].x1;
  2197.       botSeg[bCount].x2 = rightOff - botSeg[bCount].x2;
  2198.     }
  2199.       bCount++;
  2200.     }
  2201.   if (tCount)
  2202.     {
  2203.       SetGC(f, GC_SHADOWTOP);
  2204.       XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
  2205.       SetGC(f, GC_UNSET);
  2206.     }
  2207.   if (bCount)
  2208.     {
  2209.       SetGC(f, GC_SHADOWBOT);
  2210.       XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
  2211.       SetGC(f, GC_UNSET);
  2212.     }
  2213.   tCount = 0;
  2214.   for (i = 0; i < st; i++)
  2215.     {
  2216.       /* left tab shadow */
  2217.       topSeg[tCount].x1 = fc->folder.x + i;
  2218.       topSeg[tCount].y1 = fc->folder.y + cd + st;
  2219.       topSeg[tCount].x2 = fc->folder.x + i;
  2220.       topSeg[tCount].y2 = fc->folder.y + fc->folder.height - cd - st - 1;
  2221.       if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  2222.     {
  2223.       topSeg[tCount].x1 = rightOff - topSeg[tCount].x1;
  2224.       topSeg[tCount].x2 = rightOff - topSeg[tCount].x2;
  2225.     }
  2226.       tCount++;
  2227.     }
  2228.   if (tCount)
  2229.     {
  2230.       if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  2231.     SetGC(f, GC_SHADOWBOT);
  2232.       else
  2233.     SetGC(f, GC_SHADOWTOP);
  2234.       XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
  2235.       SetGC(f, GC_UNSET);
  2236.     }
  2237.   free((char *)topSeg);
  2238.   free((char *)botSeg);
  2239.  
  2240.   /* top corner blank background */
  2241.   rect.x = fc->folder.x;
  2242.   rect.y = fc->folder.y;
  2243.   rect.width = cd + st;
  2244.   rect.height = cd + st;
  2245.   if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  2246.     rect.x = fc->folder.x + fc->folder.width - rect.width;
  2247.   SetGC(f, GC_BLANK);
  2248.   XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
  2249.          rect.width, rect.height);
  2250.   SetGC(f, GC_UNSET);
  2251.  
  2252.   /* top arc */
  2253.   XSetClipRectangles(dpy, f->folder.gc, 0, 0, &rect, 1, Unsorted);
  2254.   arc.x = rect.x;
  2255.   arc.y = rect.y;
  2256.   arc.width = rect.width * 2;
  2257.   arc.height = rect.height * 2;
  2258.   if (f->folder.serverDrawsArcsLarge == True)
  2259.     {
  2260.       arc.width -= 1;
  2261.       arc.height -= 1;
  2262.     }
  2263.   arc.angle1 = 0 * 64;
  2264.   arc.angle2 = 360 * 64;
  2265.   if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  2266.     arc.x = fc->folder.x + fc->folder.width - arc.width;
  2267.   SetGC(f, GC_SHADOWTOP);
  2268.   XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
  2269.        arc.angle1, arc.angle2);
  2270.   XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
  2271.        arc.angle1, arc.angle2);
  2272.   SetGC(f, GC_UNSET);
  2273.  
  2274.   rect2 = rect;
  2275.   rect2.width -= st;
  2276.   rect2.height -= st;
  2277.   rect2.y += st;
  2278.   if (f->folder.tabPlacement == XmFOLDER_LEFT)
  2279.     rect2.x += st;
  2280.   XSetClipRectangles(dpy, f->folder.gc, 0, 0, &rect2, 1, Unsorted);
  2281.   if (w == f->folder.activeW)
  2282.     XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
  2283.   else
  2284.     XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
  2285.   arc.x += st;
  2286.   arc.y += st;
  2287.   arc.width -= st * 2;
  2288.   arc.height -= st * 2;
  2289.   XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
  2290.        arc.angle1, arc.angle2);
  2291.   XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
  2292.        arc.angle1, arc.angle2);
  2293.   XSetClipMask(dpy, f->folder.gc, None);
  2294.  
  2295.   /* bottom corner blank background */
  2296.   rect.y = fc->folder.y + fc->folder.height - cd - st;
  2297.   SetGC(f, GC_BLANK);
  2298.   XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
  2299.          rect.width, rect.height);
  2300.   SetGC(f, GC_UNSET);
  2301.  
  2302.   /* bottom arc */
  2303.   XSetClipRectangles(dpy, f->folder.gc, 0, 0, &rect, 1, Unsorted);
  2304.   arc.x = rect.x;
  2305.   arc.y = rect.y - cd - st;
  2306.   arc.width = rect.width * 2;
  2307.   arc.height = rect.height * 2;
  2308.   if (f->folder.serverDrawsArcsLarge == True)
  2309.     {
  2310.       arc.width -= 1;
  2311.       arc.height -= 1;
  2312.     }
  2313.   arc.angle1 = 0 * 64;
  2314.   arc.angle2 = 360 * 64;
  2315.   if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  2316.     arc.x = fc->folder.x + fc->folder.width - arc.width;
  2317.   SetGC(f, GC_SHADOWBOT);
  2318.   XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
  2319.        arc.angle1, arc.angle2);
  2320.   XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
  2321.        arc.angle1, arc.angle2);
  2322.   SetGC(f, GC_UNSET);
  2323.  
  2324.   rect2 = rect;
  2325.   rect2.width -= st;
  2326.   rect2.height -= st;
  2327.   if (f->folder.tabPlacement == XmFOLDER_LEFT)
  2328.     rect2.x += st;
  2329.   XSetClipRectangles(dpy, f->folder.gc, 0, 0, &rect2, 1, Unsorted);
  2330.   if (w == f->folder.activeW)
  2331.     XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
  2332.   else
  2333.     XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
  2334.   arc.x += st;
  2335.   arc.y += st;
  2336.   arc.width -= st * 2;
  2337.   arc.height -= st * 2;
  2338.   XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
  2339.        arc.angle1, arc.angle2);
  2340.   XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
  2341.        arc.angle1, arc.angle2);
  2342.   XSetClipMask(dpy, f->folder.gc, None);
  2343. }
  2344.  
  2345. static void 
  2346. DrawTabShadowLineTopBottom(XmLFolderWidget f,
  2347.                Widget w)
  2348. {
  2349.   XmLFolderConstraintRec *fc;
  2350.   Display *dpy;
  2351.   Window win;
  2352.   XSegment *topSeg, *botSeg;
  2353.   XPoint points[4];
  2354.   int tCount, bCount, botOff, i, st, cd, y;
  2355.  
  2356.   dpy = XtDisplay(f);
  2357.   win = XtWindow(f);
  2358.   fc = (XmLFolderConstraintRec *)(w->core.constraints);
  2359.   botOff = 2 * fc->folder.y + fc->folder.height - 1;
  2360.   st = f->manager.shadow_thickness;
  2361.   if (!st)
  2362.     return;
  2363.   cd = f->folder.cornerDimension;
  2364.  
  2365.   tCount = 0;
  2366.   bCount = 0;
  2367.   topSeg = (XSegment *)malloc(sizeof(XSegment) * st);
  2368.   botSeg = (XSegment *)malloc(sizeof(XSegment) * st);
  2369.   for (i = 0; i < st; i++)
  2370.     {
  2371.       /* left tab shadow */
  2372.       topSeg[tCount].x1 = fc->folder.x + i;
  2373.       topSeg[tCount].y1 = fc->folder.y + cd + st;
  2374.       topSeg[tCount].x2 = fc->folder.x + i;
  2375.       topSeg[tCount].y2 = fc->folder.y + fc->folder.height - 1;
  2376.       if (w == f->folder.activeW)
  2377.     topSeg[tCount].y2 += i;
  2378.       if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  2379.     {
  2380.       topSeg[tCount].y1 = botOff - topSeg[tCount].y1;
  2381.       topSeg[tCount].y2 = botOff - topSeg[tCount].y2;
  2382.     }
  2383.       tCount++;
  2384.       /* right tab shadow */
  2385.       botSeg[bCount].x1 = fc->folder.x + fc->folder.width - i - 1;
  2386.       botSeg[bCount].y1 = fc->folder.y + cd + st;
  2387.       botSeg[bCount].x2 = fc->folder.x + fc->folder.width - i - 1;
  2388.       botSeg[bCount].y2 = fc->folder.y + fc->folder.height - 1;
  2389.       if (w == f->folder.activeW)
  2390.     botSeg[bCount].y2 += i;
  2391.       if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  2392.     {
  2393.       botSeg[bCount].y1 = botOff - botSeg[bCount].y1;
  2394.       botSeg[bCount].y2 = botOff - botSeg[bCount].y2;
  2395.     }
  2396.       bCount++;
  2397.     }
  2398.   if (tCount)
  2399.     {
  2400.       SetGC(f, GC_SHADOWTOP);
  2401.       XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
  2402.       SetGC(f, GC_UNSET);
  2403.     }
  2404.   if (bCount)
  2405.     {
  2406.       SetGC(f, GC_SHADOWBOT);
  2407.       XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
  2408.       SetGC(f, GC_UNSET);
  2409.     }
  2410.   tCount = 0;
  2411.   for (i = 0; i < st; i++)
  2412.     {
  2413.       /* top tab shadow */
  2414.       topSeg[tCount].x1 = fc->folder.x + cd + st;
  2415.       topSeg[tCount].y1 = fc->folder.y + i;
  2416.       topSeg[tCount].x2 = fc->folder.x + fc->folder.width - cd - st - 1;
  2417.       topSeg[tCount].y2 = fc->folder.y + i;
  2418.       if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  2419.     {
  2420.       topSeg[tCount].y1 = botOff - topSeg[tCount].y1;
  2421.       topSeg[tCount].y2 = botOff - topSeg[tCount].y2;
  2422.     }
  2423.       tCount++;
  2424.     }
  2425.   if (tCount)
  2426.     {
  2427.       if (f->folder.tabPlacement == XmFOLDER_TOP)
  2428.     SetGC(f, GC_SHADOWTOP);
  2429.       else
  2430.     SetGC(f, GC_SHADOWBOT);
  2431.       XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
  2432.       SetGC(f, GC_UNSET);
  2433.     }
  2434.   free((char *)topSeg);
  2435.   free((char *)botSeg);
  2436.  
  2437.   /* left top line */
  2438.   points[0].x = fc->folder.x;
  2439.   points[0].y = fc->folder.y + cd + st - 1;
  2440.   points[1].x = fc->folder.x + cd + st - 1;
  2441.   points[1].y = fc->folder.y;
  2442.   points[2].x = fc->folder.x + cd + st - 1;
  2443.   points[2].y = fc->folder.y + cd + st - 1;
  2444.   if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  2445.     {
  2446.       points[0].y = botOff - points[0].y;
  2447.       points[1].y = botOff - points[1].y;
  2448.       points[2].y = botOff - points[2].y;
  2449.     }
  2450.   y = fc->folder.y;
  2451.   if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  2452.     y = fc->folder.y + fc->folder.height - cd - st;
  2453.   SetGC(f, GC_BLANK);
  2454.   XFillRectangle(dpy, win, f->folder.gc, fc->folder.x, y, cd + st, cd + st);
  2455.   SetGC(f, GC_UNSET);
  2456.   SetGC(f, GC_SHADOWTOP);
  2457.   XFillPolygon(dpy, win, f->folder.gc, points, 3, Nonconvex,
  2458.            CoordModeOrigin);
  2459.   points[3].x = points[0].x;
  2460.   points[3].y = points[0].y;
  2461.   XDrawLines(dpy, win, f->folder.gc, points, 4, CoordModeOrigin);
  2462.   SetGC(f, GC_UNSET);
  2463.   if (w == f->folder.activeW)
  2464.     XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
  2465.   else
  2466.     XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
  2467.   points[0].x += st;
  2468.   points[1].y += st;
  2469.   if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  2470.     points[1].y -= st * 2;
  2471.   XFillPolygon(dpy, win, f->folder.gc, points, 3,
  2472.            Nonconvex, CoordModeOrigin);
  2473.   points[3].x = points[0].x;
  2474.   points[3].y = points[0].y;
  2475.   XDrawLines(dpy, win, f->folder.gc, points, 4, CoordModeOrigin);
  2476.  
  2477.   /* right top line */
  2478.   points[0].x = fc->folder.x + fc->folder.width - 1;
  2479.   points[0].y = fc->folder.y + cd + st - 1;
  2480.   points[1].x = fc->folder.x + fc->folder.width - cd - st;
  2481.   points[1].y = fc->folder.y;
  2482.   points[2].x = fc->folder.x + fc->folder.width - cd - st;
  2483.   points[2].y = fc->folder.y + cd + st - 1;
  2484.   if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  2485.     {
  2486.       points[0].y = botOff - points[0].y;
  2487.       points[1].y = botOff - points[1].y;
  2488.       points[2].y = botOff - points[2].y;
  2489.     }
  2490.   y = fc->folder.y;
  2491.   if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  2492.     y = fc->folder.y + fc->folder.height - cd - st;
  2493.   SetGC(f, GC_BLANK);
  2494.   XFillRectangle(dpy, win, f->folder.gc, fc->folder.x + fc->folder.width -
  2495.          cd - st, y, cd + st, cd + st);
  2496.   SetGC(f, GC_UNSET);
  2497.   if (f->folder.tabPlacement == XmFOLDER_TOP)
  2498.     SetGC(f, GC_SHADOWTOP);
  2499.   else
  2500.     SetGC(f, GC_SHADOWBOT);
  2501.   XFillPolygon(dpy, win, f->folder.gc, points, 3, Nonconvex,
  2502.            CoordModeOrigin);
  2503.   points[3].x = points[0].x;
  2504.   points[3].y = points[0].y;
  2505.   XDrawLines(dpy, win, f->folder.gc, points, 4, CoordModeOrigin);
  2506.   SetGC(f, GC_UNSET);
  2507.   if (w == f->folder.activeW)
  2508.     XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
  2509.   else
  2510.     XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
  2511.   points[0].x -= st;
  2512.   points[1].y += st;
  2513.   if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  2514.     points[1].y -= st * 2;
  2515.   XFillPolygon(dpy, win, f->folder.gc, points, 3, Nonconvex,
  2516.            CoordModeOrigin);
  2517.   points[3].x = points[0].x;
  2518.   points[3].y = points[0].y;
  2519.   XDrawLines(dpy, win, f->folder.gc, points, 4, CoordModeOrigin);
  2520. }
  2521.  
  2522. static void 
  2523. DrawTabShadowLineLeftRight(XmLFolderWidget f,
  2524.                Widget w)
  2525. {
  2526.   XmLFolderConstraintRec *fc;
  2527.   Display *dpy;
  2528.   Window win;
  2529.   XSegment *topSeg, *botSeg;
  2530.   XPoint points[4];
  2531.   int tCount, bCount, rightOff, i, st, cd, x;
  2532.  
  2533.   dpy = XtDisplay(f);
  2534.   win = XtWindow(f);
  2535.   fc = (XmLFolderConstraintRec *)(w->core.constraints);
  2536.   rightOff = 2 * fc->folder.x + fc->folder.width - 1;
  2537.   st = f->manager.shadow_thickness;
  2538.   if (!st)
  2539.     return;
  2540.   cd = f->folder.cornerDimension;
  2541.  
  2542.   tCount = 0;
  2543.   bCount = 0;
  2544.   topSeg = (XSegment *)malloc(sizeof(XSegment) * st);
  2545.   botSeg = (XSegment *)malloc(sizeof(XSegment) * st);
  2546.   for (i = 0; i < st; i++)
  2547.     {
  2548.       /* top tab shadow */
  2549.       topSeg[tCount].x1 = fc->folder.x + cd + st;
  2550.       topSeg[tCount].y1 = fc->folder.y + i;
  2551.       topSeg[tCount].x2 = fc->folder.x + fc->folder.width - 1;
  2552.       if (w == f->folder.activeW)
  2553.     topSeg[tCount].x2 += i;
  2554.       topSeg[tCount].y2 = fc->folder.y + i;
  2555.       if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  2556.     {
  2557.       topSeg[tCount].x1 = rightOff - topSeg[tCount].x1;
  2558.       topSeg[tCount].x2 = rightOff - topSeg[tCount].x2;
  2559.     }
  2560.       tCount++;
  2561.       /* bottom tab shadow */
  2562.       botSeg[bCount].x1 = fc->folder.x + cd + st;
  2563.       botSeg[bCount].y1 = fc->folder.y + fc->folder.height - i - 1;
  2564.       botSeg[bCount].x2 = fc->folder.x + fc->folder.width - 1;
  2565.       if (w == f->folder.activeW)
  2566.     botSeg[bCount].x2 += i;
  2567.       botSeg[bCount].y2 = fc->folder.y + fc->folder.height - i - 1;
  2568.       if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  2569.     {
  2570.       botSeg[bCount].x1 = rightOff - botSeg[bCount].x1;
  2571.       botSeg[bCount].x2 = rightOff - botSeg[bCount].x2;
  2572.     }
  2573.       bCount++;
  2574.     }
  2575.   if (tCount)
  2576.     {
  2577.       SetGC(f, GC_SHADOWTOP);
  2578.       XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
  2579.       SetGC(f, GC_UNSET);
  2580.     }
  2581.   if (bCount)
  2582.     {
  2583.       SetGC(f, GC_SHADOWBOT);
  2584.       XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
  2585.       SetGC(f, GC_UNSET);
  2586.     }
  2587.   tCount = 0;
  2588.   for (i = 0; i < st; i++)
  2589.     {
  2590.       /* left tab shadow */
  2591.       topSeg[tCount].x1 = fc->folder.x + i;
  2592.       topSeg[tCount].y1 = fc->folder.y + cd + st;
  2593.       topSeg[tCount].x2 = fc->folder.x + i;
  2594.       topSeg[tCount].y2 = fc->folder.y + fc->folder.height - cd - st - 1;
  2595.       if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  2596.     {
  2597.       topSeg[tCount].x1 = rightOff - topSeg[tCount].x1;
  2598.       topSeg[tCount].x2 = rightOff - topSeg[tCount].x2;
  2599.     }
  2600.       tCount++;
  2601.     }
  2602.   if (tCount)
  2603.     {
  2604.       if (f->folder.tabPlacement == XmFOLDER_LEFT)
  2605.     SetGC(f, GC_SHADOWTOP);
  2606.       else
  2607.     SetGC(f, GC_SHADOWBOT);
  2608.       XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
  2609.       SetGC(f, GC_UNSET);
  2610.     }
  2611.   free((char *)topSeg);
  2612.   free((char *)botSeg);
  2613.  
  2614.   /* top line */
  2615.   points[0].x = fc->folder.x + cd + st - 1;
  2616.   points[0].y = fc->folder.y;
  2617.   points[1].x = fc->folder.x;
  2618.   points[1].y = fc->folder.y + cd + st - 1;
  2619.   points[2].x = fc->folder.x + cd + st - 1;
  2620.   points[2].y = fc->folder.y + cd + st - 1;
  2621.   if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  2622.     {
  2623.       points[0].x = rightOff - points[0].x;
  2624.       points[1].x = rightOff - points[1].x;
  2625.       points[2].x = rightOff - points[2].x;
  2626.     }
  2627.   if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  2628.     x = fc->folder.x + fc->folder.width - cd - st;
  2629.   else
  2630.     x = fc->folder.x;
  2631.   SetGC(f, GC_BLANK);
  2632.   XFillRectangle(dpy, win, f->folder.gc, x, fc->folder.y, cd + st, cd + st);
  2633.   SetGC(f, GC_UNSET);
  2634.   SetGC(f, GC_SHADOWTOP);
  2635.   XFillPolygon(dpy, win, f->folder.gc, points, 3, Nonconvex,
  2636.            CoordModeOrigin);
  2637.   points[3].x = points[0].x;
  2638.   points[3].y = points[0].y;
  2639.   XDrawLines(dpy, win, f->folder.gc, points, 4, CoordModeOrigin);
  2640.   SetGC(f, GC_UNSET);
  2641.   if (w == f->folder.activeW)
  2642.     XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
  2643.   else
  2644.     XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
  2645.   points[0].y += st;
  2646.   points[1].x += st;
  2647.   if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  2648.     points[1].x -= st * 2;
  2649.   XFillPolygon(dpy, win, f->folder.gc, points, 3,
  2650.            Nonconvex, CoordModeOrigin);
  2651.   points[3].x = points[0].x;
  2652.   points[3].y = points[0].y;
  2653.   XDrawLines(dpy, win, f->folder.gc, points, 4, CoordModeOrigin);
  2654.  
  2655.   /* bottom line */
  2656.   points[0].x = fc->folder.x + cd + st - 1;
  2657.   points[0].y = fc->folder.y + fc->folder.height - 1;
  2658.   points[1].x = fc->folder.x;
  2659.   points[1].y = fc->folder.y + fc->folder.height - cd - st;
  2660.   points[2].x = fc->folder.x + cd + st - 1;
  2661.   points[2].y = fc->folder.y + fc->folder.height - cd - st;
  2662.   if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  2663.     {
  2664.       points[0].x = rightOff - points[0].x;
  2665.       points[1].x = rightOff - points[1].x;
  2666.       points[2].x = rightOff - points[2].x;
  2667.     }
  2668.   if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  2669.     x = fc->folder.x + fc->folder.width - cd - st;
  2670.   else
  2671.     x = fc->folder.x;
  2672.   SetGC(f, GC_BLANK);
  2673.   XFillRectangle(dpy, win, f->folder.gc, x, fc->folder.y +
  2674.          fc->folder.height - cd - st, cd + st, cd + st);
  2675.   SetGC(f, GC_UNSET);
  2676.   SetGC(f, GC_SHADOWBOT);
  2677.   XFillPolygon(dpy, win, f->folder.gc, points, 3, Nonconvex,
  2678.            CoordModeOrigin);
  2679.   points[3].x = points[0].x;
  2680.   points[3].y = points[0].y;
  2681.   XDrawLines(dpy, win, f->folder.gc, points, 4, CoordModeOrigin);
  2682.   SetGC(f, GC_UNSET);
  2683.   if (w == f->folder.activeW)
  2684.     XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
  2685.   else
  2686.     XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
  2687.   points[0].y -= st;
  2688.   points[1].x += st;
  2689.   if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  2690.     points[1].x -= st * 2;
  2691.   XFillPolygon(dpy, win, f->folder.gc, points, 3, Nonconvex,
  2692.            CoordModeOrigin);
  2693.   points[3].x = points[0].x;
  2694.   points[3].y = points[0].y;
  2695.   XDrawLines(dpy, win, f->folder.gc, points, 4, CoordModeOrigin);
  2696. }
  2697.  
  2698. static void 
  2699. DrawTabShadowNoneTopBottom(XmLFolderWidget f,
  2700.                Widget w)
  2701. {
  2702.   XmLFolderConstraintRec *fc;
  2703.   Display *dpy;
  2704.   Window win;
  2705.   XSegment *topSeg, *botSeg;
  2706.   int i, st, botOff, tCount, bCount;
  2707.  
  2708.   dpy = XtDisplay(f);
  2709.   win = XtWindow(f);
  2710.   fc = (XmLFolderConstraintRec *)(w->core.constraints);
  2711.   botOff = 2 * fc->folder.y + fc->folder.height - 1;
  2712.   st = f->manager.shadow_thickness;
  2713.   if (!st)
  2714.     return;
  2715.  
  2716.   tCount = 0;
  2717.   bCount = 0;
  2718.   topSeg = (XSegment *)malloc(sizeof(XSegment) * st * 2);
  2719.   botSeg = (XSegment *)malloc(sizeof(XSegment) * st * 2);
  2720.   for (i = 0; i < st; i++)
  2721.     {
  2722.       /* left tab shadow */
  2723.       topSeg[tCount].x1 = fc->folder.x + i;
  2724.       topSeg[tCount].y1 = fc->folder.y + i;
  2725.       topSeg[tCount].x2 = fc->folder.x + i;
  2726.       topSeg[tCount].y2 = fc->folder.y + fc->folder.height - 1;
  2727.       if (w == f->folder.activeW)
  2728.     topSeg[tCount].y2 += i;
  2729.       if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  2730.     {
  2731.       topSeg[tCount].y1 = botOff - topSeg[tCount].y1;
  2732.       topSeg[tCount].y2 = botOff - topSeg[tCount].y2;
  2733.     }
  2734.       tCount++;
  2735.  
  2736.       /* right tab shadow */
  2737.       botSeg[bCount].x1 = fc->folder.x + fc->folder.width - 1 - i;
  2738.       botSeg[bCount].y1 = fc->folder.y + i;
  2739.       botSeg[bCount].x2 = fc->folder.x + fc->folder.width - 1 - i;
  2740.       botSeg[bCount].y2 = fc->folder.y + fc->folder.height - 1;
  2741.       if (w == f->folder.activeW)
  2742.     botSeg[bCount].y2 += i;
  2743.       if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  2744.     {
  2745.       botSeg[bCount].y1 = botOff - botSeg[bCount].y1;
  2746.       botSeg[bCount].y2 = botOff - botSeg[bCount].y2;
  2747.     }
  2748.       bCount++;
  2749.     }
  2750.   if (tCount)
  2751.     {
  2752.       SetGC(f, GC_SHADOWTOP);
  2753.       XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
  2754.       SetGC(f, GC_UNSET);
  2755.     }
  2756.   if (bCount)
  2757.     {
  2758.       SetGC(f, GC_SHADOWBOT);
  2759.       XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
  2760.       SetGC(f, GC_UNSET);
  2761.     }
  2762.  
  2763.   tCount = 0;
  2764.   for (i = 0; i < st; i++)
  2765.     {
  2766.       /* top tab shadow */
  2767.       topSeg[tCount].x1 = fc->folder.x + i + 1;
  2768.       topSeg[tCount].y1 = fc->folder.y + i;
  2769.       topSeg[tCount].x2 = fc->folder.x + fc->folder.width - i - 1;
  2770.       topSeg[tCount].y2 = fc->folder.y + i;
  2771.       if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  2772.     {
  2773.       topSeg[tCount].y1 = botOff - topSeg[tCount].y1;
  2774.       topSeg[tCount].y2 = botOff - topSeg[tCount].y2;
  2775.     }
  2776.       tCount++;
  2777.     }
  2778.   if (tCount)
  2779.     {
  2780.       if (f->folder.tabPlacement == XmFOLDER_TOP)
  2781.     SetGC(f, GC_SHADOWTOP);
  2782.       else
  2783.     SetGC(f, GC_SHADOWBOT);
  2784.       XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
  2785.       SetGC(f, GC_UNSET);
  2786.     }
  2787.   free((char *)topSeg);
  2788.   free((char *)botSeg);
  2789. }
  2790.  
  2791. static void 
  2792. DrawTabShadowNoneLeftRight(XmLFolderWidget f,
  2793.                Widget w)
  2794. {
  2795.   XmLFolderConstraintRec *fc;
  2796.   Display *dpy;
  2797.   Window win;
  2798.   XSegment *topSeg, *botSeg;
  2799.   int i, st, rightOff, tCount, bCount;
  2800.  
  2801.   dpy = XtDisplay(f);
  2802.   win = XtWindow(f);
  2803.   fc = (XmLFolderConstraintRec *)(w->core.constraints);
  2804.   rightOff = 2 * fc->folder.x + fc->folder.width - 1;
  2805.   st = f->manager.shadow_thickness;
  2806.   if (!st)
  2807.     return;
  2808.  
  2809.   tCount = 0;
  2810.   bCount = 0;
  2811.   topSeg = (XSegment *)malloc(sizeof(XSegment) * st * 2);
  2812.   botSeg = (XSegment *)malloc(sizeof(XSegment) * st * 2);
  2813.   for (i = 0; i < st; i++)
  2814.     {
  2815.       /* bottom tab shadow */
  2816.       topSeg[tCount].x1 = fc->folder.x + i;
  2817.       topSeg[tCount].y1 = fc->folder.y + i;
  2818.       topSeg[tCount].x2 = fc->folder.x + fc->folder.width - 1;
  2819.       if (w == f->folder.activeW)
  2820.     topSeg[tCount].x2 += i;
  2821.       topSeg[tCount].y2 = fc->folder.y + i;
  2822.       if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  2823.     {
  2824.       topSeg[tCount].x1 = rightOff - topSeg[tCount].x1;
  2825.       topSeg[tCount].x2 = rightOff - topSeg[tCount].x2;
  2826.     }
  2827.       tCount++;
  2828.  
  2829.       /* top tab shadow */
  2830.       botSeg[bCount].x1 = fc->folder.x + i;
  2831.       botSeg[bCount].y1 = fc->folder.y + fc->folder.height - i - 1;
  2832.       botSeg[bCount].x2 = fc->folder.x + fc->folder.width - 1;
  2833.       if (w == f->folder.activeW)
  2834.     botSeg[bCount].x2 += i;
  2835.       botSeg[bCount].y2 = fc->folder.y + fc->folder.height - i - 1;
  2836.       if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  2837.     {
  2838.       botSeg[bCount].x1 = rightOff - botSeg[bCount].x1;
  2839.       botSeg[bCount].x2 = rightOff - botSeg[bCount].x2;
  2840.     }
  2841.       bCount++;
  2842.     }
  2843.   if (tCount)
  2844.     {
  2845.       SetGC(f, GC_SHADOWTOP);
  2846.       XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
  2847.       SetGC(f, GC_UNSET);
  2848.     }
  2849.   if (bCount)
  2850.     {
  2851.       SetGC(f, GC_SHADOWBOT);
  2852.       XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
  2853.       SetGC(f, GC_UNSET);
  2854.     }
  2855.  
  2856.   tCount = 0;
  2857.   for (i = 0; i < st; i++)
  2858.     {
  2859.       /* left tab shadow */
  2860.       topSeg[tCount].x1 = fc->folder.x + i;
  2861.       topSeg[tCount].y1 = fc->folder.y + i + 1;
  2862.       topSeg[tCount].x2 = fc->folder.x + i;
  2863.       topSeg[tCount].y2 = fc->folder.y + fc->folder.height - i - 1;
  2864.       if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  2865.     {
  2866.       topSeg[tCount].x1 = rightOff - topSeg[tCount].x1;
  2867.       topSeg[tCount].x2 = rightOff - topSeg[tCount].x2;
  2868.     }
  2869.       tCount++;
  2870.     }
  2871.   if (tCount)
  2872.     {
  2873.       if (f->folder.tabPlacement == XmFOLDER_RIGHT)
  2874.     SetGC(f, GC_SHADOWBOT);
  2875.       else
  2876.     SetGC(f, GC_SHADOWTOP);
  2877.       XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
  2878.       SetGC(f, GC_UNSET);
  2879.     }
  2880.   free((char *)topSeg);
  2881.   free((char *)botSeg);
  2882. }
  2883.  
  2884. static void 
  2885. SetGC(XmLFolderWidget f,
  2886.       int type)
  2887. {
  2888.   Display *dpy;
  2889.   XGCValues values;
  2890.   XtGCMask mask;
  2891.  
  2892.   dpy = XtDisplay(f);
  2893.   if (type == GC_SHADOWBOT)
  2894.     {
  2895.       mask = GCForeground;
  2896.       values.foreground = f->manager.bottom_shadow_color;
  2897.       if (f->manager.bottom_shadow_pixmap != XmUNSPECIFIED_PIXMAP)
  2898.     {
  2899.       mask |= GCFillStyle | GCTile;
  2900.       values.fill_style = FillTiled;
  2901.       values.tile = f->manager.bottom_shadow_pixmap;
  2902.     }
  2903.       XChangeGC(dpy, f->folder.gc, mask, &values);
  2904.     }
  2905.   else if (type == GC_SHADOWTOP)
  2906.     {
  2907.       mask = GCForeground;
  2908.       values.foreground = f->manager.top_shadow_color;
  2909.       if (f->manager.top_shadow_pixmap != XmUNSPECIFIED_PIXMAP)
  2910.     {
  2911.       mask |= GCFillStyle | GCTile;
  2912.       values.fill_style = FillTiled;
  2913.       values.tile = f->manager.top_shadow_pixmap;
  2914.     }
  2915.       XChangeGC(dpy, f->folder.gc, mask, &values);
  2916.     }
  2917.   else if (type == GC_BLANK)
  2918.     {
  2919.       mask = GCForeground;
  2920.       values.foreground = f->folder.blankBg;
  2921.       if (f->folder.blankPix != XmUNSPECIFIED_PIXMAP)
  2922.     {
  2923.       mask |= GCFillStyle | GCTile;
  2924.       values.fill_style = FillTiled;
  2925.       values.tile = f->folder.blankPix;
  2926.     }
  2927.       XChangeGC(dpy, f->folder.gc, mask, &values);
  2928.     }
  2929.   else
  2930.     {
  2931.       mask = GCFillStyle;
  2932.       values.fill_style = FillSolid;
  2933.       XChangeGC(dpy, f->folder.gc, mask, &values);
  2934.     }
  2935. }
  2936.  
  2937. static void 
  2938. DrawTabHighlight(XmLFolderWidget f,
  2939.          Widget w)
  2940. {
  2941.   XmLFolderConstraintRec *fc;
  2942.   Display *dpy;
  2943.   Window win;
  2944.   int ht;
  2945.  
  2946.   if (!XtIsRealized(w))
  2947.     return;
  2948.   if (!f->core.visible)
  2949.     return;
  2950.   dpy = XtDisplay(f);
  2951.   win = XtWindow(f);
  2952.   fc = (XmLFolderConstraintRec *)(w->core.constraints);
  2953.   ht = f->folder.highlightThickness;
  2954.   if (f->folder.focusW == w)
  2955.     XSetForeground(dpy, f->folder.gc, f->manager.highlight_color);
  2956.   else
  2957.     {
  2958.       if (f->folder.activeW == w)
  2959.     XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
  2960.       else
  2961.     XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
  2962.     }
  2963.   XFillRectangle(dpy, win, f->folder.gc,
  2964.          w->core.x - ht, w->core.y - ht,
  2965.          XtWidth(w) + w->core.border_width * 2 + ht * 2, 
  2966.          XtHeight(w) + w->core.border_width * 2 + ht * 2);
  2967. }
  2968.  
  2969. static void 
  2970. SetTabPlacement(XmLFolderWidget f,
  2971.         Widget tab)
  2972. {
  2973.   if (!XmIsDrawnButton(tab))
  2974.     return;
  2975.   if (f->folder.allowRotate == True &&
  2976.       f->folder.tabPlacement == XmFOLDER_LEFT)
  2977.     XmLDrawnButtonSetType(tab, XmDRAWNB_STRING, XmDRAWNB_UP);
  2978.   else if (f->folder.allowRotate == True &&
  2979.        f->folder.tabPlacement == XmFOLDER_RIGHT)
  2980.     XmLDrawnButtonSetType(tab, XmDRAWNB_STRING, XmDRAWNB_DOWN);
  2981.   else
  2982.     XmLDrawnButtonSetType(tab, XmDRAWNB_STRING, XmDRAWNB_RIGHT);
  2983.   if (XtIsRealized(tab))
  2984.     XClearArea(XtDisplay(tab), XtWindow(tab), 0, 0, 0, 0, True);
  2985. }
  2986.  
  2987. static void 
  2988. GetTabRect(XmLFolderWidget f,
  2989.        Widget tab,
  2990.        XRectangle *rect,
  2991.        int includeShadow)
  2992. {
  2993.   XmLFolderConstraintRec *fc;
  2994.   int st;
  2995.  
  2996.   st = f->manager.shadow_thickness;
  2997.   fc = (XmLFolderConstraintRec *)(tab->core.constraints);
  2998.   rect->x = fc->folder.x;
  2999.   rect->y = fc->folder.y;
  3000.   rect->width = fc->folder.width;
  3001.   rect->height = fc->folder.height;
  3002.   if (includeShadow)
  3003.     {
  3004.       if (f->folder.tabPlacement == XmFOLDER_TOP)
  3005.     rect->height += st;
  3006.       else if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
  3007.     {
  3008.       rect->y -= st;
  3009.       rect->height += st;
  3010.     }
  3011.       else if (f->folder.tabPlacement == XmFOLDER_LEFT)
  3012.     rect->width += st;
  3013.       else
  3014.     {
  3015.       rect->x -= st;
  3016.       rect->width += st;
  3017.     }
  3018.     }
  3019. }
  3020.  
  3021. static void 
  3022. SetActiveTab(XmLFolderWidget f,
  3023.          Widget w,
  3024.          XEvent *event,
  3025.          Boolean notify)
  3026. {
  3027.   XmLFolderCallbackStruct cbs;
  3028.   XmLFolderConstraintRec *fc, *cfc;
  3029.   int i, j, pos;
  3030.   Display *dpy;
  3031.   Window win;
  3032.   Widget activeW, child, mw, managedW;
  3033.   WidgetList children;
  3034.   XRectangle rect;
  3035.   char *name, buf[256];
  3036.  
  3037.   win = (Window)NULL;
  3038.  
  3039.   if (f->folder.activeW == w)
  3040.     return;
  3041.   dpy = 0;
  3042.   if (XtIsRealized((Widget)f) && f->core.visible)
  3043.     {
  3044.       dpy = XtDisplay(f);
  3045.       win = XtWindow(f);
  3046.     }
  3047.  
  3048.   pos = -1;
  3049.   for (i = 0; i < f->folder.tabCount; i++)
  3050.     if (w == f->folder.tabs[i])
  3051.       pos = i;
  3052.  
  3053.   cbs.allowActivate = 1;
  3054.   cbs.layoutNeeded = 0;
  3055.   if (notify == True)
  3056.     {
  3057.       if (f->folder.debugLevel)
  3058.     fprintf(stderr, "XmLFolder: activated %d\n", pos);
  3059.       cbs.reason = XmCR_ACTIVATE;
  3060.       cbs.event = event;
  3061.       cbs.pos = pos;
  3062.       XtCallCallbackList((Widget)f, f->folder.activateCallback, &cbs);
  3063.     }
  3064.   if (!cbs.allowActivate)
  3065.     return;
  3066.  
  3067.   /* redraw current active tab */
  3068.   activeW = f->folder.activeW;
  3069.   if (activeW && dpy)
  3070.     {
  3071.       GetTabRect(f, activeW, &rect, 1);
  3072.       XClearArea(dpy, win, rect.x, rect.y, rect.width,
  3073.          rect.height, True);
  3074.     }
  3075.  
  3076.   f->folder.activeTab = pos;
  3077.   f->folder.activeW = w;
  3078.   if (!w)
  3079.     return;
  3080.  
  3081.   /* Not sure this needs to be in the 3.0 (Microline) stuff */
  3082.   PrimFocusIn(w, NULL, NULL, NULL);
  3083.  
  3084.   /* if we selected a tab not in active row - move row into place */
  3085.   if (f->folder.tabsPerRow)
  3086.     {
  3087.       fc = (XmLFolderConstraintRec *)(w->core.constraints);
  3088.       if (fc->folder.row != f->folder.activeRow)
  3089.     Layout(f, False);
  3090.     }
  3091.  
  3092.   /* manage this tabs managed widget if it exists */
  3093.   children = f->composite.children;
  3094.   f->folder.allowLayout = 0;
  3095.   for (i = 0; i < f->composite.num_children; i++)
  3096.     {
  3097.       child = children[i];
  3098.       if (!XtIsSubclass(child, xmPrimitiveWidgetClass))
  3099.     continue;
  3100.       fc = (XmLFolderConstraintRec *)(child->core.constraints);
  3101.       managedW = 0;
  3102.       if (fc->folder.managedName)
  3103.     {
  3104.       for (j = 0; j < f->composite.num_children; j++)
  3105.         {
  3106.           mw = children[j];
  3107.           if (XtIsSubclass(mw, xmPrimitiveWidgetClass))
  3108.         continue;
  3109.           name = XtName(mw);
  3110.           if (name && !strcmp(name, fc->folder.managedName))
  3111.         managedW = mw;
  3112.           cfc = (XmLFolderConstraintRec *)(mw->core.constraints);
  3113.           name = cfc->folder.managedName;
  3114.           if (name && !strcmp(name, fc->folder.managedName))
  3115.         managedW = mw;
  3116.         }
  3117.       if (!managedW)
  3118.         {
  3119.           sprintf(buf, "SetActiveTab() - managed widget named ");
  3120.           strcat(buf, fc->folder.managedName);
  3121.           strcat(buf, " not found");
  3122.           XmLWarning(child, buf);
  3123.         }
  3124.     }
  3125.       else
  3126.     managedW = fc->folder.managedW;
  3127.       if (managedW)
  3128.     {
  3129.       if (w == child && !XtIsManaged(managedW))
  3130.         XtManageChild(managedW);
  3131.       if (w != child && XtIsManaged(managedW))
  3132.         XtUnmanageChild(managedW);
  3133.     }
  3134.     }
  3135.   f->folder.allowLayout = 1;
  3136.  
  3137.   /* redraw new active tab */
  3138.   if (dpy)
  3139.     {
  3140.       GetTabRect(f, w, &rect, 1);
  3141.       XClearArea(dpy, win, rect.x, rect.y, rect.width, rect.height, True);
  3142.       XmProcessTraversal(w, XmTRAVERSE_CURRENT);
  3143.     }
  3144.  
  3145.   if (cbs.layoutNeeded)
  3146.     Layout(f, 0);
  3147. }
  3148.  
  3149. /*
  3150.    Utility
  3151. */
  3152.  
  3153. static void 
  3154. GetCoreBackground(Widget w, 
  3155.           int offset, 
  3156.           XrmValue *value)
  3157. {
  3158.   value->addr = (caddr_t)&w->core.background_pixel;
  3159. }
  3160.  
  3161. static void 
  3162. GetDefaultTabWidgetClass(Widget w, 
  3163.           int offset, 
  3164.           XrmValue *value)
  3165. {
  3166.   value->addr = (caddr_t)&xmDrawnButtonWidgetClass;
  3167. }
  3168.  
  3169. static void 
  3170. GetManagerForeground(Widget w,
  3171.              int offset,
  3172.              XrmValue *value)
  3173. {
  3174.   XmLFolderWidget f;
  3175.  
  3176.   f = (XmLFolderWidget)w;
  3177.   value->addr = (caddr_t)&f->manager.foreground;
  3178. }
  3179.  
  3180. static Boolean 
  3181. ServerDrawsArcsLarge(Display *dpy,
  3182.              int debug)
  3183. {
  3184.   Pixmap pixmap;
  3185.   XImage *image;
  3186.   Window root;
  3187.   long pixel;
  3188.   int x, y, width, height, result;
  3189.   GC gc;
  3190.  
  3191.   root = DefaultRootWindow(dpy);
  3192.   width = 5;
  3193.   height = 5;
  3194.   pixmap = XCreatePixmap(dpy, root, width, height, 1);
  3195.   gc = XCreateGC(dpy, pixmap, 0L, NULL);
  3196.   XSetForeground(dpy, gc, 0L);
  3197.   XFillRectangle(dpy, pixmap, gc, 0, 0, width, height);
  3198.   XSetForeground(dpy, gc, 1L);
  3199.   XDrawArc(dpy, pixmap, gc, 0, 0, width, height, 0, 360 * 64);
  3200.   image = XGetImage(dpy, pixmap, 0, 0, width, height, AllPlanes, ZPixmap);
  3201.   if (debug)
  3202.     {
  3203.       fprintf(stderr, "Test X server drawn arc (%d by %d):\n",
  3204.           width, height);
  3205.       for (y = 0; y < height; y++)
  3206.     {
  3207.       fprintf(stderr, " ");
  3208.       for (x = 0; x < width; x++)
  3209.         {
  3210.           pixel = XGetPixel(image, x, y);
  3211.           if (pixel == 0L)
  3212.         fprintf(stderr, ".");
  3213.           else
  3214.         fprintf(stderr, "X");
  3215.         }
  3216.       fprintf(stderr, "\n");
  3217.     }
  3218.     }
  3219.   if (XGetPixel(image, width - 1, height / 2) != 1L)
  3220.     {
  3221.       result = 1;
  3222.       if (debug)
  3223.     fprintf(stderr, "X Server Draws Arcs 1 Pixel Large\n");
  3224.     }
  3225.   else
  3226.     {
  3227.       result = 0;
  3228.       if (debug)
  3229.     fprintf(stderr, "X Server Draws Arcs Within Bounds\n");
  3230.     }
  3231.   XDestroyImage(image);
  3232.   XFreeGC(dpy, gc);
  3233.   XFreePixmap(dpy, pixmap);
  3234.   return result;
  3235. }
  3236.  
  3237. /*
  3238.    Getting and Setting Values
  3239. */
  3240.  
  3241. static Boolean 
  3242. SetValues(Widget curW,
  3243.       Widget reqW,
  3244.       Widget newW,
  3245.       ArgList args,
  3246.       Cardinal *narg)
  3247. {
  3248.   XmLFolderWidget f;
  3249.   XmLFolderWidget cur;
  3250.   int i;
  3251.   Boolean needsLayout, needsRedisplay;
  3252.  
  3253.   f = (XmLFolderWidget)newW;
  3254.   cur = (XmLFolderWidget)curW;
  3255.   needsLayout = False;
  3256.   needsRedisplay = False;
  3257. #define NE(value) (f->value != cur->value)
  3258.   if (NE(folder.tabBarHeight))
  3259.     {
  3260.       XmLWarning((Widget)f, "SetValues() - can't set tabBarHeight");
  3261.       f->folder.tabBarHeight = cur->folder.tabBarHeight;
  3262.     }
  3263.   if (NE(folder.tabCount))
  3264.     {
  3265.       XmLWarning((Widget)f, "SetValues() - can't set tabCount");
  3266.       f->folder.tabCount = cur->folder.tabCount;
  3267.     }
  3268.   if (NE(folder.activeTab))
  3269.     {
  3270.       XmLWarning((Widget)f, "SetValues() - can't set activeTab");
  3271.       f->folder.activeTab = cur->folder.activeTab;
  3272.     }
  3273.   if (f->folder.cornerDimension < 1)
  3274.     {
  3275.       XmLWarning((Widget)f, "SetValues() - cornerDimension can't be < 1");
  3276.       f->folder.cornerDimension = cur->folder.cornerDimension;
  3277.     }
  3278.   if (NE(folder.tabPlacement) ||
  3279.       NE(folder.allowRotate))
  3280.     {
  3281.       f->folder.allowLayout = 0;
  3282.       for (i = 0; i < f->folder.tabCount; i++)
  3283.     SetTabPlacement(f, f->folder.tabs[i]);
  3284.       f->folder.allowLayout = 1;
  3285.       needsLayout = True;
  3286.     }
  3287.   if (NE(folder.inactiveBg) ||
  3288.       NE(folder.blankBg) ||
  3289.       NE(folder.blankPix) ||
  3290.       NE(folder.inactiveFg))
  3291.     needsRedisplay = True;
  3292.   if (NE(folder.cornerDimension) ||
  3293.       NE(folder.cornerStyle) ||
  3294.       NE(folder.highlightThickness) ||
  3295.       NE(folder.marginHeight) ||
  3296.       NE(folder.marginWidth) ||
  3297.       NE(folder.pixmapMargin) ||
  3298.       NE(manager.shadow_thickness) ||
  3299.       NE(folder.tabsPerRow) ||
  3300.       NE(folder.spacing))
  3301.     needsLayout = True;
  3302.   if (NE(folder.fontList))
  3303.     {
  3304.       XmFontListFree(cur->folder.fontList);
  3305.       CopyFontList(f);
  3306.     }
  3307. #undef NE
  3308.   if (needsLayout == True) 
  3309.     Layout(f, 1);
  3310.   return needsRedisplay;
  3311. }
  3312.  
  3313. static void 
  3314. CopyFontList(XmLFolderWidget f)
  3315. {
  3316.   if (!f->folder.fontList)
  3317.     f->folder.fontList = XmLFontListCopyDefault((Widget)f);
  3318.   else
  3319.     f->folder.fontList = XmFontListCopy(f->folder.fontList);
  3320.   if (!f->folder.fontList)
  3321.     XmLWarning((Widget)f, "- fatal error - font list NULL");
  3322. }
  3323.  
  3324. static Boolean 
  3325. ConstraintSetValues(Widget curW,
  3326.             Widget reqW,
  3327.             Widget newW,
  3328.             ArgList args,
  3329.             Cardinal *narg)
  3330. {
  3331.   XmLFolderConstraintRec *cons, *curCons;
  3332.   XmLFolderWidget f;
  3333.   int i, hasLabelChange;
  3334.  
  3335.   f = (XmLFolderWidget)XtParent(newW);
  3336.   if (!XtIsRectObj(newW))
  3337.     return False;
  3338.   cons = (XmLFolderConstraintRec *)newW->core.constraints;
  3339.   curCons = (XmLFolderConstraintRec *)curW->core.constraints;
  3340. #define NE(value) (cons->value != curCons->value)
  3341.   if (NE(folder.managedName))
  3342.     {
  3343.       if (curCons->folder.managedName)
  3344.     free((char *)curCons->folder.managedName);
  3345.       if (cons->folder.managedName)
  3346.     cons->folder.managedName = (char *)strdup(cons->folder.managedName);
  3347.     }
  3348. #undef NE
  3349.   hasLabelChange = 0;
  3350.   if (XtIsSubclass(newW, xmPrimitiveWidgetClass))
  3351.     {
  3352.       for (i = 0; i < *narg; i++)
  3353.     if (args[i].name && !strcmp(args[i].name, XmNlabelString))
  3354.       hasLabelChange = 1;
  3355.       if (hasLabelChange &&
  3356.       (f->folder.tabPlacement == XmFOLDER_LEFT ||
  3357.        f->folder.tabPlacement == XmFOLDER_RIGHT))
  3358.     {
  3359.       f->folder.allowLayout = 0;
  3360.       for (i = 0; i < f->folder.tabCount; i++)
  3361.         SetTabPlacement(f, f->folder.tabs[i]);
  3362.       f->folder.allowLayout = 1;
  3363.     }
  3364.     }
  3365.   if (hasLabelChange ||
  3366.       curCons->folder.pix != cons->folder.pix ||
  3367.       curCons->folder.inactPix != cons->folder.inactPix)
  3368.     Layout((XmLFolderWidget)XtParent(curW), 1);
  3369.   return False;
  3370. }
  3371.  
  3372. static Boolean 
  3373. CvtStringToCornerStyle(Display *dpy,
  3374.                XrmValuePtr args,
  3375.                Cardinal *narg,
  3376.                XrmValuePtr fromVal,
  3377.                XrmValuePtr toVal,
  3378.                XtPointer *data)
  3379. {
  3380.   static XmLStringToUCharMap map[] =
  3381.   {
  3382.     { "CORNER_NONE", XmCORNER_NONE },
  3383.     { "CORNER_LINE", XmCORNER_LINE },
  3384.     { "CORNER_ARC", XmCORNER_ARC },
  3385.     { 0, 0 },
  3386.   };
  3387.  
  3388.   return XmLCvtStringToUChar(dpy, "XmRCornerStyle", map, fromVal, toVal);
  3389. }
  3390.  
  3391. static Boolean 
  3392. CvtStringToFolderResizePolicy(Display *dpy,
  3393.                   XrmValuePtr args,
  3394.                   Cardinal *narg,
  3395.                   XrmValuePtr fromVal,
  3396.                   XrmValuePtr toVal,
  3397.                   XtPointer *data)
  3398. {
  3399.   static XmLStringToUCharMap map[] =
  3400.   {
  3401.     { "RESIZE_NONE", XmRESIZE_NONE },
  3402.     { "RESIZE_STATIC", XmRESIZE_STATIC },
  3403.     { "RESIZE_DYNAMIC", XmRESIZE_DYNAMIC },
  3404.     { 0, 0 },
  3405.   };
  3406.  
  3407.   return XmLCvtStringToUChar(dpy, "XmRFolderResizePolicy", map,
  3408.                  fromVal, toVal);
  3409. }
  3410.  
  3411. static Boolean 
  3412. CvtStringToTabPlacement(Display *dpy,
  3413.             XrmValuePtr args,
  3414.             Cardinal *narg,
  3415.             XrmValuePtr fromVal,
  3416.             XrmValuePtr toVal,
  3417.             XtPointer *data)
  3418. {
  3419.   static XmLStringToUCharMap map[] =
  3420.   {
  3421.     { "FOLDER_TOP", XmFOLDER_TOP },
  3422.     { "FOLDER_LEFT", XmFOLDER_LEFT },
  3423.     { "FOLDER_BOTTOM", XmFOLDER_BOTTOM },
  3424.     { "FOLDER_RIGHT", XmFOLDER_RIGHT },
  3425.     { 0, 0 },
  3426.   };
  3427.  
  3428.   return XmLCvtStringToUChar(dpy, "XmRTabPlacement", map, fromVal, toVal);
  3429. }
  3430.  
  3431. /*
  3432.    Actions, Callbacks and Handlers
  3433. */
  3434.  
  3435. static void 
  3436. Activate(Widget w,
  3437.      XEvent *event,
  3438.      String *params,
  3439.      Cardinal *nparam)
  3440. {
  3441.   XmLFolderWidget f;
  3442.   XButtonEvent *be;
  3443.   XRectangle rect;
  3444.   Widget tab;
  3445.   int i;
  3446.  
  3447.   f = (XmLFolderWidget)w;
  3448.   if (!event || event->type != ButtonPress)
  3449.     return;
  3450.   be = (XButtonEvent *)event;
  3451.   if (f->folder.debugLevel)
  3452.     fprintf(stderr, "XmLFolder: ButtonPress %d %d\n", be->x, be->y);
  3453.   for (i = 0; i < f->folder.tabCount; i++)
  3454.     {
  3455.       tab = f->folder.tabs[i];
  3456.       if (!XtIsManaged(tab) || !XtIsSensitive(tab))
  3457.     continue;
  3458.       GetTabRect(f, tab, &rect, 0); 
  3459.       if (be->x > rect.x && be->x < rect.x + (int)rect.width &&
  3460.       be->y > rect.y && be->y < rect.y + (int)rect.height)
  3461.     {
  3462.       if (f->folder.debugLevel)
  3463.         fprintf(stderr, "XmLFolder: Pressed tab %d\n", i);
  3464.       SetActiveTab(f, tab, event, True);
  3465.       return;
  3466.     }
  3467.     }
  3468. }
  3469.  
  3470. static void 
  3471. PrimActivate(Widget w,
  3472.          XtPointer clientData,
  3473.          XtPointer callData)
  3474. {
  3475.   XmLFolderWidget f;
  3476.   XmAnyCallbackStruct *cbs;
  3477.  
  3478.   f = (XmLFolderWidget)XtParent(w);
  3479.   cbs = (XmAnyCallbackStruct *)callData;
  3480.   SetActiveTab(f, w, cbs->event, True);
  3481. }
  3482.  
  3483. static void 
  3484. PrimFocusIn(Widget w,
  3485.         XEvent *event,
  3486.         String *params,
  3487.         Cardinal *nparam)
  3488. {
  3489.   XmLFolderWidget f;
  3490.   Widget prevW;
  3491.  
  3492.   f = (XmLFolderWidget)XtParent(w);
  3493.   prevW = f->folder.focusW;
  3494.   f->folder.focusW = w;
  3495.   DrawTabHighlight(f, w);
  3496.   if (prevW)
  3497.     DrawTabHighlight(f, prevW);
  3498.   XmProcessTraversal(w, XmTRAVERSE_CURRENT);
  3499. }
  3500.  
  3501. static void 
  3502. PrimFocusOut(Widget w,
  3503.          XEvent *event,
  3504.          String *params,
  3505.          Cardinal *nparam)
  3506. {
  3507.   XmLFolderWidget f;
  3508.   Widget prevW;
  3509.  
  3510.   f = (XmLFolderWidget)XtParent(w);
  3511.   prevW = f->folder.focusW;
  3512.   f->folder.focusW = 0;
  3513.   if (prevW)
  3514.     DrawTabHighlight(f, prevW);
  3515.   DrawTabHighlight(f, w);
  3516. }
  3517.  
  3518. /*
  3519.    Public Functions
  3520. */
  3521.  
  3522. Widget 
  3523. XmLCreateFolder(Widget parent,
  3524.         char *name,
  3525.         ArgList arglist,
  3526.         Cardinal argcount)
  3527. {
  3528.   return XtCreateWidget(name, xmlFolderWidgetClass, parent,
  3529.             arglist, argcount);
  3530. }
  3531.  
  3532. Widget 
  3533. XmLFolderAddBitmapTab(Widget w,
  3534.               XmString string,
  3535.               char *bitmapBits,
  3536.               int bitmapWidth,
  3537.               int bitmapHeight)
  3538. {
  3539.   XmLFolderWidget f;
  3540.   Widget tab;
  3541.   Pixmap pix, inactPix;
  3542.   Window root;
  3543.   Display *dpy;
  3544.   int depth;
  3545.   char name[20];
  3546.  
  3547.   if (!XmLIsFolder(w))
  3548.     {
  3549.       XmLWarning(w, "AddBitmapTab() - widget not a XmLFolder");
  3550.       return 0;
  3551.     }
  3552.   f = (XmLFolderWidget)w;
  3553.   dpy = XtDisplay(w);
  3554.   root = DefaultRootWindow(dpy);
  3555.   depth = DefaultDepthOfScreen(XtScreen(w));
  3556.   pix = XCreatePixmapFromBitmapData(dpy, root, bitmapBits,
  3557.                     bitmapWidth, bitmapHeight, f->manager.foreground,
  3558.                     f->core.background_pixel, depth);
  3559.   inactPix = XCreatePixmapFromBitmapData(dpy, root, bitmapBits,
  3560.                      bitmapWidth, bitmapHeight, f->folder.inactiveFg,
  3561.                      f->folder.inactiveBg, depth);
  3562.   sprintf(name, "tab%d", f->folder.tabCount);
  3563.   tab = XtVaCreateManagedWidget(name,
  3564.                 xmDrawnButtonWidgetClass, w,
  3565.                 XmNfontList, f->folder.fontList,
  3566.                 XmNmarginWidth, 0,
  3567.                 XmNmarginHeight, 0,
  3568.                 XmNlabelString, string,
  3569.                 XmNtabPixmap, pix,
  3570.                 XmNtabInactivePixmap, inactPix,
  3571.                 XmNtabFreePixmaps, True,
  3572.                 NULL);
  3573.   return tab;
  3574. }
  3575.  
  3576. Widget 
  3577. XmLFolderAddBitmapTabForm(Widget w, 
  3578.               XmString string, 
  3579.               char *bitmapBits,
  3580.               int bitmapWidth,
  3581.               int bitmapHeight)
  3582. {
  3583.   Widget form, tab;
  3584.   XmLFolderWidget f;
  3585.   char name[20];
  3586.  
  3587.   if (!XmLIsFolder(w))
  3588.     {
  3589.       XmLWarning(w, "AddBitmapTabForm() - widget not a XmLFolder");
  3590.       return 0;
  3591.     }
  3592.   f = (XmLFolderWidget)w;
  3593.   tab = XmLFolderAddBitmapTab(w, string, bitmapBits,
  3594.                   bitmapWidth, bitmapHeight);
  3595.   sprintf(name, "form%d", f->folder.tabCount);
  3596.   form = XtVaCreateManagedWidget(name,
  3597.                  xmFormWidgetClass, w,
  3598.                  XmNbackground, f->core.background_pixel,
  3599.                  NULL);
  3600.   XtVaSetValues(tab, XmNtabManagedWidget, form, NULL);
  3601.   return form;
  3602. }
  3603.  
  3604. Widget 
  3605. XmLFolderAddTab(Widget w, 
  3606.         XmString string)
  3607. {
  3608.   Widget tab;
  3609.   XmLFolderWidget f;
  3610.   char name[20];
  3611.  
  3612.   if (!XmLIsFolder(w))
  3613.     {
  3614.       XmLWarning(w, "AddTab() - widget not a XmLFolder");
  3615.       return 0;
  3616.     }
  3617.   f = (XmLFolderWidget)w;
  3618.   sprintf(name, "tab%d", f->folder.tabCount);
  3619.   tab = XtVaCreateManagedWidget(name,
  3620.                 xmDrawnButtonWidgetClass, w,
  3621.                 XmNfontList, f->folder.fontList,
  3622.                 XmNmarginWidth, 0,
  3623.                 XmNmarginHeight, 0,
  3624.                 XmNlabelString, string,
  3625.                 NULL);
  3626.   return tab;
  3627. }
  3628.  
  3629. Widget 
  3630. XmLFolderAddTabFromClass(Widget w, 
  3631.         XmString string)
  3632. {
  3633.   Widget tab;
  3634.   XmLFolderWidget f;
  3635.   char name[20];
  3636.  
  3637.   if (!XmLIsFolder(w))
  3638.     {
  3639.       XmLWarning(w, "AddTab() - widget not a XmLFolder");
  3640.       return 0;
  3641.     }
  3642.   f = (XmLFolderWidget)w;
  3643.   sprintf(name, "tab%d", f->folder.tabCount);
  3644.  
  3645.   tab = XtVaCreateManagedWidget(name,
  3646.                                 f->folder.tabWidgetClass,
  3647. /*                                  xmDrawnButtonWidgetClass,  */
  3648.                                 w,
  3649.                                 XmNfontList, f->folder.fontList,
  3650. /*                 XmNmarginWidth, 0, */
  3651. /*                 XmNmarginHeight, 0, */
  3652.                                 XmNlabelString, string,
  3653.                                 NULL);
  3654.   return tab;
  3655. }
  3656.  
  3657. Widget 
  3658. XmLFolderAddTabForm(Widget w, 
  3659.             XmString string)
  3660. {
  3661.   Widget form, tab;
  3662.   XmLFolderWidget f;
  3663.   char name[20];
  3664.  
  3665.   if (!XmLIsFolder(w))
  3666.     {
  3667.       XmLWarning(w, "AddBitmapTabForm() - widget not a XmLFolder");
  3668.       return 0;
  3669.     }
  3670.   f = (XmLFolderWidget)w;
  3671.   tab = XmLFolderAddTab(w, string);
  3672.   sprintf(name, "form%d", f->folder.tabCount);
  3673.   form = XtVaCreateManagedWidget(name,
  3674.                  xmFormWidgetClass, w,
  3675.                  XmNbackground, f->core.background_pixel,
  3676.                  NULL);
  3677.   XtVaSetValues(tab, XmNtabManagedWidget, form, NULL);
  3678.   return form;
  3679. }
  3680.  
  3681. void 
  3682. XmLFolderSetActiveTab(Widget w,
  3683.               int position,
  3684.               Boolean notify)
  3685. {
  3686.   XmLFolderWidget f;
  3687.  
  3688.   if (!XmLIsFolder(w))
  3689.     {
  3690.       XmLWarning(w, "SetActiveTab() - widget not a XmLFolder");
  3691.       return;
  3692.     }
  3693.   f = (XmLFolderWidget)w;
  3694.   if (position < 0 || position >= f->folder.tabCount)
  3695.     {
  3696.       XmLWarning(w, "SetActiveTab() - invalid position");
  3697.       return;
  3698.     }
  3699.   SetActiveTab(f, f->folder.tabs[position], 0, notify);
  3700. }
  3701.