~ubuntu-branches/ubuntu/quantal/openmotif/quantal

« back to all changes in this revision

Viewing changes to lib/Xm/TravAct.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Bauer
  • Date: 2010-06-23 12:12:31 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100623121231-u89gxdp51sg9wjj2
Tags: 2.3.0-1
* New Maintainer (Closes: #379258) 
* Acknowledge NMU changes
* New upstream release (Closes: #494375)
* Get rid of security patches as they are already part of new upstream
  release (00-xpmvuln.openmotif.patch, 342092-CVE-2005-3964.patch)
* Bump Standards to 3.8.4
* Added {misc:Depends} to make the package lintian cleaner
* Fix weak-library-dev-dependency by adding ${binary:Version}) for the
  -dev Package of openmotif
* Let package depend on autotools-dev to use newer autotools-helper-files
* Work around an autoconf-bug (Gentoo-Bug #1475)
* Added Client-side anti-aliased fonts support via XFT
* Added UTF-8 and UTF8_STRING atom support
* Ability to show text and pixmaps in Label, LabelGadget and all
  derived widgets
* Support of PNG/JPEG image formats in the same way as XPM is supported
* Increase FILE_OFFSET_BITS to 64 to show files >2GB in file-selector
  Idea taken from Magne Oestlyngen (Closes: #288537)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
 *  @OPENGROUP_COPYRIGHT@
 
3
 *  COPYRIGHT NOTICE
 
4
 *  Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc.
 
5
 *  Copyright (c) 1996, 1997, 1998, 1999, 2000 The Open Group
 
6
 *  ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for
 
7
 *  the full copyright text.
 
8
 *  
 
9
 *  This software is subject to an open license. It may only be
 
10
 *  used on, with or for operating systems which are themselves open
 
11
 *  source systems. You must contact The Open Group for a license
 
12
 *  allowing distribution and sublicensing of this software on, with,
 
13
 *  or for operating systems which are not Open Source programs.
 
14
 *  
 
15
 *  See http://www.opengroup.org/openmotif/license for full
 
16
 *  details of the license agreement. Any use, reproduction, or
 
17
 *  distribution of the program constitutes recipient's acceptance of
 
18
 *  this agreement.
 
19
 *  
 
20
 *  EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
 
21
 *  PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 
22
 *  KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
 
23
 *  WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
 
24
 *  OR FITNESS FOR A PARTICULAR PURPOSE
 
25
 *  
 
26
 *  EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT
 
27
 *  NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT,
 
28
 *  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
29
 *  DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED
 
30
 *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
31
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 
32
 *  ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
 
33
 *  EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
 
34
 *  POSSIBILITY OF SUCH DAMAGES.
 
35
*/ 
 
36
/* 
 
37
 * HISTORY
 
38
*/ 
 
39
#ifdef HAVE_CONFIG_H
 
40
#include <config.h>
 
41
#endif
 
42
 
 
43
 
 
44
#ifdef REV_INFO
 
45
#ifndef lint
 
46
static char rcsid[] = "$TOG: TravAct.c /main/14 1999/05/27 13:58:09 mgreess $"
 
47
#endif
 
48
#endif
 
49
 
 
50
/* (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 HEWLETT-PACKARD COMPANY */
 
51
 
 
52
#include "TraversalI.h"
 
53
#include "TravActI.h"
 
54
#include <Xm/GadgetP.h>
 
55
#include <Xm/PrimitiveP.h>
 
56
#include <Xm/ManagerP.h>
 
57
#include <Xm/VendorSEP.h>
 
58
#include <Xm/MenuShellP.h>
 
59
#include "RepTypeI.h"
 
60
#include <Xm/VirtKeysP.h>
 
61
#include <Xm/DisplayP.h>
 
62
#include <Xm/ScrolledWP.h>
 
63
 
 
64
#include "ToolTipI.h"
 
65
 
 
66
 
 
67
#define EVENTS_EQ(ev1, ev2) \
 
68
  ((((ev1)->type == (ev2)->type) &&\
 
69
    ((ev1)->serial == (ev2)->serial) &&\
 
70
    ((ev1)->time == (ev2)->time) &&\
 
71
    ((ev1)->x == (ev2)->x) &&\
 
72
    ((ev1)->y == (ev2)->y)) ? TRUE : FALSE)
 
73
 
 
74
 
 
75
/********    Static Function Declarations    ********/
 
76
 
 
77
static Boolean UpdatePointerData(Widget w, XEvent *event);
 
78
static void FlushPointerData(Widget w, XEvent *event);
 
79
static void DispatchGadgetInput(XmGadget g, XEvent *event, Mask mask);
 
80
 
 
81
/********    End Static Function Declarations    ********/
 
82
 
 
83
 
 
84
/*
 
85
 * The following functions are used by the widgets to query or modify one
 
86
 * of the display dependent global variabled used by traversal mechanism.
 
87
 */
 
88
 
 
89
unsigned short
 
90
_XmGetFocusFlag(Widget w, 
 
91
                unsigned int mask)
 
92
{
 
93
  XmDisplay dd = (XmDisplay)XmGetXmDisplay(XtDisplay(w));
 
94
 
 
95
  return ((unsigned short)((XmDisplayInfo *)
 
96
           (dd->display.displayInfo))->resetFocusFlag & mask);
 
97
}
 
98
 
 
99
 
 
100
void 
 
101
_XmSetFocusFlag(Widget w,
 
102
                unsigned int mask,
 
103
#if NeedWidePrototypes
 
104
                int value)
 
105
#else
 
106
                Boolean value)
 
107
#endif /* NeedWidePrototypes */
 
108
{
 
109
  XmDisplay dd = (XmDisplay)XmGetXmDisplay(XtDisplay(w));
 
110
 
 
111
  if (value)
 
112
     ((XmDisplayInfo *)
 
113
         (dd->display.displayInfo))->resetFocusFlag |= mask;
 
114
  else
 
115
     ((XmDisplayInfo *)
 
116
         (dd->display.displayInfo))->resetFocusFlag &= ~mask;
 
117
}
 
118
     
 
119
 
 
120
static Boolean 
 
121
UpdatePointerData(Widget w,
 
122
                  XEvent *event)
 
123
{
 
124
  XmFocusData focusData;
 
125
  
 
126
  if ((focusData = _XmGetFocusData(w)) != NULL)
 
127
    {
 
128
      XCrossingEvent *lastEvent = &(focusData->lastCrossingEvent);
 
129
      
 
130
      focusData->needToFlush = TRUE;
 
131
      
 
132
      if (!EVENTS_EQ(lastEvent, (XCrossingEvent *)event))
 
133
        {
 
134
          focusData->old_pointer_item = focusData->pointer_item;
 
135
          focusData->pointer_item = w;
 
136
          focusData->lastCrossingEvent = *(XCrossingEvent *) event;
 
137
          return TRUE;
 
138
        }
 
139
    }
 
140
 
 
141
  return FALSE;
 
142
}
 
143
 
 
144
static void 
 
145
FlushPointerData(Widget w,
 
146
                 XEvent *event)
 
147
{
 
148
  XmFocusData focusData = _XmGetFocusData(w);
 
149
  
 
150
  if (focusData && focusData->needToFlush)
 
151
    {
 
152
      XCrossingEvent    lastEvent;
 
153
      
 
154
      lastEvent = focusData->lastCrossingEvent;
 
155
      
 
156
      focusData->needToFlush = FALSE;
 
157
      /* 
 
158
       * We are munging data into the event to fake out the focus
 
159
       * code when Mwm is trying to catch up with the pointer.
 
160
       * This event that we are munging might already have been
 
161
       * munged by XmDispatchGadgetInput from a motion event to a
 
162
       * crossing event !!!!!
 
163
       */
 
164
      
 
165
      lastEvent.serial = event->xany.serial;
 
166
      if ( (LeaveNotify == event->type) || (EnterNotify == event->type) )
 
167
              lastEvent.time = event->xcrossing.time;
 
168
      else
 
169
                /* Approximation; the code appears to need even Focus events,
 
170
                ** so make up a time and try to continue, rather than limit
 
171
                ** lastEvent to XCrossingEvents. (It is a flaw in the X
 
172
                ** Protocol that Focus events do not have timestamps.)
 
173
                */
 
174
                lastEvent.time = XtLastTimestampProcessed(XtDisplay(w));
 
175
      lastEvent.focus = True;
 
176
      XtDispatchEvent((XEvent *) &lastEvent);
 
177
    }
 
178
}
 
179
 
 
180
/************************************************************************
 
181
 *
 
182
 *  _XmTrackShellFocus
 
183
 *
 
184
 *  This handler is added by ShellExt initialize to the front of the
 
185
 * queue
 
186
 *     
 
187
 ************************************************************************/
 
188
 
 
189
void 
 
190
_XmTrackShellFocus(Widget widget,
 
191
                   XtPointer client_data,
 
192
                   XEvent *event,
 
193
                   Boolean *dontSwallow)
 
194
{
 
195
  XmVendorShellExtObject ve = (XmVendorShellExtObject) client_data;
 
196
  XmFocusData            focusData;
 
197
  XmGeneology            oldFocalPoint;
 
198
  XmGeneology            newFocalPoint;
 
199
  
 
200
  if (widget->core.being_destroyed)
 
201
    {
 
202
      *dontSwallow = False;
 
203
      return;
 
204
    }
 
205
 
 
206
  if ((focusData = ve->vendor.focus_data) == NULL)
 
207
    return;
 
208
 
 
209
  oldFocalPoint = newFocalPoint = focusData->focalPoint;
 
210
  
 
211
  switch(event->type)
 
212
    {
 
213
    case EnterNotify:
 
214
    case LeaveNotify:
 
215
      /*
 
216
       * If operating in a focus driven model, then enter and
 
217
       * leave events do not affect the keyboard focus.
 
218
       */
 
219
      if ((event->xcrossing.detail != NotifyInferior) &&
 
220
          (event->xcrossing.focus))
 
221
        {             
 
222
          switch (oldFocalPoint)
 
223
            {
 
224
            case XmUnrelated:
 
225
              if (event->type == EnterNotify)
 
226
                newFocalPoint = XmMyAncestor;
 
227
              break;
 
228
            case XmMyAncestor:
 
229
              if (event->type == LeaveNotify)
 
230
                newFocalPoint = XmUnrelated;
 
231
              break;
 
232
            case XmMyDescendant:
 
233
            case XmMyCousin:
 
234
            case XmMySelf:
 
235
            default:
 
236
              break;
 
237
            }   
 
238
        }
 
239
      break;
 
240
 
 
241
    case FocusIn:
 
242
      switch (event->xfocus.detail)
 
243
        {
 
244
        case NotifyNonlinear:
 
245
        case NotifyAncestor:
 
246
        case NotifyInferior:
 
247
          newFocalPoint = XmMySelf;
 
248
          break;
 
249
        case NotifyNonlinearVirtual:
 
250
        case NotifyVirtual:
 
251
          newFocalPoint = XmMyDescendant;
 
252
          break;
 
253
        case NotifyPointer:
 
254
          newFocalPoint = XmMyAncestor;
 
255
          break;
 
256
        }
 
257
      break;
 
258
 
 
259
    case FocusOut:
 
260
      switch (event->xfocus.detail)
 
261
        {
 
262
        case NotifyPointer:
 
263
        case NotifyNonlinear:
 
264
        case NotifyAncestor:
 
265
        case NotifyNonlinearVirtual:
 
266
        case NotifyVirtual:
 
267
          newFocalPoint = XmUnrelated;
 
268
          break;
 
269
        case NotifyInferior:
 
270
          return;
 
271
        }
 
272
      break;
 
273
    }
 
274
 
 
275
  if (newFocalPoint == XmUnrelated)
 
276
    {
 
277
      focusData->old_focus_item = NULL;
 
278
      
 
279
      if (focusData->trav_graph.num_alloc)
 
280
        {
 
281
          /* Free traversal graph, since focus is leaving hierarchy. */
 
282
          _XmFreeTravGraph(&(focusData->trav_graph));
 
283
        }
 
284
    }
 
285
 
 
286
  if ((focusData->focus_policy == XmEXPLICIT) &&
 
287
      (oldFocalPoint != newFocalPoint) &&
 
288
      focusData->focus_item)
 
289
    {
 
290
      if (oldFocalPoint == XmUnrelated)
 
291
        _XmCallFocusMoved(NULL, focusData->focus_item, event);
 
292
      else if (newFocalPoint == XmUnrelated)
 
293
        _XmCallFocusMoved(focusData->focus_item, NULL, event);
 
294
    }
 
295
 
 
296
  focusData->focalPoint = newFocalPoint;
 
297
}
 
298
 
 
299
/************************************************************************
 
300
 *
 
301
 *  Enter & Leave
 
302
 *      Enter and leave event processing routines.
 
303
 *
 
304
 ************************************************************************/
 
305
 
 
306
/*ARGSUSED*/
 
307
void 
 
308
_XmPrimitiveEnter(Widget wid,
 
309
                  XEvent *event,
 
310
                  String *params,       /* unused */
 
311
                  Cardinal *num_params) /* unused */
 
312
{   
 
313
  _XmToolTipEnter(wid, event, params, num_params);
 
314
  if (_XmGetFocusPolicy(wid) == XmPOINTER)
 
315
    {   
 
316
      if (event->xcrossing.focus)
 
317
        {   
 
318
          _XmCallFocusMoved(XtParent(wid), wid, event);
 
319
          _XmWidgetFocusChange(wid, XmENTER);
 
320
        }
 
321
 
 
322
      UpdatePointerData(wid, event);
 
323
    }
 
324
}
 
325
 
 
326
/*ARGSUSED*/
 
327
void 
 
328
_XmPrimitiveLeave(Widget wid,
 
329
                  XEvent *event,
 
330
                  String *params,       /* unused */
 
331
                  Cardinal *num_params) /* unused */
 
332
{   
 
333
  _XmToolTipLeave(wid, event, params, num_params);
 
334
  if (_XmGetFocusPolicy(wid) == XmPOINTER)
 
335
    {   
 
336
      if (event->xcrossing.focus)
 
337
        {   
 
338
          _XmCallFocusMoved(wid, XtParent(wid), event);
 
339
          _XmWidgetFocusChange(wid, XmLEAVE);
 
340
        }
 
341
    }   
 
342
}
 
343
 
 
344
/************************************************************************
 
345
 *
 
346
 *  Focus In & Out
 
347
 *
 
348
 ************************************************************************/
 
349
 
 
350
/*ARGSUSED*/
 
351
void 
 
352
_XmPrimitiveFocusInInternal(Widget wid,
 
353
                            XEvent *event,
 
354
                            String *params,             /* unused */
 
355
                            Cardinal *num_params)       /* unused */
 
356
{   
 
357
  if (!(event->xfocus.send_event) ||
 
358
      _XmGetFocusFlag(wid, XmFOCUS_IGNORE))
 
359
    return;
 
360
 
 
361
  if (_XmGetFocusPolicy(wid) == XmPOINTER)
 
362
    {   
 
363
      /* Maybe Mwm trying to catch up with us. */
 
364
      if (XtIsShell(XtParent(wid)))
 
365
        FlushPointerData(wid, event);
 
366
    }
 
367
  else 
 
368
    {   
 
369
      /* We should only be recieving the focus from a traversal request. */
 
370
      if (!_XmGetActiveTabGroup(wid))
 
371
        _XmMgrTraversal(_XmFindTopMostShell(wid), XmTRAVERSE_NEXT_TAB_GROUP);
 
372
      else
 
373
        _XmWidgetFocusChange(wid, XmFOCUS_IN);
 
374
    }
 
375
}
 
376
 
 
377
/*ARGSUSED*/
 
378
void 
 
379
_XmPrimitiveFocusOut(Widget wid,
 
380
                     XEvent *event,
 
381
                     String *params,            /* unused */
 
382
                     Cardinal *num_params)      /* unused */
 
383
{   
 
384
  if (event->xfocus.send_event &&
 
385
      !(wid->core.being_destroyed) &&
 
386
      (_XmGetFocusPolicy(wid) == XmEXPLICIT))
 
387
    {   
 
388
      _XmWidgetFocusChange(wid, XmFOCUS_OUT);
 
389
    }
 
390
}
 
391
 
 
392
void 
 
393
_XmPrimitiveFocusIn(Widget pw,
 
394
                    XEvent *event,
 
395
                    String *params,
 
396
                    Cardinal *num_params)
 
397
{
 
398
  _XmPrimitiveFocusInInternal(pw, event, params, num_params);
 
399
}
 
400
 
 
401
/************************************************************************
 
402
 *
 
403
 *  _XmEnterGadget
 
404
 *     This function processes enter window conditions occuring in a gadget
 
405
 *
 
406
 ************************************************************************/
 
407
 
 
408
/*ARGSUSED*/
 
409
void 
 
410
_XmEnterGadget(Widget wid,
 
411
               XEvent *event,
 
412
               String *params,          /* unused */
 
413
               Cardinal *num_params)    /* unused */
 
414
{   
 
415
  if (XmIsGadget(wid) && ((XmGadget)wid)->gadget.traversal_on)
 
416
  {
 
417
      _XmToolTipEnter(wid, event, params, num_params);
 
418
  }
 
419
  if (_XmGetFocusPolicy(wid) == XmPOINTER)
 
420
    {   
 
421
      XmFocusData focusData = _XmGetFocusData(wid);
 
422
      
 
423
      /* We may be getting called as a result of Mwm catching up
 
424
       * with the pointer and setting input focus to the shell
 
425
       * which then gets forwarded to us.
 
426
       */
 
427
      if (focusData && (focusData->focalPoint != XmUnrelated))
 
428
        {   
 
429
          _XmCallFocusMoved(XtParent(wid), wid, event);
 
430
          _XmWidgetFocusChange(wid, XmENTER);
 
431
        }
 
432
    }
 
433
}
 
434
 
 
435
/************************************************************************
 
436
 *
 
437
 *  DispatchGadgetInput
 
438
 *      This routine is used instead of _XmDispatchGadgetInput due to
 
439
 *      the fact that it needs to dispatch to unmanaged gadgets
 
440
 *
 
441
 ************************************************************************/
 
442
static void 
 
443
DispatchGadgetInput(XmGadget g,
 
444
                    XEvent *event,
 
445
                    Mask mask)
 
446
{
 
447
   if ((g->gadget.event_mask & mask) && XtIsSensitive((Widget)g))
 
448
     {
 
449
       (*(((XmGadgetClass) (g->object.widget_class))->
 
450
          gadget_class.input_dispatch)) ((Widget) g, event, mask);
 
451
     }
 
452
}
 
453
 
 
454
/************************************************************************
 
455
 *
 
456
 *  _XmLeaveGadget
 
457
 *     This function processes leave window conditions occuring in a gadget
 
458
 *
 
459
 ************************************************************************/
 
460
 
 
461
/*ARGSUSED*/
 
462
void 
 
463
_XmLeaveGadget(Widget wid,
 
464
               XEvent *event,
 
465
               String *params,          /* unused */
 
466
               Cardinal *num_params)    /* unused */
 
467
{   
 
468
  if (XmIsGadget(wid) && ((XmGadget)wid)->gadget.traversal_on)
 
469
  {
 
470
      _XmToolTipLeave(wid, event, params, num_params);
 
471
  }
 
472
 
 
473
  if (_XmGetFocusPolicy(wid) == XmPOINTER)
 
474
    {   
 
475
      _XmCallFocusMoved(wid, XtParent(wid), event);
 
476
      _XmWidgetFocusChange(wid, XmLEAVE);
 
477
    }
 
478
}
 
479
 
 
480
/************************************************************************
 
481
 *
 
482
 *  _XmFocusInGadget
 
483
 *     This function processes focusIn conditions occuring in a gadget
 
484
 *
 
485
 
 
486
 ************************************************************************/
 
487
/*ARGSUSED*/
 
488
void 
 
489
_XmFocusInGadget(Widget wid,
 
490
                 XEvent *event,         /* unused */
 
491
                 String *params,        /* unused */
 
492
                 Cardinal *num_params)  /* unused */
 
493
{
 
494
  if (_XmGetFocusPolicy(wid) == XmEXPLICIT)
 
495
    _XmWidgetFocusChange(wid, XmFOCUS_IN);
 
496
}
 
497
 
 
498
/************************************************************************
 
499
 *
 
500
 *  _XmFocusOutGadget
 
501
 *     This function processes FocusOut conditions occuring in a gadget
 
502
 *
 
503
 ************************************************************************/
 
504
 
 
505
/*ARGSUSED*/
 
506
void 
 
507
_XmFocusOutGadget(Widget wid,
 
508
                  XEvent *event,        /* unused */
 
509
                  String *params,       /* unused */
 
510
                  Cardinal *num_params) /* unused */
 
511
{
 
512
  if (_XmGetFocusPolicy(wid) == XmEXPLICIT)
 
513
    _XmWidgetFocusChange(wid, XmFOCUS_OUT);
 
514
}
 
515
 
 
516
/************************************************************************
 
517
 *
 
518
 *  Enter, FocusIn and Leave Window procs
 
519
 *
 
520
 *     These two procedures handle traversal activation and deactivation
 
521
 *     for manager widgets. They are invoked directly throught the
 
522
 *     the action table of a widget.
 
523
 *
 
524
 ************************************************************************/
 
525
 
 
526
/************************************************************************
 
527
 *
 
528
 *  _XmManagerEnter
 
529
 *     This function handles both focusIn and Enter. Don't ask me why
 
530
 *     :-(
 
531
 *
 
532
 ************************************************************************/
 
533
 
 
534
/*ARGSUSED*/
 
535
void 
 
536
_XmManagerEnter(Widget wid,
 
537
                XEvent *event_in,
 
538
                String *params,         /* unused */
 
539
                Cardinal *num_params)   /* unused */
 
540
{
 
541
  XmManagerWidget mw = (XmManagerWidget) wid;
 
542
  XCrossingEvent *event = (XCrossingEvent *) event_in;
 
543
  
 
544
  if (_XmGetFocusPolicy((Widget) mw) == XmPOINTER)
 
545
    {
 
546
      if (UpdatePointerData((Widget) mw, event_in) && event->focus)
 
547
        {
 
548
          Widget old;
 
549
          
 
550
          if (event->detail == NotifyInferior)
 
551
            old = XtWindowToWidget(event->display, event->subwindow);
 
552
          else
 
553
            old = XtParent(mw);
 
554
 
 
555
          _XmCallFocusMoved(old, (Widget) mw, (XEvent *) event);
 
556
          _XmWidgetFocusChange((Widget) mw, XmENTER);
 
557
        }
 
558
    }
 
559
}
 
560
 
 
561
/*ARGSUSED*/
 
562
void 
 
563
_XmManagerLeave(Widget wid,
 
564
                XEvent *event,
 
565
                String *params,         /* unused */
 
566
                Cardinal *num_params)   /* unused */
 
567
{
 
568
  /*
 
569
   * This code is inefficient since it is called twice for each
 
570
   * internal move in the hierarchy |||
 
571
   */
 
572
  if (event->type == LeaveNotify)
 
573
    {
 
574
      if (_XmGetFocusPolicy(wid) == XmPOINTER)
 
575
        {
 
576
          Widget new_wid;
 
577
          
 
578
          if (event->xcrossing.detail == NotifyInferior)
 
579
            new_wid = XtWindowToWidget(event->xcrossing.display, 
 
580
                                       event->xcrossing.subwindow);
 
581
          else 
 
582
            new_wid = XtParent(wid);
 
583
 
 
584
          if (UpdatePointerData(wid, event) && event->xcrossing.focus)
 
585
            {
 
586
              _XmCallFocusMoved(wid, new_wid, event);
 
587
              _XmWidgetFocusChange(wid, XmLEAVE);
 
588
            }
 
589
        }
 
590
    }
 
591
}
 
592
 
 
593
/*ARGSUSED*/
 
594
void 
 
595
_XmManagerFocusInInternal(Widget wid,
 
596
                          XEvent *event,
 
597
                          String *params,       /* unused */
 
598
                          Cardinal *num_params) /* unused */
 
599
{   
 
600
  Widget child;
 
601
 
 
602
  /*
 
603
   * Managers ignore all focus events which have been generated by the
 
604
   * window system; only those sent to us by a window manager or the
 
605
   * Xtk focus code is accepted.
 
606
   * Bail out if the focus policy is not set to explicit
 
607
   */
 
608
  if (!(event->xfocus.send_event) ||
 
609
      _XmGetFocusFlag(wid, XmFOCUS_RESET | XmFOCUS_IGNORE))
 
610
    return;
 
611
 
 
612
  if (_XmGetFocusPolicy(wid) == XmPOINTER)
 
613
    {   
 
614
      FlushPointerData(wid, event);
 
615
    } 
 
616
  else if (!_XmGetActiveTabGroup(wid))
 
617
    {   
 
618
      /* If the heirarchy doesn't have an active tab group give it one. */
 
619
      _XmMgrTraversal(_XmFindTopMostShell(wid), XmTRAVERSE_NEXT_TAB_GROUP);
 
620
    } 
 
621
  else if ((child = ((XmManagerWidget) wid)->manager.active_child) && 
 
622
           XmIsGadget(child))
 
623
    {   
 
624
      /* If focus went to a gadget, then force it to highlight */
 
625
      DispatchGadgetInput((XmGadget) child, event, XmFOCUS_IN_EVENT);
 
626
    }
 
627
  else
 
628
    {
 
629
      _XmWidgetFocusChange(wid, XmFOCUS_IN);
 
630
    }
 
631
}
 
632
 
 
633
/*
 
634
 * Non-menu widgets use this entry point, so that they will ignore focus
 
635
 * events during menu activities.
 
636
 */
 
637
void 
 
638
_XmManagerFocusIn(Widget mw,
 
639
                  XEvent *event,
 
640
                  String *params,
 
641
                  Cardinal *num_params)
 
642
{
 
643
  _XmManagerFocusInInternal(mw, event, params, num_params);
 
644
}
 
645
 
 
646
/*
 
647
 * If the manager widget received a FocusOut while it is processing its
 
648
 * FocusIn event, then it knows that the focus has been successfully moved
 
649
 * to one of its children.  However, if no FocusOut is received, then the
 
650
 * manager widget must manually force the child to take the focus.
 
651
 */
 
652
 
 
653
/*ARGSUSED*/
 
654
void 
 
655
_XmManagerFocusOut(Widget wid,
 
656
                   XEvent *event,
 
657
                   String *params,              /* unused */
 
658
                   Cardinal *num_params)        /* unused */
 
659
{   
 
660
  Widget child;
 
661
  
 
662
  if (!event->xfocus.send_event)
 
663
    return;
 
664
 
 
665
  if (_XmGetFocusPolicy(wid) == XmEXPLICIT)
 
666
    {   
 
667
      /* If focus is in a gadget, then force it to unhighlight. */
 
668
      if ((child = ((XmManagerWidget) wid)->manager.active_child) &&
 
669
          XmIsGadget(child))
 
670
        {   
 
671
          DispatchGadgetInput((XmGadget) child, event, XmFOCUS_OUT_EVENT);
 
672
        }
 
673
      else
 
674
        {
 
675
          _XmWidgetFocusChange(wid, XmFOCUS_OUT);
 
676
        }
 
677
    }
 
678
}
 
679
 
 
680
/*ARGSUSED*/
 
681
void 
 
682
_XmManagerUnmap(Widget mw,
 
683
                XEvent *event,          /* unused */
 
684
                String *params,         /* unused */
 
685
                Cardinal *num_params)   /* unused */
 
686
{
 
687
  /* This functionality is bogus, since a good implementation
 
688
   * requires more code (hooks for mapping of widgets) than it's
 
689
   * worth.  To move focus away from a widget when it is unmapped
 
690
   * implies the ability to recover from the case when the last
 
691
   * traversable widget in a hierarchy is unmapped and then re-mapped.
 
692
   * Since we don't have the hooks in place for the mapping of these
 
693
   * widgets, and since the old code only worked some of the time,
 
694
   * and since it is arguable that the focus should never be
 
695
   * changed in response to a widget being unmapped, we should choose
 
696
   * to do NO traversal in response to the unmapping of a widget.
 
697
   * However, historical precedent again defeats good design.
 
698
   */
 
699
  _XmValidateFocus(mw);
 
700
}
 
701
 
 
702
/*ARGSUSED*/
 
703
void 
 
704
_XmPrimitiveUnmap(Widget pw,
 
705
                  XEvent *event,        /* unused */
 
706
                  String *params,       /* unused */
 
707
                  Cardinal *num_params) /* unused */
 
708
{
 
709
  _XmValidateFocus(pw);
 
710
}