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

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. /*-----------------------------------------*/
  19. /*                                                                        */
  20. /* Name:        <Xfe/Oriented.c>                                        */
  21. /* Description:    XfeToolScroll widget source.                            */
  22. /* Author:        Ramiro Estrugo <ramiro@netscape.com>                    */
  23. /*                                                                        */
  24. /*----------------------------------------------------------------------*/
  25.  
  26.  
  27. #include <Xfe/OrientedP.h>
  28. #include <Xfe/Primitive.h>
  29.  
  30. #define MESSAGE1 "Widget is not an XfeOriented."
  31. #define MESSAGE2 "XmNcursorOn is a read-only resource."
  32. #define MESSAGE3 "The XfeOriented widget is not alive."
  33. #define MESSAGE4 "The descendant '%s' is not alive."
  34.  
  35. #define DESCENDANT_CURSOR_EVENTS    (EnterWindowMask |        \
  36.                                      LeaveWindowMask |        \
  37.                                      PointerMotionMask)
  38.  
  39. #define DESCENDANT_DRAG_EVENTS        (ButtonPressMask |         \
  40.                                      ButtonReleaseMask |     \
  41.                                      Button1MotionMask)
  42.  
  43. #define CURSOR_EVENTS                (EnterWindowMask |        \
  44.                                      LeaveWindowMask |        \
  45.                                      PointerMotionMask)
  46.  
  47. #define DRAG_EVENTS                    (ButtonPressMask |         \
  48.                                      ButtonReleaseMask |     \
  49.                                      Button1MotionMask)
  50.  
  51. #define HOR_CURSOR        "sb_h_double_arrow"
  52. #define VER_CURSOR        "sb_v_double_arrow"
  53.  
  54. /*----------------------------------------------------------------------*/
  55. /*                                                                        */
  56. /* Core class methods                                                    */
  57. /*                                                                        */
  58. /*----------------------------------------------------------------------*/
  59. static void     Initialize        (Widget,Widget,ArgList,Cardinal *);
  60. static void        ClassPartInit    (WidgetClass);
  61. static void     Destroy            (Widget);
  62. static Boolean    SetValues        (Widget,Widget,Widget,ArgList,Cardinal *);
  63.  
  64. /*----------------------------------------------------------------------*/
  65. /*                                                                        */
  66. /* Constraint class methods                                                */
  67. /*                                                                        */
  68. /*----------------------------------------------------------------------*/
  69. static void        ConstraintInitialize(Widget,Widget,ArgList,Cardinal *);
  70. static Boolean    ConstraintSetValues    (Widget,Widget,Widget,ArgList,Cardinal *);
  71.  
  72. /*----------------------------------------------------------------------*/
  73. /*                                                                        */
  74. /* XfeOriented class methods                                            */
  75. /*                                                                        */
  76. /*----------------------------------------------------------------------*/
  77. static void     EnterProc                (Widget,Widget,int,int);
  78. static void     LeaveProc                (Widget,Widget,int,int);
  79. static void     DescendantEnterProc        (Widget,Widget,int,int);
  80. static void     DescendantLeaveProc        (Widget,Widget,int,int);
  81.  
  82. /*----------------------------------------------------------------------*/
  83. /*                                                                        */
  84. /* Misc functions                                                        */
  85. /*                                                                        */
  86. /*----------------------------------------------------------------------*/
  87.  
  88. /*----------------------------------------------------------------------*/
  89. /*                                                                        */
  90. /* Event handlers                                                        */
  91. /*                                                                        */
  92. /*----------------------------------------------------------------------*/
  93. static void     CursorEH            (Widget,XtPointer,XEvent *,Boolean *);
  94. static void        DragEH                (Widget,XtPointer,XEvent *,Boolean *);
  95.  
  96. /*----------------------------------------------------------------------*/
  97. /*                                                                        */
  98. /* Descendant event handlers                                            */
  99. /*                                                                        */
  100. /*----------------------------------------------------------------------*/
  101. static void     DescendantCursorEH    (Widget,XtPointer,XEvent *,Boolean *);
  102. static void     DescendantDragEH    (Widget,XtPointer,XEvent *,Boolean *);
  103.  
  104. static void     DescendantPrimitiveCursorCB    (Widget,XtPointer,XtPointer);
  105.  
  106. /*----------------------------------------------------------------------*/
  107. /*                                                                        */
  108. /* XfeOriented Resources                                                */
  109. /*                                                                        */
  110. /*----------------------------------------------------------------------*/
  111. static XtResource resources[] =     
  112. {                    
  113.     /* Orientation resources */
  114.     { 
  115.         XmNorientation,
  116.         XmCOrientation,
  117.         XmROrientation,
  118.         sizeof(unsigned char),
  119.         XtOffsetOf(XfeOrientedRec , xfe_oriented . orientation),
  120.         XmRImmediate, 
  121.         (XtPointer) XmHORIZONTAL
  122.     },
  123.  
  124.     /* Drag resources */
  125.     { 
  126.         XmNallowDrag,
  127.         XmCBoolean,
  128.         XmRBoolean,
  129.         sizeof(Boolean),
  130.         XtOffsetOf(XfeOrientedRec , xfe_oriented . allow_drag),
  131.         XmRImmediate, 
  132.         (XtPointer) False
  133.     },
  134.     { 
  135.         XmNdragInProgress,
  136.         XmCDragInProgress,
  137.         XmRBoolean,
  138.         sizeof(Boolean),
  139.         XtOffsetOf(XfeOrientedRec , xfe_oriented . drag_in_progress),
  140.         XmRImmediate, 
  141.         (XtPointer) False
  142.     },
  143.  
  144.     { 
  145.         XmNcursorOn,
  146.         XmCReadOnly,
  147.         XmRBoolean,
  148.         sizeof(Boolean),
  149.         XtOffsetOf(XfeOrientedRec , xfe_oriented . cursor_on),
  150.         XmRImmediate, 
  151.         (XtPointer) False
  152.     },
  153.  
  154.     /* Cursor resources */
  155.     { 
  156.         XmNverticalCursor,
  157.         XmCVerticalCursor,
  158.         XmRCursor,
  159.         sizeof(Cursor),
  160.         XtOffsetOf(XfeOrientedRec , xfe_oriented . vertical_cursor),
  161.         XmRString, 
  162.         VER_CURSOR
  163.     },
  164.     { 
  165.         XmNhorizontalCursor,
  166.         XmCHorizontalCursor,
  167.         XmRCursor,
  168.         sizeof(Cursor),
  169.         XtOffsetOf(XfeOrientedRec , xfe_oriented . horizontal_cursor),
  170.         XmRString, 
  171.         HOR_CURSOR
  172.     },
  173.  
  174.     /* Spacing resources */
  175.     { 
  176.         XmNspacing,
  177.         XmCSpacing,
  178.         XmRHorizontalDimension,
  179.         sizeof(Dimension),
  180.         XtOffsetOf(XfeOrientedRec , xfe_oriented . spacing),
  181.         XmRImmediate, 
  182.         (XtPointer) 1
  183.     },
  184. };   
  185.  
  186. /*----------------------------------------------------------------------*/
  187. /*                                                                        */
  188. /* XfeToolBar Synthetic Resources                                        */
  189. /*                                                                        */
  190. /*----------------------------------------------------------------------*/
  191. static XmSyntheticResource syn_resources[] =
  192. {
  193.     { 
  194.         XmNspacing,
  195.         sizeof(Dimension),
  196.         XtOffsetOf(XfeOrientedRec , xfe_oriented . spacing),
  197.         _XmFromHorizontalPixels,
  198.         _XmToHorizontalPixels 
  199.     },
  200. };
  201.  
  202. /*----------------------------------------------------------------------*/
  203. /*                                                                        */
  204. /* XfeOriented constraint resources                                        */
  205. /*                                                                        */
  206. /*----------------------------------------------------------------------*/
  207. static XtResource constraint_resources[] = 
  208. {
  209.     { 
  210.         XmNallowDrag,
  211.         XmCBoolean,
  212.         XmRBoolean,
  213.         sizeof(Boolean),
  214.         XtOffsetOf(XfeOrientedConstraintRec , xfe_oriented . allow_drag),
  215.         XmRImmediate,
  216.         (XtPointer) False
  217.     },
  218. };   
  219.  
  220. /*----------------------------------------------------------------------*/
  221. /*                                                                        */
  222. /* Widget Class Record Initialization                                   */
  223. /*                                                                        */
  224. /*----------------------------------------------------------------------*/
  225. _XFE_WIDGET_CLASS_RECORD(oriented,Oriented) =
  226. {
  227.     {
  228.         (WidgetClass) &xfeManagerClassRec,        /* superclass           */
  229.         "XfeOriented",                            /* class_name           */
  230.         sizeof(XfeOrientedRec),                    /* widget_size          */
  231.         NULL,                                    /* class_initialize     */
  232.         ClassPartInit,                            /* class_part_initialize*/
  233.         FALSE,                                  /* class_inited         */
  234.         Initialize,                             /* initialize           */
  235.         NULL,                                   /* initialize_hook      */
  236.         XtInheritRealize,                        /* realize              */
  237.         NULL,                                    /* actions              */
  238.         0,                                        /* num_actions            */
  239.         resources,                              /* resources            */
  240.         XtNumber(resources),                    /* num_resources        */
  241.         NULLQUARK,                              /* xrm_class            */
  242.         TRUE,                                   /* compress_motion      */
  243.         XtExposeCompressMaximal,                /* compress_exposure    */
  244.         TRUE,                                   /* compress_enterleave    */
  245.         FALSE,                                  /* visible_interest     */
  246.         Destroy,                                /* destroy              */
  247.         XtInheritResize,                        /* resize               */
  248.         XtInheritExpose,                        /* expose               */
  249.         SetValues,                              /* set_values           */
  250.         NULL,                                   /* set_values_hook      */
  251.         XtInheritSetValuesAlmost,                /* set_values_almost    */
  252.         NULL,                                    /* get_values_hook      */
  253.         NULL,                                   /* accexfe_focus         */
  254.         XtVersion,                              /* version              */
  255.         NULL,                                   /* callback_private     */
  256.         XtInheritTranslations,                    /* tm_table                */
  257.         XtInheritQueryGeometry,                    /* query_geometry       */
  258.         XtInheritDisplayAccelerator,            /* display accel        */
  259.         NULL,                                   /* extension            */
  260.     },
  261.  
  262.     /* Composite Part */
  263.     {
  264.         XtInheritGeometryManager,                /* geometry_manager        */
  265.         XtInheritChangeManaged,                    /* change_managed        */
  266.         XtInheritInsertChild,                    /* insert_child            */
  267.         XtInheritDeleteChild,                    /* delete_child            */
  268.         NULL                                    /* extension            */
  269.     },
  270.  
  271.     /* Constraint Part */
  272.     {
  273.         constraint_resources,                    /* constraint res        */
  274.         XtNumber(constraint_resources),            /* num constraint res    */
  275.         sizeof(XfeOrientedConstraintRec),        /* constraint size        */
  276.         ConstraintInitialize,                    /* init proc            */
  277.         NULL,                                    /* destroy proc            */
  278.         ConstraintSetValues,                    /* set values proc        */
  279.         NULL,                                   /* extension            */
  280.     },
  281.  
  282.     /* XmManager Part */
  283.     {
  284.         XtInheritTranslations,                    /* tm_table                */
  285.         syn_resources,                            /* syn resources        */
  286.         XtNumber(syn_resources),                /* num syn_resources    */
  287.         NULL,                                   /* syn_cont_resources      */
  288.         0,                                      /* num_syn_cont_resource*/
  289.         XmInheritParentProcess,                 /* parent_process          */
  290.         NULL,                                   /* extension               */
  291.     },
  292.  
  293.     /* XfeManager Part     */
  294.     {
  295.         XfeInheritBitGravity,                    /* bit_gravity            */
  296.         XfeInheritPreferredGeometry,            /* preferred_geometry    */
  297.         XfeInheritMinimumGeometry,                /* minimum_geometry        */
  298.         XfeInheritUpdateRect,                    /* update_rect            */
  299.         NULL,                                    /* accept_child            */
  300.         NULL,                                    /* insert_child            */
  301.         NULL,                                    /* delete_child            */
  302.         NULL,                                    /* change_managed        */
  303.         NULL,                                    /* prepare_components    */
  304.         NULL,                                    /* layout_components    */
  305.         NULL,                                    /* layout_children        */
  306.         NULL,                                    /* draw_background        */
  307.         XfeInheritDrawShadow,                    /* draw_shadow            */
  308.         NULL,                                    /* draw_components        */
  309.         NULL,                                    /* extension              */
  310.     },
  311.  
  312.     /* XfeOriented Part */
  313.     {
  314.         EnterProc,                                /* enter                */
  315.         LeaveProc,                                /* leave                */
  316.         NULL,                                    /* motion                */
  317.         NULL,                                    /* drag_start            */
  318.         NULL,                                    /* drag_end                */
  319.         NULL,                                    /* drag_motion            */
  320.         DescendantEnterProc,                    /* des_enter            */
  321.         DescendantLeaveProc,                    /* des_leave            */
  322.         NULL,                                    /* des_motion            */
  323.         NULL,                                    /* des_drag_start        */
  324.         NULL,                                    /* des_drag_end            */
  325.         NULL,                                    /* des_drag_motion        */
  326.         NULL,                                    /* extension              */
  327.     },
  328. };
  329.  
  330. /*----------------------------------------------------------------------*/
  331. /*                                                                        */
  332. /* xfeOrientedWidgetClassdeclaration.                                    */
  333. /*                                                                        */
  334. /*----------------------------------------------------------------------*/
  335. _XFE_WIDGET_CLASS(oriented,Oriented);
  336.  
  337. /*----------------------------------------------------------------------*/
  338. /*                                                                        */
  339. /* Core class methods                                                    */
  340. /*                                                                        */
  341. /*----------------------------------------------------------------------*/
  342. static void
  343. ClassPartInit(WidgetClass wc)
  344. {
  345.     XfeOrientedWidgetClass cc = (XfeOrientedWidgetClass) wc;
  346.     XfeOrientedWidgetClass sc = (XfeOrientedWidgetClass) wc->core_class.superclass;
  347.  
  348.     _XfeResolve(cc,sc,xfe_oriented_class,enter,
  349.                 XfeInheritEnter);
  350.  
  351.     _XfeResolve(cc,sc,xfe_oriented_class,leave,
  352.                 XfeInheritLeave);
  353.  
  354.     _XfeResolve(cc,sc,xfe_oriented_class,motion,
  355.                 XfeInheritMotion);
  356.  
  357.     _XfeResolve(cc,sc,xfe_oriented_class,drag_start,
  358.                 XfeInheritDragStart);
  359.  
  360.     _XfeResolve(cc,sc,xfe_oriented_class,drag_end,
  361.                 XfeInheritDragEnd);
  362.  
  363.     _XfeResolve(cc,sc,xfe_oriented_class,drag_motion,
  364.                 XfeInheritDragMotion);
  365.    
  366.     _XfeResolve(cc,sc,xfe_oriented_class,descendant_enter,
  367.                 XfeInheritDescendantEnter);
  368.  
  369.     _XfeResolve(cc,sc,xfe_oriented_class,descendant_leave,
  370.                 XfeInheritDescendantLeave);
  371.  
  372.     _XfeResolve(cc,sc,xfe_oriented_class,descendant_motion,
  373.                 XfeInheritDescendantMotion);
  374.  
  375.     _XfeResolve(cc,sc,xfe_oriented_class,descendant_drag_start,
  376.                 XfeInheritDescendantDragStart);
  377.  
  378.     _XfeResolve(cc,sc,xfe_oriented_class,descendant_drag_end,
  379.                 XfeInheritDescendantDragEnd);
  380.  
  381.     _XfeResolve(cc,sc,xfe_oriented_class,descendant_drag_motion,
  382.                 XfeInheritDescendantDragMotion);
  383. }
  384. /*----------------------------------------------------------------------*/
  385. static void
  386. Initialize(Widget rw,Widget nw,ArgList args,Cardinal *nargs)
  387. {
  388.     XfeOrientedPart *        op = _XfeOrientedPart(nw);
  389.  
  390.     /* Make sure rep types are ok */
  391.     XfeRepTypeCheck(nw,XmROrientation,&op->orientation,XmHORIZONTAL);
  392.  
  393.     /* Set the allow_drag state for the first time */
  394.     XfeOrientedSetAllowDrag(nw,op->allow_drag);
  395.  
  396.     /* Initialize other private members */
  397.     op->drag_start_x = 0;
  398.     op->drag_start_y = 0;
  399.  
  400.     /* Finish of initialization */
  401.     _XfeManagerChainInitialize(rw,nw,xfeOrientedWidgetClass);
  402. }
  403. /*----------------------------------------------------------------------*/
  404. static void
  405. Destroy(Widget w)
  406. {
  407. }
  408. /*----------------------------------------------------------------------*/
  409. static Boolean
  410. SetValues(Widget ow,Widget rw,Widget nw,ArgList args,Cardinal *nargs)
  411. {
  412.     XfeOrientedPart *        np = _XfeOrientedPart(nw);
  413.     XfeOrientedPart *        op = _XfeOrientedPart(ow);
  414.  
  415.     /* cursor_on */
  416.     if (np->cursor_on != op->cursor_on)
  417.     {
  418.         np->cursor_on = op->cursor_on;
  419.  
  420.         _XfeWarning(nw,MESSAGE2);
  421.     }
  422.  
  423.     /* orientation */
  424.     if (np->orientation != op->orientation)
  425.     {
  426.         /* Make sure the new orientation is ok */
  427.         XfeRepTypeCheck(nw,XmROrientation,&np->orientation,XmHORIZONTAL);
  428.  
  429.         _XfemConfigFlags(nw) |= XfeConfigGLE;
  430.     }
  431.  
  432.     /* spacing */
  433.     if (np->spacing != op->spacing)
  434.     {
  435.         _XfemConfigFlags(nw) |= XfeConfigGLE;
  436.     }
  437.  
  438.     /* allow_drag */
  439.     if (np->allow_drag != op->allow_drag)
  440.     {
  441.         XfeOrientedSetAllowDrag(nw,np->allow_drag);
  442.     }
  443.  
  444.     return _XfeManagerChainSetValues(ow,rw,nw,xfeOrientedWidgetClass);
  445. }
  446. /*----------------------------------------------------------------------*/
  447.  
  448. /*----------------------------------------------------------------------*/
  449. /*                                                                        */
  450. /* Constraint class methods                                                */
  451. /*                                                                        */
  452. /*----------------------------------------------------------------------*/
  453. static void
  454. ConstraintInitialize(Widget rc,Widget nc,ArgList av,Cardinal * ac)
  455. {
  456.       Widget                        w = _XfeParent(nc);
  457.     XfeOrientedConstraintPart *    cp = _XfeOrientedConstraintPart(nc);
  458.  
  459.     XfeOrientedDescendantSetAllowDrag(w,nc,cp->allow_drag);
  460.  
  461.     /* Finish constraint initialization */
  462.     _XfeConstraintChainInitialize(rc,nc,xfeOrientedWidgetClass);
  463. }
  464. /*----------------------------------------------------------------------*/
  465. static Boolean
  466. ConstraintSetValues(Widget oc,Widget rc,Widget nc,ArgList av,Cardinal * ac)
  467. {
  468.     Widget                        w = XtParent(nc);
  469.      XfeOrientedConstraintPart *    ncp = _XfeOrientedConstraintPart(nc);
  470.      XfeOrientedConstraintPart *    ocp = _XfeOrientedConstraintPart(oc);
  471.  
  472.     /* allow_drag */
  473.     if (ncp->allow_drag != ocp->allow_drag)
  474.     {
  475.         XfeOrientedDescendantSetAllowDrag(w,nc,ncp->allow_drag);
  476.     }
  477.  
  478.     /* Finish constraint set values */
  479.     return _XfeConstraintChainSetValues(oc,rc,nc,xfeOrientedWidgetClass);
  480. }
  481. /*----------------------------------------------------------------------*/
  482.  
  483. /*----------------------------------------------------------------------*/
  484. /*                                                                        */
  485. /* XfeOriented class methods                                            */
  486. /*                                                                        */
  487. /*----------------------------------------------------------------------*/
  488. static void
  489. EnterProc(Widget w,Widget descendant,int x,int y)
  490. {
  491.     _XfeOrientedSetCursorState(w,True);
  492. }
  493. /*----------------------------------------------------------------------*/
  494. static void
  495. LeaveProc(Widget w,Widget descendant,int x,int y)
  496. {
  497.     _XfeOrientedSetCursorState(w,False);
  498. }
  499. /*----------------------------------------------------------------------*/
  500. static void
  501. DescendantEnterProc(Widget w,Widget descendant,int x,int y)
  502. {
  503.     _XfeOrientedSetCursorState(w,True);
  504. }
  505. /*----------------------------------------------------------------------*/
  506. static void
  507. DescendantLeaveProc(Widget w,Widget descendant,int x,int y)
  508. {
  509.     _XfeOrientedSetCursorState(w,False);
  510. }
  511. /*----------------------------------------------------------------------*/
  512.  
  513.  
  514. /*----------------------------------------------------------------------*/
  515. /*                                                                        */
  516. /* Misc functions                                                        */
  517. /*                                                                        */
  518. /*----------------------------------------------------------------------*/
  519.  
  520. /*----------------------------------------------------------------------*/
  521. /*                                                                        */
  522. /* Dragging event handlers                                                */
  523. /*                                                                        */
  524. /*----------------------------------------------------------------------*/
  525. static void
  526. CursorEH(Widget            oriented,
  527.          XtPointer        client_data,
  528.          XEvent *        event,
  529.          Boolean *        cont)
  530. {
  531.     Widget                w = (Widget) client_data;
  532.     XfeOrientedPart *    op = _XfeOrientedPart(w);
  533.     int                    x;
  534.     int                    y;
  535.  
  536.     /* If a drag is in progress, dont change the cursor */
  537.     if (op->drag_in_progress)
  538.     {
  539.         return;
  540.     }
  541.  
  542.     /* Obtain the coords for the event */
  543.     XfeEventGetXY(event,&x,&y);
  544.  
  545.     /* Enter */
  546.     if (event->type == EnterNotify)
  547.     {
  548.         _XfeOrientedEnter(w,NULL,x,y);
  549.     }
  550.     /* Leave */
  551.     else if (event->type == LeaveNotify)
  552.     {
  553.         _XfeOrientedLeave(w,NULL,x,y);
  554.     }
  555.     /* Motion */
  556.     else if (event->type == MotionNotify)
  557.     {
  558.         _XfeOrientedMotion(w,NULL,x,y);
  559.     }
  560.  
  561.     *cont = True;
  562. }
  563. /*----------------------------------------------------------------------*/
  564. static void
  565. DragEH(Widget        oriented,
  566.        XtPointer    client_data,
  567.        XEvent *        event,
  568.        Boolean *    cont)
  569. {
  570.     Widget                w = (Widget) client_data;
  571.     XfeOrientedPart *    op = _XfeOrientedPart(w);
  572.     int                    x;
  573.     int                    y;
  574.     
  575.     /* Obtain the coords for the event */
  576.     XfeEventGetXY(event,&x,&y);
  577.  
  578.     switch(event->type)
  579.     {
  580.     case ButtonPress:
  581.  
  582.         /* Make sure a drag is not already in progress */
  583.         if (!op->drag_in_progress)
  584.         {
  585.             op->drag_in_progress = True;
  586.  
  587.             op->drag_start_x = x;
  588.             op->drag_start_y = y;
  589.  
  590.             _XfeOrientedDragStart(w,NULL,x,y);
  591.         }
  592.  
  593.         break;
  594.         
  595.     case ButtonRelease:
  596.  
  597.         /* Make sure a drag is indeed in progress */
  598.         if (op->drag_in_progress)
  599.         {
  600.             op->drag_in_progress = False;
  601.             
  602.             _XfeOrientedDragEnd(w,NULL,x,y);
  603.         }
  604.         
  605.         break;
  606.         
  607.     case MotionNotify:
  608.  
  609.         /* Make sure a drag is indeed in progress */
  610.         if (op->drag_in_progress)
  611.         {
  612.             op->drag_in_progress = True;
  613.  
  614.             _XfeOrientedDragMotion(w,NULL,x,y);
  615.         }
  616.         
  617.         break;
  618.     }
  619.  
  620.     *cont = True;
  621. }
  622. /*----------------------------------------------------------------------*/
  623.  
  624. /*----------------------------------------------------------------------*/
  625. /*                                                                        */
  626. /* Descendant event handlers                                            */
  627. /*                                                                        */
  628. /*----------------------------------------------------------------------*/
  629. static void
  630. DescendantCursorEH(Widget        descendant,
  631.                    XtPointer    client_data,
  632.                    XEvent *        event,
  633.                    Boolean *    cont)
  634. {
  635.     Widget                w = (Widget) client_data;
  636.     XfeOrientedPart *    op = _XfeOrientedPart(w);
  637.     int                    root_x;
  638.     int                    root_y;
  639.     int                    x;
  640.     int                    y;
  641.  
  642.     /* If a drag is in progress, dont change the cursor */
  643.     if (op->drag_in_progress)
  644.     {
  645.         return;
  646.     }
  647.  
  648.     /* Obtain the root coords for the event */
  649.     XfeEventGetRootXY(event,&root_x,&root_y);
  650.  
  651.     /* Compute coords relative to the oriented widget */
  652.     x = root_x - XfeRootX(w);
  653.     y = root_y - XfeRootY(w);
  654.  
  655.     /* Enter */
  656.     if (event->type == EnterNotify)
  657.     {
  658.         _XfeOrientedDescendantEnter(w,descendant,x,y);
  659.     }
  660.     /* Leave */
  661.     else if (event->type == LeaveNotify)
  662.     {
  663.         _XfeOrientedDescendantLeave(w,descendant,x,y);
  664.     }
  665.     /* Motion */
  666.     else if (event->type == MotionNotify)
  667.     {
  668.         _XfeOrientedDescendantMotion(w,descendant,x,y);
  669.     }
  670.  
  671.     *cont = True;
  672. }
  673. /*----------------------------------------------------------------------*/
  674. static void
  675. DescendantDragEH(Widget        descendant,
  676.                  XtPointer    client_data,
  677.                  XEvent *    event,
  678.                  Boolean *    cont)
  679. {
  680.     Widget                w = (Widget) client_data;
  681.     XfeOrientedPart *    op = _XfeOrientedPart(w);
  682.     int                    root_x;
  683.     int                    root_y;
  684.     int                    x;
  685.     int                    y;
  686.     
  687.     /* Obtain the root coords for the event */
  688.     XfeEventGetRootXY(event,&root_x,&root_y);
  689.  
  690.     /* Compute coords relative to the oriented widget */
  691.     x = root_x - XfeRootX(w);
  692.     y = root_y - XfeRootY(w);
  693.         
  694.     switch(event->type)
  695.     {
  696.     case ButtonPress:
  697.  
  698.         /* Make sure a drag is not already in progress */
  699.         if (!op->drag_in_progress)
  700.         {
  701.             op->drag_in_progress = True;
  702.  
  703.             op->drag_start_x = x;
  704.             op->drag_start_y = y;
  705.  
  706.             _XfeOrientedDescendantDragStart(w,descendant,x,y);
  707.         }
  708.  
  709.         break;
  710.         
  711.     case ButtonRelease:
  712.  
  713.         /* Make sure a drag is indeed in progress */
  714.         if (op->drag_in_progress)
  715.         {
  716.             op->drag_in_progress = False;
  717.             
  718.             _XfeOrientedDescendantDragEnd(w,descendant,x,y);
  719.         }
  720.  
  721.         break;
  722.         
  723.     case MotionNotify:
  724.  
  725.         /* Make sure a drag is indeed in progress */
  726.         if (op->drag_in_progress)
  727.         {
  728.             op->drag_in_progress = True;
  729.  
  730.             _XfeOrientedDescendantDragMotion(w,descendant,x,y);
  731.         }
  732.         
  733.         break;
  734.     }
  735.  
  736.     *cont = True;
  737. }
  738. /*----------------------------------------------------------------------*/
  739. static void
  740. DescendantPrimitiveCursorCB(Widget        descendant,
  741.                             XtPointer    client_data,
  742.                             XtPointer    call_data)
  743. {
  744.     Widget                    w = (Widget) client_data;
  745.     XfeOrientedPart *        op = _XfeOrientedPart(w);
  746.  
  747.     XmAnyCallbackStruct *    data = (XmAnyCallbackStruct *) call_data;
  748.     XEvent *                event = data->event;
  749.  
  750.     int                        root_x;
  751.     int                        root_y;
  752.     int                        x;
  753.     int                        y;
  754.  
  755.     /* If a drag is in progress, dont change the cursor */
  756.     if (op->drag_in_progress)
  757.     {
  758.         return;
  759.     }
  760.  
  761.     /* Obtain the root coords for the event */
  762.     XfeEventGetRootXY(event,&root_x,&root_y);
  763.  
  764.     /* Compute coords relative to the oriented widget */
  765.     x = root_x - XfeRootX(w);
  766.     y = root_y - XfeRootY(w);
  767.  
  768.     /* Enter */
  769.     if (data->reason == XmCR_ENTER)
  770.     {
  771.         _XfeOrientedDescendantEnter(w,descendant,x,y);
  772.     }
  773.     /* Leave */
  774.     else if (data->reason == XmCR_LEAVE)
  775.     {
  776.         _XfeOrientedDescendantLeave(w,descendant,x,y);
  777.     }
  778. }
  779. /*----------------------------------------------------------------------*/
  780.  
  781. /*----------------------------------------------------------------------*/
  782. /*                                                                        */
  783. /* XfeOriented method invocation functions                                */
  784. /*                                                                        */
  785. /*----------------------------------------------------------------------*/
  786. /* extern */ void
  787. _XfeOrientedEnter(Widget w,Widget descendant,int x,int y)
  788. {
  789.     XfeOrientedWidgetClass    oc = (XfeOrientedWidgetClass) XtClass(w);
  790.  
  791.     if (oc->xfe_oriented_class.enter)
  792.     {
  793.         (*oc->xfe_oriented_class.enter)(w,descendant,x,y);
  794.     }
  795. }
  796. /*----------------------------------------------------------------------*/
  797. /* extern */ void
  798. _XfeOrientedLeave(Widget w,Widget descendant,int x,int y)
  799. {
  800.     XfeOrientedWidgetClass    oc = (XfeOrientedWidgetClass) XtClass(w);
  801.  
  802.     if (oc->xfe_oriented_class.leave)
  803.     {
  804.         (*oc->xfe_oriented_class.leave)(w,descendant,x,y);
  805.     }
  806. }
  807. /*----------------------------------------------------------------------*/
  808. /* extern */ void
  809. _XfeOrientedMotion(Widget w,Widget descendant,int x,int y)
  810. {
  811.     XfeOrientedWidgetClass    oc = (XfeOrientedWidgetClass) XtClass(w);
  812.  
  813.     if (oc->xfe_oriented_class.motion)
  814.     {
  815.         (*oc->xfe_oriented_class.motion)(w,descendant,x,y);
  816.     }
  817. }
  818. /*----------------------------------------------------------------------*/
  819. /* extern */ void
  820. _XfeOrientedDragStart(Widget w,Widget descendant,int x,int y)
  821. {
  822.     XfeOrientedWidgetClass    oc = (XfeOrientedWidgetClass) XtClass(w);
  823.  
  824.     if (oc->xfe_oriented_class.drag_start)
  825.     {
  826.         (*oc->xfe_oriented_class.drag_start)(w,descendant,x,y);
  827.     }
  828. }
  829. /*----------------------------------------------------------------------*/
  830. /* extern */ void
  831. _XfeOrientedDragEnd(Widget w,Widget descendant,int x,int y)
  832. {
  833.     XfeOrientedWidgetClass    oc = (XfeOrientedWidgetClass) XtClass(w);
  834.  
  835.     if (oc->xfe_oriented_class.drag_end)
  836.     {
  837.         (*oc->xfe_oriented_class.drag_end)(w,descendant,x,y);
  838.     }
  839. }
  840. /*----------------------------------------------------------------------*/
  841. /* extern */ void
  842. _XfeOrientedDragMotion(Widget w,Widget descendant,int x,int y)
  843. {
  844.     XfeOrientedWidgetClass    oc = (XfeOrientedWidgetClass) XtClass(w);
  845.  
  846.     if (oc->xfe_oriented_class.drag_motion)
  847.     {
  848.         (*oc->xfe_oriented_class.drag_motion)(w,descendant,x,y);
  849.     }
  850. }
  851. /*----------------------------------------------------------------------*/
  852. /* extern */ void
  853. _XfeOrientedDescendantEnter(Widget w,Widget descendant,int x,int y)
  854. {
  855.     XfeOrientedWidgetClass    oc = (XfeOrientedWidgetClass) XtClass(w);
  856.  
  857.     if (oc->xfe_oriented_class.descendant_enter)
  858.     {
  859.         (*oc->xfe_oriented_class.descendant_enter)(w,descendant,x,y);
  860.     }
  861. }
  862. /*----------------------------------------------------------------------*/
  863. /* extern */ void
  864. _XfeOrientedDescendantLeave(Widget w,Widget descendant,int x,int y)
  865. {
  866.     XfeOrientedWidgetClass    oc = (XfeOrientedWidgetClass) XtClass(w);
  867.  
  868.     if (oc->xfe_oriented_class.descendant_leave)
  869.     {
  870.         (*oc->xfe_oriented_class.descendant_leave)(w,descendant,x,y);
  871.     }
  872. }
  873. /*----------------------------------------------------------------------*/
  874. /* extern */ void
  875. _XfeOrientedDescendantMotion(Widget w,Widget descendant,int x,int y)
  876. {
  877.     XfeOrientedWidgetClass    oc = (XfeOrientedWidgetClass) XtClass(w);
  878.  
  879.     if (oc->xfe_oriented_class.descendant_motion)
  880.     {
  881.         (*oc->xfe_oriented_class.descendant_motion)(w,descendant,x,y);
  882.     }
  883. }
  884. /*----------------------------------------------------------------------*/
  885. /* extern */ void
  886. _XfeOrientedDescendantDragStart(Widget w,Widget descendant,int x,int y)
  887. {
  888.     XfeOrientedWidgetClass    oc = (XfeOrientedWidgetClass) XtClass(w);
  889.  
  890.     if (oc->xfe_oriented_class.descendant_drag_start)
  891.     {
  892.         (*oc->xfe_oriented_class.descendant_drag_start)(w,descendant,x,y);
  893.     }
  894. }
  895. /*----------------------------------------------------------------------*/
  896. /* extern */ void
  897. _XfeOrientedDescendantDragEnd(Widget w,Widget descendant,int x,int y)
  898. {
  899.     XfeOrientedWidgetClass    oc = (XfeOrientedWidgetClass) XtClass(w);
  900.  
  901.     if (oc->xfe_oriented_class.descendant_drag_end)
  902.     {
  903.         (*oc->xfe_oriented_class.descendant_drag_end)(w,descendant,x,y);
  904.     }
  905. }
  906. /*----------------------------------------------------------------------*/
  907. /* extern */ void
  908. _XfeOrientedDescendantDragMotion(Widget w,Widget descendant,int x,int y)
  909. {
  910.     XfeOrientedWidgetClass    oc = (XfeOrientedWidgetClass) XtClass(w);
  911.  
  912.     if (oc->xfe_oriented_class.descendant_drag_motion)
  913.     {
  914.         (*oc->xfe_oriented_class.descendant_drag_motion)(w,descendant,x,y);
  915.     }
  916. }
  917. /*----------------------------------------------------------------------*/
  918.  
  919. /*----------------------------------------------------------------------*/
  920. /*                                                                        */
  921. /* XfeOriented private Methods                                            */
  922. /*                                                                        */
  923. /*----------------------------------------------------------------------*/
  924. /* extern */ void
  925. _XfeOrientedSetCursorState(Widget w,Boolean state)
  926. {
  927.     XfeOrientedPart *    op = _XfeOrientedPart(w);
  928.     Cursor                cursor;
  929.  
  930.     assert( XfeIsOriented(w) );
  931.     assert( _XfeIsAlive(w) );
  932.  
  933.     /* Vertical */
  934.     if (op->orientation == XmVERTICAL)
  935.     {
  936.         cursor = op->vertical_cursor;
  937.     }
  938.     /* Horizontal */
  939.     else
  940.     {
  941.         cursor = op->horizontal_cursor;
  942.     }
  943.  
  944.     /* Make sure the cursor is good */
  945.     if (!_XfeCursorGood(cursor))
  946.     {
  947.         return;
  948.     }
  949.  
  950.     /* On */
  951.     if (state)
  952.     {
  953.         /* Turn cursor on if needed */
  954.         if (!op->cursor_on)
  955.         {
  956.             op->cursor_on = True;
  957.  
  958.             XfeCursorDefine(w,cursor);
  959.         }
  960.     }
  961.     /* Off */
  962.     else
  963.     {
  964.         /* Turn cursor off if needed */
  965.         if (op->cursor_on)
  966.         {
  967.             op->cursor_on = False;
  968.  
  969.             XfeCursorUndefine(w);
  970.         }
  971.     }
  972. }
  973. /*----------------------------------------------------------------------*/
  974.  
  975. /*----------------------------------------------------------------------*/
  976. /*                                                                        */
  977. /* XfeOriented public Methods                                            */
  978. /*                                                                        */
  979. /*----------------------------------------------------------------------*/
  980. /* extern */ Boolean
  981. XfeOrientedSetAllowDrag(Widget w,Boolean allow_drag)
  982. {
  983.     assert( XfeIsOriented(w) );
  984.     assert( _XfeIsAlive(w) );
  985.  
  986.     /* Make sure the oriented is alive */
  987.     if (!_XfeIsAlive(w))
  988.     {
  989.         _XfeWarning(w,MESSAGE3);
  990.         
  991.         return False;
  992.     }
  993.  
  994.     /* First remove any event handlers that might have been added */
  995.     XtRemoveEventHandler(w,
  996.                          CURSOR_EVENTS,
  997.                          True,
  998.                          CursorEH,
  999.                          w);
  1000.     
  1001.     XtRemoveEventHandler(w,
  1002.                          DRAG_EVENTS,
  1003.                          True,
  1004.                          DragEH,
  1005.                          w);
  1006.     
  1007.     /* Add the event handlers if needed */
  1008.     if (allow_drag)
  1009.     {
  1010.         XtAddEventHandler(w,
  1011.                           CURSOR_EVENTS,
  1012.                           True,
  1013.                           CursorEH,
  1014.                           w);
  1015.         
  1016.         XtAddEventHandler(w,
  1017.                           DRAG_EVENTS,
  1018.                           True,
  1019.                           DragEH,
  1020.                           w);
  1021.     }
  1022.  
  1023.     return True;
  1024. }
  1025. /*----------------------------------------------------------------------*/
  1026. /* extern */ Boolean
  1027. XfeOrientedDescendantSetAllowDrag(Widget    w,
  1028.                                   Widget    descendant,
  1029.                                   Boolean    allow_drag)
  1030. {
  1031.     assert( XfeIsOriented(w) );
  1032.     assert( _XfeIsAlive(w) );
  1033.     assert( _XfeIsAlive(descendant) );
  1034.  
  1035.     /* Make sure the oriented is alive */
  1036.     if (!_XfeIsAlive(w))
  1037.     {
  1038.         _XfeWarning(w,MESSAGE3);
  1039.         
  1040.         return False;
  1041.     }
  1042.  
  1043.     /* Make sure the descendant is alive */
  1044.     if (!_XfeIsAlive(descendant))
  1045.     {
  1046.         _XfeArgWarning(w,MESSAGE4,descendant);
  1047.         
  1048.         return False;
  1049.     }
  1050.  
  1051.     /* First remove any event handlers that might have been added */
  1052.     if (XfeIsPrimitive(descendant))
  1053.     {
  1054.         XtRemoveCallback(descendant,
  1055.                          XmNenterCallback,
  1056.                          DescendantPrimitiveCursorCB,
  1057.                          w);
  1058.  
  1059.         XtRemoveCallback(descendant,
  1060.                          XmNleaveCallback,
  1061.                          DescendantPrimitiveCursorCB,
  1062.                          w);
  1063.     }
  1064.     else
  1065.     {
  1066.         XtRemoveEventHandler(descendant,
  1067.                              DESCENDANT_CURSOR_EVENTS,
  1068.                              True,
  1069.                              DescendantCursorEH,
  1070.                              w);
  1071.     }
  1072.     
  1073.     /* Add the event handlers if needed */
  1074.     if (allow_drag)
  1075.     {
  1076.         if (XfeIsPrimitive(descendant))
  1077.         {
  1078.             XtAddCallback(descendant,
  1079.                           XmNenterCallback,
  1080.                           DescendantPrimitiveCursorCB,
  1081.                           w);
  1082.             
  1083.             XtAddCallback(descendant,
  1084.                           XmNleaveCallback,
  1085.                           DescendantPrimitiveCursorCB,
  1086.                           w);
  1087.         }
  1088.         else
  1089.         {
  1090.             XtAddEventHandler(descendant,
  1091.                               DESCENDANT_CURSOR_EVENTS,
  1092.                               True,
  1093.                               DescendantCursorEH,
  1094.                               w);
  1095.         }
  1096.  
  1097.         XtAddEventHandler(descendant,
  1098.                           DESCENDANT_DRAG_EVENTS,
  1099.                           True,
  1100.                           DescendantDragEH,
  1101.                           w);
  1102.     }
  1103.  
  1104.  
  1105.     return True;
  1106. }
  1107. /*----------------------------------------------------------------------*/
  1108. static void
  1109. ApplyChildSetAllowDrag(Widget w,Widget child,XtPointer client_data)
  1110. {
  1111.     XfeOrientedDescendantSetAllowDrag(w,child,(Boolean) client_data);
  1112. }
  1113. /*----------------------------------------------------------------------*/
  1114. /* extern */ void
  1115. XfeOrientedChildrenSetAllowDrag(Widget w,Boolean allow_drag)
  1116. {
  1117.     assert( XfeIsOriented(w) );
  1118.     assert( _XfeIsAlive(w) );
  1119.  
  1120.     /* Make sure the oriented is alive */
  1121.     if (!_XfeIsAlive(w))
  1122.     {
  1123.         _XfeWarning(w,MESSAGE3);
  1124.         
  1125.         return;
  1126.     }
  1127.     
  1128.     XfeManagerApply(w,ApplyChildSetAllowDrag,(XtPointer) allow_drag,False);
  1129. }
  1130. /*----------------------------------------------------------------------*/
  1131.