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

« back to all changes in this revision

Viewing changes to lib/Xm/Scale.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 REV_INFO
 
40
#ifndef lint
 
41
static char rcsid[] = "$TOG: Scale.c /main/31 1999/10/13 16:18:07 mgreess $"
 
42
#endif
 
43
#endif
 
44
/* (c) Copyright 1989, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
 
45
/* (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 HEWLETT-PACKARD COMPANY */
 
46
 
 
47
#ifdef HAVE_CONFIG_H
 
48
#include <config.h>
 
49
#endif
 
50
 
 
51
 
 
52
#include <stdio.h>
 
53
#include <limits.h>
 
54
#ifndef CSRG_BASED
 
55
/*
 
56
 * Modification by Integrated Computer Solutions, Inc.  May 2000
 
57
 *
 
58
 * Original:
 
59
 *
 
60
 * # ifdef linux
 
61
 * #  define RADIXCHAR MON_DECIMAL_POINT
 
62
 * # endif
 
63
 * # include <langinfo.h>
 
64
 *
 
65
 * glibc >= 2.0 defines RADIXCHAR in langinfo.h, simply make sure 
 
66
 * that it is not redefined here.
 
67
 */
 
68
# include <langinfo.h>
 
69
# if defined(linux) && !defined(RADIXCHAR)
 
70
#  define RADIXCHAR DECIMAL_POINT
 
71
# endif
 
72
# ifdef X_LOCALE
 
73
#  ifdef linux
 
74
   /* avoid conflicting with <X11/Xlocale.h> defines */
 
75
#   undef LC_ALL
 
76
#   undef LC_COLLATE
 
77
#   undef LC_CTYPE
 
78
#   undef LC_MONETARY
 
79
#   undef LC_NUMERIC
 
80
#   undef LC_TIME
 
81
#  endif
 
82
# endif
 
83
#else
 
84
# define nl_langinfo(radixchar) "."
 
85
#endif
 
86
#ifdef __cplusplus
 
87
extern "C" { /* some 'locale.h' do not have prototypes (sun) */
 
88
#endif
 
89
#include <X11/Xlocale.h>
 
90
#ifdef __cplusplus
 
91
} /* Close scope of 'extern "C"' declaration */
 
92
#endif /* __cplusplus */
 
93
 
 
94
#include <Xm/AtomMgr.h>
 
95
#include <Xm/DisplayP.h>
 
96
#include <Xm/DragC.h>
 
97
#include <Xm/DragIconP.h>
 
98
#include <Xm/LabelG.h>
 
99
#include <Xm/ScaleP.h>
 
100
#include <Xm/ScrollBarP.h>      /* for slider geometrical data */
 
101
#include <Xm/TraitP.h>
 
102
#include <Xm/TransferT.h>
 
103
#include <Xm/XmosP.h>
 
104
#include <Xm/VaSimpleP.h>
 
105
#include "GeoUtilsI.h"
 
106
#include "GMUtilsI.h"
 
107
#include "MessagesI.h"
 
108
#include "RepTypeI.h"
 
109
#include "TransferI.h"
 
110
#include "TraversalI.h"
 
111
#include "XmI.h"
 
112
 
 
113
#define state_flags last_value
 
114
  
 
115
#define MESSAGE1        _XmMMsgScale_0000
 
116
#define MESSAGE2        _XmMMsgScale_0001
 
117
#define MESSAGE3        _XmMMsgScale_0002
 
118
#define MESSAGE5        _XmMMsgScaleScrBar_0004
 
119
#define MESSAGE7        _XmMMsgScale_0006
 
120
#define MESSAGE8        _XmMMsgScale_0007
 
121
#define MESSAGE9        _XmMMsgScale_0008
 
122
 
 
123
 
 
124
static Region null_region = NULL;
 
125
 
 
126
 
 
127
/* Convenience macros and definitions */
 
128
 
 
129
#define TotalWidth(w)   (w->core.width + (w->core.border_width * 2))
 
130
#define TotalHeight(w)  (w->core.height + (w->core.border_width * 2))
 
131
 
 
132
#define SCROLLBAR_MAX   1000000000
 
133
#define SCALE_VALUE_MARGIN 3
 
134
#define SCALE_DEFAULT_MAJOR_SIZE \
 
135
        (100 + (2 * sw->scale.highlight_thickness))
 
136
#define SCALE_DEFAULT_MINOR_SIZE \
 
137
        (15 + (2 * sw->scale.highlight_thickness))
 
138
 
 
139
#define SLIDER_SIZE(sca)        ((sca->scale.sliding_mode == XmTHERMOMETER)?\
 
140
                                 0:sca->scale.slider_size)
 
141
 
 
142
 
 
143
/* this one is context dependent, args and n are used */
 
144
#define SET(name, val) {XtSetArg (args[n], (name), (val)); n++;}
 
145
 
 
146
 
 
147
#define LeadXTic(sb, sca) (sb->scrollBar.slider_area_x \
 
148
                     + (Dimension) (((float) SLIDER_SIZE(sca) / 2.0) + 0.5))
 
149
#define LeadYTic(sb, sca) (sb->scrollBar.slider_area_y \
 
150
                     + (Dimension) (((float) SLIDER_SIZE(sca) / 2.0) + 0.5))
 
151
#define TrailXTic(sb, sca) (sb->core.width - (sb->scrollBar.slider_area_x \
 
152
                     + sb->scrollBar.slider_area_width\
 
153
                      - (Dimension) (((float) SLIDER_SIZE(sca) / 2.0) + 0.5)))
 
154
#define TrailYTic(sb, sca) (sb->core.height - (sb->scrollBar.slider_area_y \
 
155
                     + sb->scrollBar.slider_area_height\
 
156
                      - (Dimension) (((float) SLIDER_SIZE(sca) / 2.0) + 0.5)))
 
157
                
 
158
 
 
159
/********    Static Function Declarations    ********/
 
160
 
 
161
static void ScaleGetTitleString( 
 
162
                        Widget wid,
 
163
                        int resource,
 
164
                        XtArgVal *value) ;
 
165
static void ClassInitialize( void ) ;
 
166
static void ClassPartInitialize( 
 
167
                        WidgetClass wc) ;
 
168
static void ProcessingDirectionDefault( 
 
169
                        XmScaleWidget widget,
 
170
                        int offset,
 
171
                        XrmValue *value) ;
 
172
static void SliderVisualDefault( 
 
173
                        XmScaleWidget widget,
 
174
                        int offset,
 
175
                        XrmValue *value) ;
 
176
static void SliderMarkDefault( 
 
177
                        XmScaleWidget widget,
 
178
                        int offset,
 
179
                        XrmValue *value) ;
 
180
static void EditableDefault( 
 
181
                        XmScaleWidget widget,
 
182
                        int offset,
 
183
                        XrmValue *value) ;
 
184
static void ValidateInitialState( 
 
185
                        XmScaleWidget req,
 
186
                        XmScaleWidget new_w) ;
 
187
static Widget CreateScaleTitle( 
 
188
                        XmScaleWidget new_w) ;
 
189
static Widget CreateScaleScrollBar( 
 
190
                        XmScaleWidget new_w) ;
 
191
static void Initialize( 
 
192
                        Widget rw,
 
193
                        Widget nw,
 
194
                        ArgList args,
 
195
                        Cardinal *num_args) ;
 
196
static void GetForegroundGC( 
 
197
                        XmScaleWidget sw) ;
 
198
static void Redisplay( 
 
199
                        Widget wid,
 
200
                        XEvent *event,
 
201
                        Region region) ;
 
202
static void CalcScrollBarData( 
 
203
                        XmScaleWidget sw,
 
204
                        int *value,
 
205
                        int *slider_size,
 
206
                        int *increment,
 
207
                        int *page) ;
 
208
static void Resize( 
 
209
                        Widget wid) ;
 
210
static void ValidateInputs( 
 
211
                        XmScaleWidget cur,
 
212
                        XmScaleWidget new_w) ;
 
213
static void HandleTitle( 
 
214
                        XmScaleWidget cur,
 
215
                        XmScaleWidget req,
 
216
                        XmScaleWidget new_w) ;
 
217
static void HandleScrollBar( 
 
218
                        XmScaleWidget cur,
 
219
                        XmScaleWidget req,
 
220
                        XmScaleWidget new_w) ;
 
221
static Boolean SetValues( 
 
222
                        Widget cw,
 
223
                        Widget rw,
 
224
                        Widget nw,
 
225
                        ArgList args_in,
 
226
                        Cardinal *num_args_in) ;
 
227
static void Realize( 
 
228
                        register Widget w,
 
229
                        XtValueMask *p_valueMask,
 
230
                        XSetWindowAttributes *attributes) ;
 
231
static void Destroy( 
 
232
                        Widget wid) ;
 
233
static XtGeometryResult GeometryManager( 
 
234
                        Widget w,
 
235
                        XtWidgetGeometry *request,
 
236
                        XtWidgetGeometry *reply) ;
 
237
static Dimension MaxLabelWidth( 
 
238
                        XmScaleWidget sw) ;
 
239
static Dimension MaxLabelHeight( 
 
240
                        XmScaleWidget sw) ;
 
241
static Dimension ValueTroughWidth( 
 
242
                        XmScaleWidget sw) ;
 
243
static Dimension ValueTroughHeight( 
 
244
                        XmScaleWidget sw) ;
 
245
static Dimension ValueTroughAscent( 
 
246
                        XmScaleWidget sw) ;
 
247
static Dimension ValueTroughDescent( 
 
248
                        XmScaleWidget sw) ;
 
249
static Dimension TitleWidth( 
 
250
                        XmScaleWidget sw) ;
 
251
static Dimension TitleHeight( 
 
252
                        XmScaleWidget sw) ;
 
253
static Cardinal NumManaged(
 
254
                           XmScaleWidget sw,
 
255
                           Widget * first_man,
 
256
                           Widget * last_man);
 
257
static Dimension MajorLeadPad( 
 
258
                        XmScaleWidget sw) ;
 
259
static Dimension MajorTrailPad( 
 
260
                        XmScaleWidget sw) ;
 
261
static Dimension ScrollWidth( 
 
262
                        XmScaleWidget sw) ;
 
263
static Dimension ScrollHeight( 
 
264
                        XmScaleWidget sw) ;
 
265
static void GetScaleSize( 
 
266
                        XmScaleWidget sw,
 
267
                        Dimension *w,
 
268
                        Dimension *h) ;
 
269
static void LayoutHorizontalLabels( 
 
270
                        XmScaleWidget sw,
 
271
                        XRectangle *scrollBox,
 
272
                        XRectangle *labelBox,
 
273
                        Widget instigator) ;
 
274
static void LayoutHorizontalScale( 
 
275
                        XmScaleWidget sw,
 
276
                        XtWidgetGeometry * desired,
 
277
                        Widget instigator) ;
 
278
static void LayoutVerticalLabels( 
 
279
                        XmScaleWidget sw,
 
280
                        XRectangle *scrollBox,
 
281
                        XRectangle *labelBox,
 
282
                        Widget instigator) ;
 
283
static void LayoutVerticalScale( 
 
284
                        XmScaleWidget sw,
 
285
                        XtWidgetGeometry * desired,
 
286
                        Widget instigator) ;
 
287
static void ChangeManaged( 
 
288
                        Widget wid) ;
 
289
static void GetValueString(
 
290
                        XmScaleWidget sw,
 
291
                        int value,
 
292
                        String buffer);
 
293
static void ShowValue(
 
294
                        XmScaleWidget sw) ;
 
295
static void SetScrollBarData( 
 
296
                        XmScaleWidget sw) ;
 
297
static void ValueChanged( 
 
298
                        Widget wid,
 
299
                        XtPointer closure,
 
300
                        XtPointer call_data) ;
 
301
static XtGeometryResult QueryGeometry( 
 
302
                        Widget wid,
 
303
                        XtWidgetGeometry *intended,
 
304
                        XtWidgetGeometry *desired) ;
 
305
static XmNavigability WidgetNavigable( 
 
306
                        Widget wid) ;
 
307
static void StartDrag (Widget  w, 
 
308
                        XtPointer data, 
 
309
                        XEvent  *event, 
 
310
                        Boolean *cont) ;
 
311
static void DragConvertCallback (Widget w,
 
312
                                 XtPointer client_data,
 
313
                                 XmConvertCallbackStruct *cs);
 
314
static void CheckSetRenderTable(Widget wid,
 
315
                                int offset,
 
316
                                XrmValue *value); 
 
317
 
 
318
/********    End Static Function Declarations    ********/
 
319
 
 
320
 
 
321
 
 
322
/*  Resource definitions for Scale class */
 
323
 
 
324
static XtResource resources[] =
 
325
{
 
326
   {
 
327
       XmNshadowThickness, XmCShadowThickness, XmRHorizontalDimension,
 
328
       sizeof (Dimension), XtOffsetOf(XmManagerRec, manager.shadow_thickness),
 
329
       XmRCallProc, (XtPointer) _XmSetThickness
 
330
   },
 
331
 
 
332
   {
 
333
       XmNvalue, XmCValue, XmRInt, 
 
334
       sizeof(int), XtOffsetOf(XmScaleRec,scale.value),
 
335
       XmRImmediate, (XtPointer) XmINVALID_DIMENSION
 
336
   },
 
337
 
 
338
   {
 
339
       XmNmaximum, XmCMaximum, XmRInt, 
 
340
       sizeof(int), XtOffsetOf(XmScaleRec,scale.maximum), 
 
341
       XmRImmediate, (XtPointer)100
 
342
   },
 
343
 
 
344
   {
 
345
       XmNminimum, XmCMinimum, XmRInt,
 
346
       sizeof(int), XtOffsetOf(XmScaleRec,scale.minimum), 
 
347
       XmRImmediate, (XtPointer)0
 
348
   },
 
349
 
 
350
   {
 
351
       XmNorientation, XmCOrientation, XmROrientation, 
 
352
       sizeof(unsigned char), XtOffsetOf(XmScaleRec,scale.orientation), 
 
353
       XmRImmediate, (XtPointer) XmVERTICAL
 
354
   },
 
355
 
 
356
   {
 
357
       XmNprocessingDirection, XmCProcessingDirection, XmRProcessingDirection,
 
358
       sizeof(unsigned char), 
 
359
       XtOffsetOf(XmScaleRec,scale.processing_direction), 
 
360
       XmRCallProc, (XtPointer) ProcessingDirectionDefault
 
361
   },
 
362
 
 
363
   {
 
364
       XmNtitleString, XmCTitleString, XmRXmString, 
 
365
       sizeof(XmString), XtOffsetOf(XmScaleRec,scale.title), 
 
366
       XmRImmediate, (XtPointer) NULL
 
367
   },
 
368
 
 
369
   {
 
370
        "pri.vate","Pri.vate",XmRInt,
 
371
        sizeof(int), XtOffsetOf(XmScaleRec,scale.last_value),
 
372
        XmRImmediate, (XtPointer) False
 
373
   },
 
374
 
 
375
   {
 
376
       XmNfontList, XmCFontList, XmRFontList, 
 
377
       sizeof(XmFontList), XtOffsetOf(XmScaleRec, scale.font_list), 
 
378
       XmRCallProc, (XtPointer)CheckSetRenderTable
 
379
   },
 
380
 
 
381
   {
 
382
       XmNrenderTable, XmCRenderTable, XmRRenderTable, 
 
383
       sizeof(XmRenderTable), XtOffsetOf(XmScaleRec, scale.font_list), 
 
384
       XmRCallProc, (XtPointer)CheckSetRenderTable
 
385
   },
 
386
 
 
387
   {
 
388
       XmNshowValue, XmCShowValue, XmRShowValue, 
 
389
       sizeof(XtEnum), XtOffsetOf(XmScaleRec,scale.show_value), 
 
390
       XmRImmediate, (XtPointer) XmNONE
 
391
   },
 
392
         
 
393
   {
 
394
       XmNdecimalPoints, XmCDecimalPoints, XmRShort, 
 
395
       sizeof(short), XtOffsetOf(XmScaleRec,scale.decimal_points), 
 
396
       XmRImmediate, (XtPointer) 0
 
397
   },
 
398
 
 
399
   {
 
400
       XmNscaleWidth, XmCScaleWidth, XmRHorizontalDimension,
 
401
       sizeof (Dimension), XtOffsetOf(XmScaleRec, scale.scale_width),
 
402
       XmRImmediate, (XtPointer) 0
 
403
   },
 
404
 
 
405
   {
 
406
       XmNscaleHeight, XmCScaleHeight, XmRVerticalDimension,
 
407
       sizeof (Dimension), XtOffsetOf(XmScaleRec, scale.scale_height),
 
408
       XmRImmediate, (XtPointer) 0
 
409
   },
 
410
 
 
411
   {
 
412
       XmNhighlightThickness, XmCHighlightThickness, XmRHorizontalDimension, 
 
413
       sizeof (Dimension), XtOffsetOf(XmScaleRec, scale.highlight_thickness),
 
414
       XmRCallProc, (XtPointer) _XmSetThickness
 
415
   },
 
416
 
 
417
   {
 
418
       XmNhighlightOnEnter, XmCHighlightOnEnter, XmRBoolean, 
 
419
       sizeof (Boolean), XtOffsetOf(XmScaleRec, scale.highlight_on_enter),
 
420
       XmRImmediate, (XtPointer) False
 
421
   },
 
422
   {
 
423
       XmNvalueChangedCallback, XmCCallback, XmRCallback, 
 
424
       sizeof(XtCallbackList), 
 
425
       XtOffsetOf(XmScaleRec,scale.value_changed_callback), 
 
426
       XmRCallback, (XtPointer) NULL
 
427
   },
 
428
 
 
429
   {
 
430
      XmNconvertCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
 
431
      XtOffsetOf(XmScaleRec, scale.convert_callback),
 
432
      XmRCallback, (XtPointer) NULL
 
433
   },
 
434
 
 
435
   { 
 
436
       XmNdragCallback, XmCCallback, XmRCallback, 
 
437
       sizeof(XtCallbackList),
 
438
       XtOffsetOf(XmScaleRec,scale.drag_callback), 
 
439
       XmRCallback, (XtPointer) NULL
 
440
   },
 
441
 
 
442
   {
 
443
       XmNscaleMultiple, XmCScaleMultiple, XmRInt, 
 
444
       sizeof(int), XtOffsetOf(XmScaleRec,scale.scale_multiple), 
 
445
       XmRImmediate, (XtPointer) 0
 
446
   },
 
447
   {
 
448
       XmNslidingMode, XmCSlidingMode, XmRSlidingMode, 
 
449
       sizeof(XtEnum), XtOffsetOf(XmScaleRec,scale.sliding_mode), 
 
450
       XmRImmediate, (XtPointer) XmSLIDER
 
451
   },
 
452
   {
 
453
       XmNeditable, XmCEditable, XmRBoolean, 
 
454
       sizeof(XtEnum), XtOffsetOf(XmScaleRec,scale.editable), 
 
455
       XmRCallProc, (XtPointer) EditableDefault
 
456
   },
 
457
   {
 
458
       XmNsliderVisual, XmCSliderVisual, XmRSliderVisual,
 
459
       sizeof (XtEnum),
 
460
       XtOffsetOf(XmScaleRec, scale.slider_visual),
 
461
       XmRCallProc, (XtPointer) SliderVisualDefault
 
462
   },
 
463
   {
 
464
       XmNsliderMark, XmCSliderMark, XmRSliderMark,
 
465
       sizeof (XtEnum),
 
466
       XtOffsetOf(XmScaleRec, scale.slider_mark),
 
467
       XmRCallProc, (XtPointer) SliderMarkDefault
 
468
   },
 
469
   { /* undocumented - need synthetic hook to be complete */
 
470
       XmNsliderSize, XmCSliderSize, XmRHorizontalInt, sizeof (int),
 
471
       XtOffsetOf(XmScaleRec, scale.slider_size),
 
472
       XmRImmediate, (XtPointer) 30
 
473
   },
 
474
   { 
 
475
       XmNshowArrows, XmCShowArrows, XmRShowArrows, sizeof (XtEnum),
 
476
       XtOffsetOf(XmScaleRec, scale.show_arrows),
 
477
       XmRImmediate, (XtPointer) XmNONE
 
478
   },
 
479
};
 
480
 
 
481
 
 
482
/*  Definition for resources that need special processing in get values  */
 
483
 
 
484
static XmSyntheticResource syn_resources[] =
 
485
{
 
486
    { 
 
487
        XmNtitleString,
 
488
        sizeof (XmString), XtOffsetOf(XmScaleRec, scale.title), 
 
489
        ScaleGetTitleString, (XmImportProc)NULL 
 
490
    },
 
491
    { 
 
492
        XmNscaleWidth,
 
493
        sizeof (Dimension), XtOffsetOf(XmScaleRec, scale.scale_width), 
 
494
        XmeFromHorizontalPixels, XmeToHorizontalPixels 
 
495
    },
 
496
    { 
 
497
        XmNscaleHeight,
 
498
        sizeof (Dimension), XtOffsetOf(XmScaleRec, scale.scale_height), 
 
499
        XmeFromVerticalPixels, XmeToVerticalPixels
 
500
    }
 
501
};
 
502
 
 
503
 
 
504
/*  Scale class record definition  */
 
505
 
 
506
static XmBaseClassExtRec baseClassExtRec = {
 
507
    NULL,
 
508
    NULLQUARK,
 
509
    XmBaseClassExtVersion,
 
510
    sizeof(XmBaseClassExtRec),
 
511
    (XtInitProc)NULL,                   /* InitializePrehook    */
 
512
    (XtSetValuesFunc)NULL,              /* SetValuesPrehook     */
 
513
    (XtInitProc)NULL,                   /* InitializePosthook   */
 
514
    (XtSetValuesFunc)NULL,              /* SetValuesPosthook    */
 
515
    NULL,                               /* secondaryObjectClass */
 
516
    (XtInitProc)NULL,                   /* secondaryCreate      */
 
517
    (XmGetSecResDataFunc)NULL,          /* getSecRes data       */
 
518
    { 0 },                              /* fastSubclass flags   */
 
519
    (XtArgsProc)NULL,                   /* getValuesPrehook     */
 
520
    (XtArgsProc)NULL,                   /* getValuesPosthook    */
 
521
    (XtWidgetClassProc)NULL,            /* classPartInitPrehook */
 
522
    (XtWidgetClassProc)NULL,            /* classPartInitPosthook*/
 
523
    NULL,                               /* ext_resources        */
 
524
    NULL,                               /* compiled_ext_resources*/
 
525
    0,                                  /* num_ext_resources    */
 
526
    FALSE,                              /* use_sub_resources    */
 
527
    WidgetNavigable,                    /* widgetNavigable      */
 
528
    (XmFocusChangeProc)NULL,            /* focusChange          */
 
529
    (XmWrapperData)NULL                 /* wrapperData          */
 
530
};
 
531
 
 
532
externaldef(xmscaleclassrec) XmScaleClassRec xmScaleClassRec = 
 
533
{
 
534
   {                                            /* core_class fields    */
 
535
      (WidgetClass) &xmManagerClassRec,         /* superclass         */
 
536
      "XmScale",                                /* class_name         */
 
537
      sizeof(XmScaleRec),                       /* widget_size        */
 
538
      ClassInitialize,                          /* class_initialize   */
 
539
      ClassPartInitialize,                      /* class_part_init    */
 
540
      FALSE,                                    /* class_inited       */
 
541
      Initialize,                               /* initialize         */
 
542
      (XtArgsProc)NULL,                         /* initialize_hook    */
 
543
      Realize,                                  /* realize            */
 
544
      NULL,                                     /* actions            */
 
545
      0,                                        /* num_actions        */
 
546
      resources,                                /* resources          */
 
547
      XtNumber(resources),                      /* num_resources      */
 
548
      NULLQUARK,                                /* xrm_class          */
 
549
      TRUE,                                     /* compress_motion    */
 
550
      XtExposeCompressMaximal,                  /* compress_exposure  */
 
551
      TRUE,                                     /* compress_enterlv   */
 
552
      FALSE,                                    /* visible_interest   */
 
553
      Destroy,                                  /* destroy            */
 
554
      Resize,                                   /* resize             */
 
555
      Redisplay,                                /* expose             */
 
556
      SetValues,                                /* set_values         */
 
557
      (XtArgsFunc)NULL,                         /* set_values_hook    */
 
558
      XtInheritSetValuesAlmost,                 /* set_values_almost  */
 
559
      (XtArgsProc)NULL,                         /* get_values_hook    */
 
560
      (XtAcceptFocusProc)NULL,                  /* accept_focus       */
 
561
      XtVersion,                                /* version            */
 
562
      NULL,                                     /* callback_private   */
 
563
      XtInheritTranslations,                    /* tm_table           */
 
564
      (XtGeometryHandler) QueryGeometry,        /* query_geometry     */
 
565
      (XtStringProc)NULL,                       /* display_accelerator*/
 
566
      (XtPointer)&baseClassExtRec,              /* extension          */
 
567
   },
 
568
 
 
569
   {                                            /* composite_class fields */
 
570
      GeometryManager,                          /* geometry_manager   */
 
571
      ChangeManaged,                            /* change_managed     */
 
572
      XtInheritInsertChild,                     /* insert_child       */
 
573
      XtInheritDeleteChild,                     /* delete_child       */
 
574
      NULL,                                     /* extension          */
 
575
   },
 
576
 
 
577
   {                                            /* constraint_class fields */
 
578
      NULL,                                     /* resource list        */   
 
579
      0,                                        /* num resources        */   
 
580
      sizeof(XmManagerConstraintRec),           /* constraint size      */   
 
581
      (XtInitProc)NULL,                         /* init proc            */   
 
582
      (XtWidgetProc)NULL,                       /* destroy proc         */   
 
583
      (XtSetValuesFunc)NULL,                    /* set values proc      */   
 
584
      NULL,                                     /* extension            */
 
585
   },
 
586
 
 
587
 
 
588
   {            /* manager_class fields */
 
589
      XtInheritTranslations,                    /* translations           */
 
590
      syn_resources,                            /* syn_resources          */
 
591
      XtNumber(syn_resources),                  /* num_syn_resources      */
 
592
      NULL,                                     /* syn_cont_resources     */
 
593
      0,                                        /* num_syn_cont_resources */
 
594
      XmInheritParentProcess,                   /* parent_process         */
 
595
      NULL,                                     /* extension              */
 
596
   },
 
597
 
 
598
   {                                            /* scale class - none */     
 
599
      (XtPointer) NULL                          /* extension */
 
600
   }    
 
601
};
 
602
 
 
603
externaldef(xmscalewidgetclass) WidgetClass
 
604
        xmScaleWidgetClass = (WidgetClass)&xmScaleClassRec;
 
605
 
 
606
 
 
607
/* Transfer trait record */
 
608
 
 
609
static XmConst XmTransferTraitRec ScaleTransfer = {
 
610
  0,                                            /* version */
 
611
  (XmConvertCallbackProc) DragConvertCallback,  /* convertProc */
 
612
  NULL,                                         /* destinationProc */
 
613
  NULL,                                         /* destinationPreHookProc */
 
614
};
 
615
 
 
616
/****************************************************************/
 
617
/************** Synthetic hook & default routines ***************/
 
618
/****************************************************************/
 
619
 
 
620
/*ARGSUSED*/
 
621
static void
 
622
ScaleGetTitleString(
 
623
        Widget wid,
 
624
        int resource,           /* unused */
 
625
        XtArgVal *value)
 
626
/****************           ARGSUSED  ****************/
 
627
{
 
628
        XmScaleWidget scale = (XmScaleWidget) wid ;
 
629
        Arg           al[1] ;
 
630
 
 
631
        if (scale->scale.title == NULL) {
 
632
            /* mean that the title has never been set, so 
 
633
               we should return NULL, not the label value which
 
634
               is the label name, not NULL,  in this case */
 
635
            *value = (XtArgVal) NULL ;
 
636
        } else { 
 
637
            /* title = -1, our magic value used to tell: look in
 
638
               the label child. */
 
639
            XtSetArg (al[0], XmNlabelString, value);    /* make a copy */
 
640
            XtGetValues (scale->composite.children[0], al, 1);
 
641
        }
 
642
}
 
643
 
 
644
 
 
645
/*********************************************************************
 
646
 *
 
647
 * ProcessingDirectionDefault
 
648
 *    This procedure provides the dynamic default behavior for
 
649
 *    the processing direction resource dependent on the orientation.
 
650
 *
 
651
 *********************************************************************/
 
652
/*ARGSUSED*/
 
653
static void 
 
654
ProcessingDirectionDefault(
 
655
        XmScaleWidget widget,
 
656
        int offset,             /* unused */
 
657
        XrmValue *value )
 
658
{
 
659
        static unsigned char direction;
 
660
 
 
661
        value->addr = (XPointer) &direction;
 
662
 
 
663
        if (widget->scale.orientation == XmHORIZONTAL)
 
664
        {
 
665
           if (LayoutIsRtoLM(widget))
 
666
                direction = XmMAX_ON_LEFT;
 
667
           else
 
668
                direction = XmMAX_ON_RIGHT;
 
669
        }
 
670
        else /* XmVERTICAL  -- range checking done during widget
 
671
                                   initialization */
 
672
                direction = XmMAX_ON_TOP;
 
673
}
 
674
 
 
675
 
 
676
 
 
677
/*********************************************************************
 
678
 *
 
679
 * SliderVisualDefault
 
680
 *    
 
681
 *
 
682
 *********************************************************************/
 
683
/*ARGSUSED*/
 
684
static void 
 
685
SliderVisualDefault(
 
686
        XmScaleWidget widget,
 
687
        int offset,             /* unused */
 
688
        XrmValue *value )
 
689
{
 
690
      static XtEnum slider_visual ;
 
691
 
 
692
      value->addr = (XPointer) &slider_visual;
 
693
              
 
694
      if (widget->scale.sliding_mode == XmTHERMOMETER) {
 
695
          slider_visual = XmTROUGH_COLOR ;
 
696
      } else {
 
697
          slider_visual = XmSHADOWED_BACKGROUND ;
 
698
      }
 
699
      
 
700
}
 
701
 
 
702
 
 
703
 
 
704
 
 
705
 
 
706
/*********************************************************************
 
707
 *
 
708
 * SliderMarkDefault
 
709
 *    
 
710
 *
 
711
 *********************************************************************/
 
712
/*ARGSUSED*/
 
713
static void 
 
714
SliderMarkDefault(
 
715
        XmScaleWidget widget,
 
716
        int offset,             /* unused */
 
717
        XrmValue *value )
 
718
{
 
719
      static XtEnum slider_mark ;
 
720
 
 
721
      value->addr = (XPointer) &slider_mark;
 
722
 
 
723
      if (!widget->scale.editable) slider_mark = XmNONE ;
 
724
      else {
 
725
          if (widget->scale.sliding_mode == XmTHERMOMETER)
 
726
              slider_mark = XmROUND_MARK ;
 
727
          else
 
728
              slider_mark = XmETCHED_LINE ;
 
729
      }
 
730
}
 
731
 
 
732
/*********************************************************************
 
733
 *
 
734
 * EditableDefault
 
735
 *    
 
736
 *
 
737
 *********************************************************************/
 
738
/*ARGSUSED*/
 
739
static void 
 
740
EditableDefault(
 
741
        XmScaleWidget widget,
 
742
        int offset,             /* unused */
 
743
        XrmValue *value )
 
744
{
 
745
      static XtEnum editable ;
 
746
 
 
747
      value->addr = (XPointer) &editable;
 
748
              
 
749
      if (widget->scale.sliding_mode == XmTHERMOMETER) {
 
750
          editable = False ;
 
751
      } else {
 
752
          editable = True ;
 
753
      }
 
754
      
 
755
}
 
756
 
 
757
 
 
758
/*
 
759
 * XmRCallProc routine for checking list.font before setting it to NULL
 
760
 * if no value is specified for both XmNrenderTable and XmNfontList.
 
761
 * If "last_value" is True, then function has been called twice on same 
 
762
 * widget, thus resource needs to be set NULL, otherwise leave it alone.
 
763
 */
 
764
/* ARGSUSED */
 
765
static void 
 
766
CheckSetRenderTable(Widget wid,
 
767
                    int offset,
 
768
                    XrmValue *value )
 
769
{
 
770
  XmScaleWidget sw = (XmScaleWidget)wid;
 
771
  
 
772
  /* Check if been here before */
 
773
  if (sw->scale.last_value)
 
774
      value->addr = NULL;
 
775
  else {
 
776
      sw->scale.last_value = True;
 
777
      value->addr = (char*)&(sw->scale.font_list);
 
778
  }
 
779
 
 
780
}
 
781
 
 
782
 
 
783
/************************************************************************
 
784
 *
 
785
 *  ClassInitialize
 
786
 *
 
787
 ************************************************************************/
 
788
static void 
 
789
ClassInitialize( void )
 
790
{
 
791
  baseClassExtRec.record_type = XmQmotif ;
 
792
 
 
793
  if (null_region == NULL)
 
794
    null_region = XCreateRegion();
 
795
}
 
796
 
 
797
 
 
798
 
 
799
/************************************************************************
 
800
 *
 
801
 *  ClassPartInitialize
 
802
 *     Initialize the fast subclassing.
 
803
 *
 
804
 ************************************************************************/
 
805
static void 
 
806
ClassPartInitialize(
 
807
        WidgetClass wc )
 
808
{
 
809
   _XmFastSubclassInit (wc, XmSCALE_BIT);
 
810
 
 
811
    /* Install transfer trait */
 
812
    XmeTraitSet((XtPointer)wc, XmQTtransfer, (XtPointer) &ScaleTransfer);
 
813
}
 
814
 
 
815
 
 
816
 
 
817
/*********************************************************************
 
818
 *  Initialize
 
819
 *      Validate all of the argument data for the widget, create the
 
820
 *      title label and scrollbar.
 
821
 *
 
822
 *********************************************************************/
 
823
/*ARGSUSED*/
 
824
static void 
 
825
ValidateInitialState(
 
826
        XmScaleWidget req,      /* unused */
 
827
        XmScaleWidget new_w )
 
828
{
 
829
        Boolean default_value = FALSE;
 
830
        float value_range;
 
831
        
 
832
 
 
833
        if (new_w->scale.minimum >= new_w->scale.maximum)
 
834
        {
 
835
                new_w->scale.minimum = 0;
 
836
                new_w->scale.maximum = 100;
 
837
                XmeWarning( (Widget) new_w, MESSAGE1);
 
838
        }
 
839
 
 
840
        value_range = (float)((float)new_w->scale.maximum - 
 
841
                              (float)new_w->scale.minimum);
 
842
 
 
843
        if (value_range > (float)((float)INT_MAX / (float) 2.0))
 
844
        {
 
845
             new_w->scale.minimum = 0;
 
846
             if (new_w->scale.maximum > (INT_MAX / 2))
 
847
                 new_w->scale.maximum = INT_MAX / 2;
 
848
            XmeWarning( (Widget) new_w, MESSAGE9);
 
849
        }
 
850
 
 
851
        if (new_w->scale.value == XmINVALID_DIMENSION)
 
852
        {
 
853
                new_w->scale.value = 0;
 
854
                default_value = True;
 
855
        }
 
856
 
 
857
        if (new_w->scale.value < new_w->scale.minimum)
 
858
        {
 
859
                new_w->scale.value = new_w->scale.minimum;
 
860
                if (!default_value) XmeWarning( (Widget) new_w, MESSAGE2);
 
861
        }
 
862
 
 
863
        if (new_w->scale.value > new_w->scale.maximum)
 
864
        {
 
865
                new_w->scale.value = new_w->scale.minimum;
 
866
                if (!default_value) XmeWarning( (Widget) new_w, MESSAGE3);
 
867
        }
 
868
 
 
869
        if(!XmRepTypeValidValue( XmRID_ORIENTATION,
 
870
                                new_w->scale.orientation, (Widget) new_w) )
 
871
        {
 
872
                new_w->scale.orientation = XmVERTICAL;
 
873
        }
 
874
 
 
875
        if (!XmRepTypeValidValue( XmRID_SHOW_VALUE,
 
876
                                new_w->scale.show_value, (Widget) new_w) )
 
877
            {
 
878
                new_w->scale.show_value = XmNONE;
 
879
            }
 
880
 
 
881
        if (new_w->scale.orientation == XmHORIZONTAL)
 
882
        {
 
883
                if ((new_w->scale.processing_direction != XmMAX_ON_RIGHT) &&
 
884
                        (new_w->scale.processing_direction != XmMAX_ON_LEFT))
 
885
 
 
886
                {
 
887
                        new_w->scale.processing_direction = XmMAX_ON_RIGHT;
 
888
                        XmeWarning( (Widget) new_w, MESSAGE5);
 
889
                }
 
890
        }
 
891
        else
 
892
        {
 
893
                if ((new_w->scale.processing_direction != XmMAX_ON_TOP) &&
 
894
                        (new_w->scale.processing_direction != XmMAX_ON_BOTTOM))
 
895
                {
 
896
                        new_w->scale.processing_direction = XmMAX_ON_TOP;
 
897
                        XmeWarning( (Widget) new_w, MESSAGE5);
 
898
                }
 
899
        }
 
900
 
 
901
        if (new_w->scale.scale_multiple > (new_w->scale.maximum 
 
902
                - new_w->scale.minimum))
 
903
        {
 
904
                XmeWarning( (Widget) new_w, MESSAGE7);
 
905
                new_w->scale.scale_multiple = (new_w->scale.maximum
 
906
                        - new_w->scale.minimum) / 10;
 
907
        }
 
908
        else if (new_w->scale.scale_multiple < 0)
 
909
        {
 
910
                XmeWarning( (Widget) new_w, MESSAGE8);
 
911
                new_w->scale.scale_multiple = (new_w->scale.maximum
 
912
                        - new_w->scale.minimum) / 10;
 
913
        }
 
914
        else if (new_w->scale.scale_multiple == 0)
 
915
                new_w->scale.scale_multiple = (new_w->scale.maximum
 
916
                        - new_w->scale.minimum) / 10;
 
917
        /* Assure a minimum value of 1 */
 
918
        if (new_w->scale.scale_multiple < 1)
 
919
                new_w->scale.scale_multiple = 1;
 
920
}
 
921
 
 
922
static Widget 
 
923
CreateScaleTitle(
 
924
        XmScaleWidget new_w )
 
925
{
 
926
        XmLabelGadget title;
 
927
        Arg args[5];
 
928
        int n;
 
929
 
 
930
        /*  Create the title label gadget  */
 
931
 
 
932
        /* title can be NULL or a valid XmString, if null,
 
933
           the label will use its own name as XmString */
 
934
        n = 0;
 
935
        XtSetArg (args[n], XmNlabelString, new_w->scale.title); n++;
 
936
        XtSetArg (args[n], XmNfontList, new_w->scale.font_list);        n++;
 
937
 
 
938
        title = (XmLabelGadget) XmCreateLabelGadget( (Widget) new_w, 
 
939
                                                    "Title",
 
940
                args, n);
 
941
 
 
942
        if (new_w->scale.title) {
 
943
            XtManageChild ((Widget) title);
 
944
            new_w->scale.title = (XmString) -1 ;
 
945
        } /* scale.title need to be set to some special not NULL value
 
946
             in order to see any change at SetValues time and also to
 
947
             return NULL at Getvalue time in the hook. This is pirs 3197:
 
948
             when you setvalues a new xmstring as title, the value of the
 
949
             title field, a pointer, might be the same. */
 
950
 
 
951
        return((Widget) title);
 
952
}
 
953
 
 
954
static Widget 
 
955
CreateScaleScrollBar(
 
956
        XmScaleWidget new_w )
 
957
{
 
958
    Widget scrollbar;
 
959
    Arg args[25];
 
960
    int n = 0;
 
961
    
 
962
    /*  Build up an arg list for and create the scrollbar  */
 
963
    
 
964
    n = 0;
 
965
    SET(XmNmaximum, SCROLLBAR_MAX);     
 
966
    SET(XmNminimum, 0); 
 
967
    SET(XmNshowArrows, new_w->scale.show_arrows);       
 
968
    SET(XmNunitType, XmPIXELS); 
 
969
    SET(XmNorientation, new_w->scale.orientation);      
 
970
    SET(XmNprocessingDirection, new_w->scale.processing_direction);       
 
971
    SET(XmNslidingMode, new_w->scale.sliding_mode);
 
972
    SET(XmNsliderVisual, new_w->scale.slider_visual);
 
973
    SET(XmNsliderMark, new_w->scale.slider_mark);
 
974
    SET(XmNeditable, new_w->scale.editable);
 
975
    if (new_w->scale.scale_width != 0)
 
976
        SET(XmNwidth, new_w->scale.scale_width);        
 
977
    if (new_w->scale.scale_height != 0)
 
978
        SET(XmNheight, new_w->scale.scale_height);      
 
979
    
 
980
 
 
981
    /* then get everything else from the scale parent */
 
982
    /* another more incestuous but also more powerful - because it
 
983
       allows customization - way of doing that would be to provide
 
984
       resource default proc in ScrollBar that look for a Scale parent
 
985
       and inherit those visual resources */
 
986
    SET(XmNhighlightColor, new_w->manager.highlight_color);             
 
987
    SET(XmNhighlightPixmap, new_w->manager.highlight_pixmap);
 
988
    SET(XmNhighlightThickness, new_w->scale.highlight_thickness);
 
989
    SET(XmNhighlightOnEnter, new_w->scale.highlight_on_enter);  
 
990
    SET(XmNtraversalOn, new_w->manager.traversal_on);   
 
991
    SET(XmNshadowThickness, new_w->manager.shadow_thickness);
 
992
    SET(XmNbackground, new_w->core.background_pixel);   
 
993
    SET(XmNtopShadowColor, new_w->manager.top_shadow_color); 
 
994
    SET(XmNbottomShadowColor, new_w->manager.bottom_shadow_color);
 
995
    SET(XmNtopShadowPixmap, new_w->manager.top_shadow_pixmap);
 
996
    SET(XmNbottomShadowPixmap, new_w->manager.bottom_shadow_pixmap);
 
997
    scrollbar = XmCreateScrollBar( (Widget) new_w, "Scrollbar", args, n);
 
998
    
 
999
    XtManageChild(scrollbar);
 
1000
 
 
1001
    XtAddCallback(scrollbar, XmNvalueChangedCallback, ValueChanged, NULL);
 
1002
    XtAddCallback(scrollbar, XmNdragCallback, ValueChanged, NULL);
 
1003
 
 
1004
    return(scrollbar);
 
1005
}
 
1006
 
 
1007
 
 
1008
/************************************************************************
 
1009
 *
 
1010
 *  GetForegroundGC
 
1011
 *     Get the graphics context used for drawing the slider value.
 
1012
 *
 
1013
 ************************************************************************/
 
1014
static void 
 
1015
GetForegroundGC(
 
1016
        XmScaleWidget sw )
 
1017
{
 
1018
   XGCValues values;
 
1019
   XtGCMask  valueMask;
 
1020
 
 
1021
   valueMask = GCForeground | GCBackground | GCGraphicsExposures;
 
1022
   values.foreground = sw->manager.foreground;
 
1023
   values.background = sw->core.background_pixel;
 
1024
   values.graphics_exposures = False;
 
1025
   if (sw->scale.font_struct)
 
1026
     values.font = sw->scale.font_struct->fid, valueMask |= GCFont;
 
1027
 
 
1028
/*   if ((sw->core.background_pixmap != None) && 
 
1029
       (sw->core.background_pixmap != XmUNSPECIFIED_PIXMAP)) {
 
1030
       valueMask |= GCFillStyle | GCTile ;
 
1031
       values.fill_style = FillTiled;
 
1032
       values.tile = sw->core.background_pixmap;
 
1033
   }*/
 
1034
 
 
1035
   /* Added dynamic clip mask & don't care about origion to merge with
 
1036
      Label[Gadget] and List GC:s */
 
1037
   sw->scale.foreground_GC = XtAllocateGC ((Widget) sw, 0, valueMask, &values,
 
1038
                                           GCClipMask, 
 
1039
                                           GCClipXOrigin | GCClipYOrigin);
 
1040
}
 
1041
 
 
1042
 
 
1043
/*ARGSUSED*/
 
1044
static void 
 
1045
Initialize(
 
1046
        Widget rw,
 
1047
        Widget nw,
 
1048
        ArgList args,           /* unused */
 
1049
        Cardinal *num_args )    /* unused */
 
1050
{
 
1051
    XmScaleWidget req = (XmScaleWidget) rw ;
 
1052
    XmScaleWidget new_w = (XmScaleWidget) nw ;
 
1053
    
 
1054
    new_w->scale.value_region = XCreateRegion();
 
1055
 
 
1056
    /* Validate the incoming data  */                      
 
1057
    ValidateInitialState(req, new_w);
 
1058
 
 
1059
    if (new_w->scale.font_list == NULL)
 
1060
        new_w->scale.font_list =
 
1061
            XmeGetDefaultRenderTable( (Widget) new_w, XmLABEL_FONTLIST);
 
1062
    
 
1063
    /*  Set the scale font struct used for interactive value display  */
 
1064
    /*  to the 0th font in the title font list.  If not font list is  */
 
1065
    /*  provides, open up fixed and use that.                         */
 
1066
    
 
1067
    new_w->scale.font_list = XmFontListCopy(new_w->scale.font_list);
 
1068
 
 
1069
    if (new_w->scale.font_list) {
 
1070
        if (!XmeRenderTableGetDefaultFont(new_w->scale.font_list,
 
1071
                                          &new_w->scale.font_struct))
 
1072
            new_w->scale.font_struct = NULL;
 
1073
#ifndef USE_XFT
 
1074
    } else {
 
1075
        new_w->scale.font_struct = 
 
1076
          XLoadQueryFont (XtDisplay (new_w), XmDEFAULT_FONT);
 
1077
        if (new_w->scale.font_struct == NULL)
 
1078
            new_w->scale.font_struct = XLoadQueryFont (XtDisplay (new_w), "*");
 
1079
#endif
 
1080
    }
 
1081
    
 
1082
    (void) CreateScaleTitle(new_w);
 
1083
    (void) CreateScaleScrollBar(new_w);
 
1084
    
 
1085
    /*  Get the foreground GC and initialize internal variables  */
 
1086
    
 
1087
    GetForegroundGC (new_w);
 
1088
    
 
1089
    new_w->scale.show_value_x = 0;
 
1090
    new_w->scale.show_value_y = 0;
 
1091
    new_w->scale.show_value_width = 0;
 
1092
    new_w->scale.show_value_height = 0;
 
1093
    new_w->scale.state_flags = 0 ;
 
1094
 
 
1095
    /* add the handler that drags the value shown in the scale window */
 
1096
    XtAddEventHandler(nw, ButtonPressMask, False, StartDrag, NULL);
 
1097
}
 
1098
 
 
1099
 
 
1100
/************************************************************************
 
1101
 *
 
1102
 *  Redisplay
 
1103
 *     General redisplay function called on exposure events.
 
1104
 *     Only redisplays the gadgets (title included) and the value, 
 
1105
 *       the scrollbar will take care of itself.
 
1106
 *
 
1107
 ************************************************************************/
 
1108
static void 
 
1109
Redisplay(
 
1110
        Widget wid,
 
1111
        XEvent *event,
 
1112
        Region region )
 
1113
{
 
1114
    XmScaleWidget sw = (XmScaleWidget) wid ;
 
1115
 
 
1116
    XmeRedisplayGadgets( (Widget) sw, event, region);
 
1117
   
 
1118
    ShowValue (sw);
 
1119
}
 
1120
 
 
1121
 
 
1122
 
 
1123
 
 
1124
/************************************************************************
 
1125
 *
 
1126
 *  Resize
 
1127
 *     Re-layout children.
 
1128
 *
 
1129
 ************************************************************************/
 
1130
static void 
 
1131
Resize(
 
1132
        Widget wid )
 
1133
{
 
1134
    XmScaleWidget sw = (XmScaleWidget) wid ;
 
1135
    XtWidgetGeometry desired ;
 
1136
 
 
1137
    /* Find out what the best possible answer would be, the layout
 
1138
       routines use this optimum for placing the children */
 
1139
    desired.width =  0;
 
1140
    desired.height =  0;
 
1141
    GetScaleSize(sw, &desired.width, &desired.height);
 
1142
    
 
1143
    if (sw->scale.orientation == XmHORIZONTAL)
 
1144
        LayoutHorizontalScale(sw, &desired, NULL);
 
1145
    else 
 
1146
        LayoutVerticalScale(sw, &desired, NULL);
 
1147
 
 
1148
    /* Scale has a gravity None, so resize will always generate redisplay */
 
1149
}
 
1150
 
 
1151
 
 
1152
 
 
1153
 
 
1154
/************************************************************************
 
1155
 *
 
1156
 *  SetValues stuff
 
1157
 *
 
1158
 ************************************************************************/
 
1159
 
 
1160
static void 
 
1161
ValidateInputs(
 
1162
        XmScaleWidget cur,
 
1163
        XmScaleWidget new_w )
 
1164
{
 
1165
   float value_range;
 
1166
   /* Validate the incoming data  */                      
 
1167
 
 
1168
   if (new_w->scale.minimum >= new_w->scale.maximum)
 
1169
   {
 
1170
      new_w->scale.minimum = cur->scale.minimum;
 
1171
      new_w->scale.maximum = cur->scale.maximum;
 
1172
      XmeWarning( (Widget) new_w, MESSAGE1);
 
1173
   }
 
1174
 
 
1175
   value_range = (float)((float)new_w->scale.maximum - 
 
1176
                         (float)new_w->scale.minimum);
 
1177
   if (value_range > (float)((float)INT_MAX / (float) 2.0))
 
1178
   {
 
1179
       new_w->scale.minimum = 0;
 
1180
         if (new_w->scale.maximum > (INT_MAX / 2))
 
1181
             new_w->scale.maximum = INT_MAX / 2;
 
1182
        XmeWarning( (Widget) new_w, MESSAGE9);
 
1183
   }
 
1184
 
 
1185
   if (new_w->scale.value < new_w->scale.minimum)
 
1186
   {
 
1187
      new_w->scale.value = new_w->scale.minimum;
 
1188
      XmeWarning( (Widget) new_w, MESSAGE2);
 
1189
   }
 
1190
 
 
1191
   if (new_w->scale.value > new_w->scale.maximum)
 
1192
   {
 
1193
      new_w->scale.value = new_w->scale.maximum;
 
1194
      XmeWarning( (Widget) new_w, MESSAGE3);
 
1195
   }
 
1196
 
 
1197
   if(!XmRepTypeValidValue( XmRID_SLIDING_MODE,
 
1198
                           new_w->scale.sliding_mode, (Widget) new_w) )
 
1199
   {
 
1200
      new_w->scale.sliding_mode = cur->scale.sliding_mode;
 
1201
   }
 
1202
 
 
1203
 
 
1204
   if(!XmRepTypeValidValue( XmRID_ORIENTATION,
 
1205
                           new_w->scale.orientation, (Widget) new_w)    )
 
1206
       {
 
1207
       new_w->scale.orientation = cur->scale.orientation;
 
1208
   }
 
1209
 
 
1210
 
 
1211
   if(!XmRepTypeValidValue( XmRID_SHOW_VALUE,
 
1212
                           new_w->scale.show_value, (Widget) new_w)    )
 
1213
       {
 
1214
       new_w->scale.show_value = cur->scale.show_value;
 
1215
   }
 
1216
 
 
1217
 
 
1218
   if (new_w->scale.orientation == XmHORIZONTAL)
 
1219
   {
 
1220
      if (new_w->scale.processing_direction != XmMAX_ON_LEFT &&
 
1221
          new_w->scale.processing_direction != XmMAX_ON_RIGHT)
 
1222
      {
 
1223
         new_w->scale.processing_direction = cur->scale.processing_direction;
 
1224
         XmeWarning( (Widget) new_w, MESSAGE5);
 
1225
      }
 
1226
   }
 
1227
   else
 
1228
   {
 
1229
      if (new_w->scale.processing_direction != XmMAX_ON_TOP &&
 
1230
          new_w->scale.processing_direction != XmMAX_ON_BOTTOM)
 
1231
      {
 
1232
         new_w->scale.processing_direction = cur->scale.processing_direction;
 
1233
         XmeWarning( (Widget) new_w, MESSAGE5);
 
1234
      }
 
1235
   }
 
1236
 
 
1237
   if (new_w->scale.scale_multiple != cur->scale.scale_multiple)
 
1238
       {
 
1239
           if (new_w->scale.scale_multiple > (new_w->scale.maximum 
 
1240
                                              - new_w->scale.minimum))
 
1241
               {
 
1242
                   XmeWarning( (Widget) new_w, MESSAGE7);
 
1243
                   new_w->scale.scale_multiple = (new_w->scale.maximum
 
1244
                                                  - new_w->scale.minimum) / 10;
 
1245
               }
 
1246
           else if (new_w->scale.scale_multiple < 0)
 
1247
               {
 
1248
                   XmeWarning( (Widget) new_w, MESSAGE8);
 
1249
                   new_w->scale.scale_multiple = (new_w->scale.maximum
 
1250
                                                  - new_w->scale.minimum) / 10;
 
1251
               }
 
1252
           else if (new_w->scale.scale_multiple == 0)
 
1253
               new_w->scale.scale_multiple = (new_w->scale.maximum
 
1254
                                              - new_w->scale.minimum) / 10;
 
1255
           /* Assure a minimum value of 1 */
 
1256
           if (new_w->scale.scale_multiple < 1)
 
1257
               new_w->scale.scale_multiple = 1;
 
1258
       }
 
1259
}
 
1260
 
 
1261
 
 
1262
/*ARGSUSED*/
 
1263
static void 
 
1264
HandleTitle(
 
1265
        XmScaleWidget cur,
 
1266
        XmScaleWidget req,      /* unused */
 
1267
        XmScaleWidget new_w )
 
1268
{
 
1269
        Arg args[5];
 
1270
        int n = 0;
 
1271
 
 
1272
        /* cur title is either NULL or (-1), as set in CreateScaleTitle,
 
1273
           so diff are always pertinent */
 
1274
        /* new title can be NULL or a valid xmstring */
 
1275
        if (new_w->scale.title != cur->scale.title) {
 
1276
            XtSetArg (args[n], XmNlabelString, new_w->scale.title);     n++;
 
1277
        }
 
1278
 
 
1279
        if (new_w->scale.font_list != cur->scale.font_list) {
 
1280
            XtSetArg (args[n], XmNfontList, new_w->scale.font_list);    n++;
 
1281
        }
 
1282
 
 
1283
        if (n) XtSetValues (new_w->composite.children[0], args, n);
 
1284
        
 
1285
        if (new_w->scale.title != cur->scale.title) {
 
1286
            if (new_w->scale.title != NULL) {
 
1287
                /* new title differs from old one and is no null, so
 
1288
                   it's a valid xmstring that we change to -1 */
 
1289
                XtManageChild(new_w->composite.children[0]);
 
1290
                new_w->scale.title = (XmString) -1 ;
 
1291
            }
 
1292
            else  /* new title differs from old one and is null,
 
1293
                   so we let it be null, so that get scale title returns
 
1294
                   null instead of the label string */
 
1295
                XtUnmanageChild (new_w->composite.children[0]);
 
1296
        }
 
1297
}
 
1298
 
 
1299
/*ARGSUSED*/
 
1300
static void 
 
1301
HandleScrollBar(
 
1302
        XmScaleWidget cur,
 
1303
        XmScaleWidget req,      /* unused */
 
1304
        XmScaleWidget new_w )
 
1305
{
 
1306
        Arg args[30];
 
1307
        int n = 0;
 
1308
        Widget scrollbar = new_w->composite.children[1];
 
1309
        int slider_size, increment, page, value ;
 
1310
    
 
1311
        /* reset any attributes of the scrollbar */
 
1312
        SET(XmNshowArrows, new_w->scale.show_arrows);   
 
1313
        SET(XmNorientation, new_w->scale.orientation);  
 
1314
        SET(XmNprocessingDirection, new_w->scale.processing_direction);
 
1315
        if (new_w->scale.scale_width != cur->scale.scale_width)
 
1316
            SET(XmNwidth, new_w->scale.scale_width);    
 
1317
        if (new_w->scale.scale_height != cur->scale.scale_height)
 
1318
            SET(XmNheight, new_w->scale.scale_height);  
 
1319
        SET(XmNslidingMode, new_w->scale.sliding_mode);
 
1320
        SET(XmNsliderMark, new_w->scale.slider_mark);
 
1321
        SET(XmNsliderVisual, new_w->scale.slider_visual);
 
1322
        SET(XmNeditable, new_w->scale.editable);
 
1323
 
 
1324
        /* there is an issue of propagation here, whether or not
 
1325
           we want to force it. There is a behavior compatibility
 
1326
           issue if we decide to change the current situation */
 
1327
        SET(XmNsensitive, new_w->core.sensitive);      
 
1328
 
 
1329
        SET(XmNhighlightColor, new_w->manager.highlight_color);         
 
1330
        SET(XmNhighlightPixmap, new_w->manager.highlight_pixmap);
 
1331
        SET(XmNhighlightThickness, new_w->scale.highlight_thickness);   
 
1332
        SET(XmNshadowThickness, new_w->manager.shadow_thickness);
 
1333
        SET(XmNhighlightOnEnter, new_w->scale.highlight_on_enter);      
 
1334
        SET(XmNtraversalOn, new_w->manager.traversal_on);       
 
1335
        SET(XmNbackground, new_w->core.background_pixel);       
 
1336
        SET(XmNtopShadowColor, new_w->manager.top_shadow_color); 
 
1337
        SET(XmNtopShadowPixmap, new_w->manager.top_shadow_pixmap);
 
1338
        SET(XmNbottomShadowColor, new_w->manager.bottom_shadow_color);
 
1339
        SET(XmNbottomShadowPixmap, new_w->manager.bottom_shadow_pixmap);
 
1340
                
 
1341
        CalcScrollBarData(new_w, &value, &slider_size, &increment, &page);
 
1342
        SET(XmNvalue, value);           
 
1343
        SET(XmNsliderSize, slider_size);        
 
1344
        SET(XmNincrement, increment);           
 
1345
        SET(XmNpageIncrement, page);            
 
1346
 
 
1347
        XtSetValues (scrollbar, args, n);
 
1348
 
 
1349
        SetScrollBarData(new_w);
 
1350
}
 
1351
 
 
1352
 
 
1353
/************************************************************************
 
1354
 *
 
1355
 *  SetValues class method
 
1356
 *
 
1357
 ************************************************************************/
 
1358
/*ARGSUSED*/
 
1359
static Boolean 
 
1360
SetValues(
 
1361
        Widget cw,
 
1362
        Widget rw,
 
1363
        Widget nw,
 
1364
        ArgList args_in,        /* unused */
 
1365
        Cardinal *num_args_in ) /* unused */
 
1366
{
 
1367
    XmScaleWidget cur = (XmScaleWidget) cw ;
 
1368
    XmScaleWidget req = (XmScaleWidget) rw ;
 
1369
    XmScaleWidget new_w = (XmScaleWidget) nw ;
 
1370
    Boolean redisplay = False ;
 
1371
 
 
1372
#define DIFF(x) ((new_w->x) != (cur->x))
 
1373
 
 
1374
    /* this flag is checked in the GM */
 
1375
    new_w->scale.state_flags |= FROM_SET_VALUE ;
 
1376
 
 
1377
    if (DIFF(scale.orientation)) {
 
1378
 
 
1379
        /* Make sure that processing direction tracks orientation */
 
1380
        if (!DIFF(scale.processing_direction)) {
 
1381
            if ((new_w->scale.orientation == XmHORIZONTAL) &&
 
1382
                (cur->scale.processing_direction == XmMAX_ON_TOP))
 
1383
                new_w->scale.processing_direction = XmMAX_ON_RIGHT;
 
1384
            else if ((new_w->scale.orientation == XmHORIZONTAL) &&
 
1385
                     (cur->scale.processing_direction == XmMAX_ON_BOTTOM))
 
1386
                new_w->scale.processing_direction = XmMAX_ON_LEFT;
 
1387
            else if ((new_w->scale.orientation == XmVERTICAL) &&
 
1388
                     (cur->scale.processing_direction == XmMAX_ON_LEFT))
 
1389
                new_w->scale.processing_direction = XmMAX_ON_BOTTOM;
 
1390
            else if ((new_w->scale.orientation == XmVERTICAL) &&
 
1391
                     (cur->scale.processing_direction == XmMAX_ON_RIGHT))
 
1392
                new_w->scale.processing_direction = XmMAX_ON_TOP;
 
1393
        }
 
1394
 
 
1395
        /* Make scale_width and scale_height track orientation too */
 
1396
        if ((new_w->scale.scale_width == cur->scale.scale_width) &&
 
1397
            (new_w->scale.scale_height == cur->scale.scale_height)) {
 
1398
            new_w->scale.scale_width = cur->scale.scale_height;
 
1399
            new_w->scale.scale_height = cur->scale.scale_width;
 
1400
        }
 
1401
        
 
1402
    }
 
1403
 
 
1404
    ValidateInputs(cur, new_w);
 
1405
 
 
1406
    HandleTitle(cur, req, new_w);
 
1407
    HandleScrollBar(cur, req, new_w);
 
1408
 
 
1409
        /*  Set the font struct for the value displayed  */
 
1410
 
 
1411
    if (DIFF(scale.font_list)) {
 
1412
 
 
1413
#ifndef USE_XFT
 
1414
        if ((cur->scale.font_list == NULL) && 
 
1415
            (cur->scale.font_struct != NULL))
 
1416
            XFreeFont(XtDisplay (cur), cur->scale.font_struct);
 
1417
#endif
 
1418
 
 
1419
        if (cur->scale.font_list) XmFontListFree(cur->scale.font_list);
 
1420
                
 
1421
        if (new_w->scale.font_list == NULL)
 
1422
            new_w->scale.font_list =
 
1423
                XmeGetDefaultRenderTable( (Widget) new_w, XmLABEL_FONTLIST); 
 
1424
                
 
1425
        new_w->scale.font_list = XmFontListCopy(new_w->scale.font_list);
 
1426
 
 
1427
        if (new_w->scale.font_list != NULL) {
 
1428
            if (!XmeRenderTableGetDefaultFont(new_w->scale.font_list,
 
1429
                                              &new_w->scale.font_struct))
 
1430
                new_w->scale.font_struct = NULL;
 
1431
#ifdef USE_XFT
 
1432
        /* TODO: should it be ifndef? */
 
1433
        } else {
 
1434
            new_w->scale.font_struct =
 
1435
                XLoadQueryFont(XtDisplay(new_w), XmDEFAULT_FONT);
 
1436
            if (new_w->scale.font_struct == NULL)
 
1437
                new_w->scale.font_struct =
 
1438
                    XLoadQueryFont(XtDisplay(new_w), "*");
 
1439
#endif
 
1440
        }
 
1441
 
 
1442
        XtReleaseGC ((Widget) new_w, new_w->scale.foreground_GC);
 
1443
        GetForegroundGC (new_w);
 
1444
        redisplay = True;
 
1445
    }
 
1446
 
 
1447
 
 
1448
    if (XtIsRealized((Widget)new_w) && 
 
1449
        ( DIFF(scale.font_list) ||
 
1450
        DIFF(scale.highlight_thickness) ||
 
1451
        DIFF(scale.scale_height) ||
 
1452
        DIFF(scale.scale_width) ||
 
1453
        DIFF(scale.orientation) ||
 
1454
        DIFF(manager.unit_type) ||
 
1455
        DIFF(manager.shadow_thickness) || 
 
1456
        /* need to check on req for title since HandleTitle made
 
1457
           the new_w field equal to cur */
 
1458
        (req->scale.title != cur->scale.title) ||
 
1459
        /* major show value change only */
 
1460
        (DIFF(scale.show_value) &&
 
1461
         ((new_w->scale.show_value == XmNONE) ||
 
1462
          (cur->scale.show_value == XmNONE))))) {
 
1463
  
 
1464
        Dimension width=0, height=0 ;
 
1465
            /*
 
1466
             * Re-calculate the size of the Scale if a new size was not 
 
1467
             * specified, and only if realized.
 
1468
             */
 
1469
        
 
1470
        GetScaleSize (new_w, &width, &height);
 
1471
 
 
1472
        if (new_w->core.width == cur->core.width)
 
1473
            new_w->core.width = width ;
 
1474
 
 
1475
        if (new_w->core.height == cur->core.height)
 
1476
            new_w->core.height = height ;
 
1477
    }
 
1478
    
 
1479
    if (XtIsRealized((Widget)new_w) && 
 
1480
        (DIFF(scale.sliding_mode) ||
 
1481
        /* minor show value change only */
 
1482
        (DIFF(scale.show_value) &&
 
1483
         (new_w->scale.show_value != XmNONE) &&
 
1484
         (cur->scale.show_value != XmNONE)) ||
 
1485
        DIFF(scale.show_arrows))) {
 
1486
        XtWidgetProc resize;
 
1487
        
 
1488
        /* generate a relayout and ask for redisplay, only if realized */
 
1489
        _XmProcessLock();
 
1490
        resize = xmScaleClassRec.core_class.resize;
 
1491
        _XmProcessUnlock();     
 
1492
        
 
1493
        (* resize) (nw);
 
1494
        redisplay = True;
 
1495
    }
 
1496
 
 
1497
 
 
1498
    if (XtIsRealized((Widget)new_w) &&
 
1499
        (DIFF(scale.decimal_points) ||
 
1500
        DIFF(scale.value) ||
 
1501
        DIFF(scale.minimum) ||
 
1502
        DIFF(scale.maximum) ||
 
1503
        DIFF(scale.processing_direction) ||
 
1504
        DIFF(scale.show_value))) {
 
1505
        ShowValue(new_w);
 
1506
    }
 
1507
 
 
1508
 
 
1509
    /*  See if the GC needs to be regenerated  */
 
1510
 
 
1511
    if (DIFF(manager.foreground) ||
 
1512
        DIFF(core.background_pixel)||
 
1513
        DIFF(core.background_pixmap)) {
 
1514
        XtReleaseGC ((Widget) new_w, new_w->scale.foreground_GC);
 
1515
        GetForegroundGC (new_w);
 
1516
        redisplay = True;
 
1517
    }
 
1518
    
 
1519
    /* unset the GM flag */
 
1520
    new_w->scale.state_flags &= ~FROM_SET_VALUE ;
 
1521
 
 
1522
    return (redisplay);
 
1523
#undef DIFF
 
1524
}
 
1525
 
 
1526
 
 
1527
 
 
1528
/************************************************************************
 
1529
 *
 
1530
 *  Realize
 
1531
 *      Can't use the standard Manager class realize procedure,
 
1532
 *      because it creates a window with NW gravity, and the
 
1533
 *      scale wants a gravity of None.
 
1534
 *
 
1535
 ************************************************************************/
 
1536
static void 
 
1537
Realize(
 
1538
        register Widget w,
 
1539
        XtValueMask *p_valueMask,
 
1540
        XSetWindowAttributes *attributes )
 
1541
{
 
1542
   Mask valueMask = *p_valueMask;
 
1543
 
 
1544
   /*   Make sure height and width are not zero.
 
1545
    */
 
1546
   if (!XtWidth(w)) XtWidth(w) = 1 ;
 
1547
   if (!XtHeight(w)) XtHeight(w) = 1 ;
 
1548
    
 
1549
   valueMask |= CWBitGravity | CWDontPropagate;
 
1550
   attributes->bit_gravity = ForgetGravity;
 
1551
   attributes->do_not_propagate_mask =
 
1552
      ButtonPressMask | ButtonReleaseMask |
 
1553
      KeyPressMask | KeyReleaseMask | PointerMotionMask;
 
1554
        
 
1555
   XtCreateWindow (w, InputOutput, CopyFromParent, valueMask, attributes);
 
1556
}
 
1557
 
 
1558
 
 
1559
 
 
1560
/************************************************************************
 
1561
 *
 
1562
 *  Destroy
 
1563
 *      Free the callback lists attached to the scale.
 
1564
 *
 
1565
 ************************************************************************/
 
1566
static void 
 
1567
Destroy(
 
1568
        Widget wid )
 
1569
{
 
1570
    XmScaleWidget sw = (XmScaleWidget) wid ;
 
1571
 
 
1572
    XtReleaseGC ((Widget) sw, sw->scale.foreground_GC);
 
1573
 
 
1574
#ifdef USE_XFT
 
1575
    if (sw->scale.font_list == NULL && sw->scale.font_struct != NULL)
 
1576
        XFreeFont (XtDisplay (sw), sw->scale.font_struct);
 
1577
#endif
 
1578
 
 
1579
    if (sw->scale.font_list) XmFontListFree(sw->scale.font_list);
 
1580
 
 
1581
    if (sw->scale.value_region)
 
1582
      XDestroyRegion(sw->scale.value_region);
 
1583
}
 
1584
 
 
1585
 
 
1586
 
 
1587
 
 
1588
/************************************************************************
 
1589
 *
 
1590
 *  QueryGeometry
 
1591
 *
 
1592
 ************************************************************************/
 
1593
static XtGeometryResult 
 
1594
QueryGeometry(
 
1595
        Widget widget,
 
1596
        XtWidgetGeometry *intended,
 
1597
        XtWidgetGeometry *desired )
 
1598
{
 
1599
    /* deal with user initial size setting */
 
1600
    if (!XtIsRealized(widget))  {
 
1601
        desired->width = XtWidth(widget) ;    /* might be 0 */
 
1602
        desired->height = XtHeight(widget) ;  /* might be 0 */
 
1603
    } else {        
 
1604
        /* always computes natural size afterwards */
 
1605
        desired->width = 0 ;
 
1606
        desired->height = 0 ;
 
1607
    }
 
1608
 
 
1609
    GetScaleSize ((XmScaleWidget) widget, &desired->width, &desired->height);
 
1610
 
 
1611
    /* this function will set CWidth and CHeight */
 
1612
    return XmeReplyToQueryGeometry(widget, intended, desired) ;
 
1613
}
 
1614
 
 
1615
 
 
1616
/************************************************************************
 
1617
 *
 
1618
 *  GeometryManager
 
1619
 *      Accept everything except change in position.
 
1620
 *
 
1621
 ************************************************************************/
 
1622
/*ARGSUSED*/
 
1623
static XtGeometryResult 
 
1624
GeometryManager(
 
1625
        Widget w,
 
1626
        XtWidgetGeometry *request,
 
1627
        XtWidgetGeometry *reply ) /* unused */
 
1628
{
 
1629
    XtWidgetGeometry desired ;
 
1630
    XmScaleWidget sw = (XmScaleWidget) XtParent(w) ;
 
1631
 
 
1632
    if (IsQueryOnly(request)) return XtGeometryYes;
 
1633
 
 
1634
 
 
1635
    if (IsWidth(request)) w->core.width = request->width;
 
1636
    if (IsHeight(request)) w->core.height = request->height;
 
1637
    if (IsBorder(request)) w->core.border_width = request->border_width;
 
1638
 
 
1639
    /* no need to do any layout if it is our change, Xt will
 
1640
     generate one at the end */
 
1641
    if (sw->scale.state_flags & FROM_SET_VALUE) return XtGeometryYes;
 
1642
 
 
1643
 
 
1644
    /* Find out what the best possible answer would be */
 
1645
    desired.width =  0;
 
1646
    desired.height =  0;
 
1647
    GetScaleSize(sw, &desired.width, &desired.height);
 
1648
    
 
1649
    /* ask that to our parent */
 
1650
    desired.request_mode = (CWWidth | CWHeight);
 
1651
    _XmMakeGeometryRequest((Widget) sw, &desired);
 
1652
 
 
1653
    /* layout using the new size (accepted or not) */
 
1654
    if (sw->scale.orientation == XmHORIZONTAL)
 
1655
        LayoutHorizontalScale(sw, &desired, w);
 
1656
    else /* sw->scale.orientation == XmVERTICAL */
 
1657
        LayoutVerticalScale(sw, &desired, w);
 
1658
 
 
1659
    return XtGeometryYes;
 
1660
}
 
1661
 
 
1662
 
 
1663
 
 
1664
 
 
1665
/*********************************************************************
 
1666
 *  ChangeManaged
 
1667
 *     Layout children.
 
1668
 *
 
1669
 *********************************************************************/
 
1670
static void 
 
1671
ChangeManaged(
 
1672
        Widget wid )
 
1673
{
 
1674
    XmScaleWidget sw = (XmScaleWidget) wid ;
 
1675
    XtWidgetGeometry desired ;
 
1676
    Dimension tmp_width = 0, tmp_height = 0 ;
 
1677
 
 
1678
    GetScaleSize(sw, &tmp_width, &tmp_height);
 
1679
    desired.width = tmp_width ;
 
1680
    desired.height = tmp_height ;
 
1681
 
 
1682
    if (!XtIsRealized((Widget)sw))  {
 
1683
        /* the first time, only attemps to change non specified sizes */
 
1684
        if (XtWidth(sw)) desired.width = XtWidth(sw) ;  
 
1685
        if (XtHeight(sw)) desired.height = XtHeight(sw) ;
 
1686
    } 
 
1687
 
 
1688
    desired.request_mode = (CWWidth | CWHeight);
 
1689
    _XmMakeGeometryRequest((Widget) sw, &desired);
 
1690
 
 
1691
    /* layout with no instigator, but with our real preferred size */
 
1692
    desired.width = tmp_width ;
 
1693
    desired.height = tmp_height ;
 
1694
    if (sw->scale.orientation == XmHORIZONTAL)
 
1695
        LayoutHorizontalScale(sw, &desired, NULL);
 
1696
    else 
 
1697
        LayoutVerticalScale(sw, &desired, NULL);
 
1698
 
 
1699
    XmeNavigChangeManaged( (Widget) sw);
 
1700
}
 
1701
 
 
1702
 
 
1703
 
 
1704
 
 
1705
 
 
1706
static void 
 
1707
GetScaleSize(
 
1708
        XmScaleWidget sw,
 
1709
        Dimension *w,
 
1710
        Dimension *h )
 
1711
{
 
1712
    Dimension sav_w, sav_h;
 
1713
 
 
1714
    sav_w = XtWidth(sw);
 
1715
    sav_h = XtHeight(sw);
 
1716
 
 
1717
    /* Mark the scale as anything goes */
 
1718
    XtWidth(sw) = *w;
 
1719
    XtHeight(sw) = *h;
 
1720
 
 
1721
    /* only override the pointed dimensions if they are null */
 
1722
 
 
1723
    if (sw->scale.orientation == XmHORIZONTAL)  {
 
1724
        if (!*w) {
 
1725
            *w = MAX(TitleWidth(sw),
 
1726
                     MajorLeadPad(sw) + ScrollWidth(sw) + MajorTrailPad(sw));
 
1727
        }
 
1728
 
 
1729
        if (!*h) {
 
1730
            *h = MaxLabelHeight(sw) + ValueTroughHeight(sw)
 
1731
                + ScrollHeight(sw) + TitleHeight(sw);
 
1732
            if (sw->scale.show_value) *h += SCALE_VALUE_MARGIN;
 
1733
        }
 
1734
    } else /* sw->scale.orientation == XmVERTICAL */  {
 
1735
        if (!*w) {
 
1736
            *w = MaxLabelWidth(sw) + ValueTroughWidth(sw) 
 
1737
                + ScrollWidth(sw) + TitleWidth(sw);
 
1738
            if (sw->scale.show_value) *w += SCALE_VALUE_MARGIN;
 
1739
        }
 
1740
 
 
1741
        if (!*h) {
 
1742
            *h = MAX(TitleHeight(sw),
 
1743
                     MajorLeadPad(sw) + ScrollHeight(sw) + MajorTrailPad(sw));
 
1744
        }
 
1745
    }
 
1746
 
 
1747
    /* Don't ever desire 0 dimensions */
 
1748
    if (!*w) *w = 1;
 
1749
    if (!*h) *h = 1;
 
1750
 
 
1751
    /* Restore the current values */
 
1752
    XtWidth(sw) = sav_w;
 
1753
    XtHeight(sw) = sav_h;
 
1754
 
 
1755
}
 
1756
 
 
1757
 
 
1758
static Dimension 
 
1759
MaxLabelWidth(
 
1760
        XmScaleWidget sw )
 
1761
{
 
1762
    register int i;
 
1763
    register Widget c;
 
1764
    Dimension max = 0;
 
1765
 
 
1766
    /* start at 2 to skip the title and the scrollbar */
 
1767
    for ( i = 2; i < sw->composite.num_children; i++)
 
1768
        {
 
1769
            c = sw->composite.children[i];
 
1770
            if (XtIsManaged(c) && 
 
1771
                !((Object)c)->object.being_destroyed) 
 
1772
                ASSIGN_MAX(max, TotalWidth(c));
 
1773
        }
 
1774
    
 
1775
    return (max);
 
1776
}
 
1777
 
 
1778
static Dimension 
 
1779
MaxLabelHeight(
 
1780
        XmScaleWidget sw )
 
1781
{
 
1782
    register int i;
 
1783
    register Widget c;
 
1784
    Dimension max = 0;
 
1785
 
 
1786
    /* start at 2 to skip the title and the scrollbar */
 
1787
    for ( i = 2; i < sw->composite.num_children; i++)
 
1788
        {
 
1789
            c = sw->composite.children[i];
 
1790
            if (XtIsManaged(c) && 
 
1791
                !((Object)c)->object.being_destroyed) 
 
1792
                ASSIGN_MAX(max, TotalHeight(c));
 
1793
        }
 
1794
    
 
1795
    return (max);
 
1796
}
 
1797
 
 
1798
static Dimension 
 
1799
ValueTroughHeight(
 
1800
        XmScaleWidget sw)
 
1801
{
 
1802
#if USE_XFT
 
1803
    int ret_val = 0;
 
1804
    if (sw->scale.show_value) {
 
1805
        XmRenderTableGetDefaultFontExtents(sw->scale.font_list,
 
1806
                                           &ret_val, NULL, NULL);
 
1807
    }
 
1808
    return (Dimension)ret_val;
 
1809
#else
 
1810
    char buff[15];
 
1811
    register Dimension tmp_max, tmp_min, result;
 
1812
    int direction, ascent, descent;
 
1813
    XCharStruct overall_return;
 
1814
    
 
1815
#define GET_MAX(tmp, max_or_min_value) {\
 
1816
    if (sw->scale.decimal_points)\
 
1817
            sprintf(buff, "%d%c", max_or_min_value,\
 
1818
                    nl_langinfo(RADIXCHAR)[0]);\
 
1819
        else\
 
1820
            sprintf(buff, "%d", max_or_min_value);\
 
1821
            \
 
1822
        XTextExtents(sw->scale.font_struct, buff, strlen(buff),\
 
1823
                     &direction, &ascent, &descent, &overall_return);\
 
1824
            \
 
1825
            tmp = ascent + descent;\
 
1826
            }
 
1827
        
 
1828
    if (sw->scale.show_value) {
 
1829
        GET_MAX(tmp_max, sw->scale.maximum) ;
 
1830
        GET_MAX(tmp_min, sw->scale.minimum) ;
 
1831
        result = MAX(tmp_min, tmp_max);
 
1832
        return (result);
 
1833
        }
 
1834
    else
 
1835
        return (0);
 
1836
#undef GET_MAX
 
1837
#endif
 
1838
}
 
1839
 
 
1840
static Dimension 
 
1841
ValueTroughAscent(
 
1842
        XmScaleWidget sw)
 
1843
{
 
1844
#if USE_XFT
 
1845
    int ret_val = 0;
 
1846
    if (sw->scale.show_value) {
 
1847
        XmRenderTableGetDefaultFontExtents(sw->scale.font_list,
 
1848
                                           NULL, &ret_val, NULL);
 
1849
    }
 
1850
    return (Dimension)ret_val;
 
1851
#else
 
1852
    char buff[15];
 
1853
    register Dimension tmp_max, tmp_min, result;
 
1854
    int direction, ascent, descent;
 
1855
    XCharStruct overall_return;
 
1856
    
 
1857
#define GET_MAX(tmp, max_or_min_value) {\
 
1858
    if (sw->scale.decimal_points)\
 
1859
            sprintf(buff, "%d%c", max_or_min_value,\
 
1860
                    nl_langinfo(RADIXCHAR)[0]);\
 
1861
        else\
 
1862
            sprintf(buff, "%d", max_or_min_value);\
 
1863
            \
 
1864
        XTextExtents(sw->scale.font_struct, buff, strlen(buff),\
 
1865
                     &direction, &ascent, &descent, &overall_return);\
 
1866
            \
 
1867
            tmp = ascent;\
 
1868
            }
 
1869
        
 
1870
    if (sw->scale.show_value) {
 
1871
        GET_MAX(tmp_max, sw->scale.maximum) ;
 
1872
        GET_MAX(tmp_min, sw->scale.minimum) ;
 
1873
        result = MAX(tmp_min, tmp_max);
 
1874
        return (result);
 
1875
        }
 
1876
    else
 
1877
        return (0);
 
1878
#undef GET_MAX
 
1879
#endif
 
1880
}
 
1881
 
 
1882
static Dimension 
 
1883
ValueTroughDescent(
 
1884
        XmScaleWidget sw)
 
1885
{
 
1886
#if USE_XFT
 
1887
    int ret_val = 0;
 
1888
    if (sw->scale.show_value) {
 
1889
        XmRenderTableGetDefaultFontExtents(sw->scale.font_list,
 
1890
                                           NULL, NULL, &ret_val);
 
1891
    }
 
1892
    return (Dimension)ret_val;
 
1893
#else
 
1894
    char buff[15];
 
1895
    register Dimension tmp_max, tmp_min, result;
 
1896
    int direction, ascent, descent;
 
1897
    XCharStruct overall_return;
 
1898
    
 
1899
#define GET_MAX(tmp, max_or_min_value) {\
 
1900
    if (sw->scale.decimal_points)\
 
1901
            sprintf(buff, "%d%c", max_or_min_value,\
 
1902
                    nl_langinfo(RADIXCHAR)[0]);\
 
1903
        else\
 
1904
            sprintf(buff, "%d", max_or_min_value);\
 
1905
            \
 
1906
        XTextExtents(sw->scale.font_struct, buff, strlen(buff),\
 
1907
                     &direction, &ascent, &descent, &overall_return);\
 
1908
            \
 
1909
            tmp = descent;\
 
1910
            }
 
1911
        
 
1912
    if (sw->scale.show_value) {
 
1913
        GET_MAX(tmp_max, sw->scale.maximum) ;
 
1914
        GET_MAX(tmp_min, sw->scale.minimum) ;
 
1915
        result = MAX(tmp_min, tmp_max);
 
1916
        return (result);
 
1917
        }
 
1918
    else
 
1919
        return (0);
 
1920
#undef GET_MAX
 
1921
#endif
 
1922
}
 
1923
 
 
1924
static Dimension 
 
1925
ValueTroughWidth(
 
1926
        XmScaleWidget sw)
 
1927
{
 
1928
    char buff[15];
 
1929
    register Dimension tmp_max, tmp_min, result;
 
1930
    int direction, ascent, descent;
 
1931
    XCharStruct overall_return;
 
1932
    
 
1933
#if USE_XFT
 
1934
#define GET_MAX(tmp, max_or_min_value) {\
 
1935
    XmString tmp_str;\
 
1936
    if (sw->scale.decimal_points)\
 
1937
            sprintf(buff, "%d%c", max_or_min_value,\
 
1938
                    nl_langinfo(RADIXCHAR)[0]);\
 
1939
        else\
 
1940
            sprintf(buff, "%d", max_or_min_value);\
 
1941
            \
 
1942
    tmp = XmStringWidth(sw->scale.font_list, tmp_str = XmStringCreateSimple(buff));\
 
1943
    XmStringFree(tmp_str);\
 
1944
}
 
1945
#else
 
1946
#define GET_MAX(tmp, max_or_min_value) {\
 
1947
    if (sw->scale.decimal_points)\
 
1948
            sprintf(buff, "%d%c", max_or_min_value,\
 
1949
                    nl_langinfo(RADIXCHAR)[0]);\
 
1950
        else\
 
1951
            sprintf(buff, "%d", max_or_min_value);\
 
1952
            \
 
1953
        XTextExtents(sw->scale.font_struct, buff, strlen(buff),\
 
1954
                     &direction, &ascent, &descent, &overall_return);\
 
1955
            \
 
1956
            tmp = overall_return.rbearing - overall_return.lbearing;\
 
1957
            }
 
1958
#endif
 
1959
        
 
1960
    if (sw->scale.show_value) {
 
1961
        GET_MAX(tmp_max, sw->scale.maximum) ;
 
1962
        GET_MAX(tmp_min, sw->scale.minimum) ;
 
1963
        result = MAX(tmp_min, tmp_max);
 
1964
        return (result);
 
1965
        }
 
1966
    else
 
1967
        return (0);
 
1968
#undef GET_MAX
 
1969
}
 
1970
 
 
1971
 
 
1972
static Dimension 
 
1973
TitleWidth(
 
1974
        XmScaleWidget sw )
 
1975
{
 
1976
    register Dimension tmp = 0;
 
1977
    register Widget title_widget = sw->composite.children[0];
 
1978
 
 
1979
    if (XtIsManaged(title_widget)) {
 
1980
        tmp = TotalWidth(title_widget) ;
 
1981
 
 
1982
        if (sw->scale.orientation == XmVERTICAL)
 
1983
            tmp += (TotalHeight(title_widget)) >> 2;
 
1984
    }
 
1985
    
 
1986
    return(tmp);
 
1987
}
 
1988
 
 
1989
 
 
1990
 
 
1991
static Dimension 
 
1992
TitleHeight(
 
1993
        XmScaleWidget sw )
 
1994
{
 
1995
    register Dimension tmp = 0;
 
1996
    register Widget title_widget = sw->composite.children[0];
 
1997
 
 
1998
    if (XtIsManaged(title_widget)) {
 
1999
        tmp = TotalHeight(title_widget);
 
2000
 
 
2001
        if (sw->scale.orientation == XmHORIZONTAL)
 
2002
            tmp += (TotalHeight(title_widget)) >> 2;
 
2003
    }
 
2004
    
 
2005
    return(tmp);
 
2006
}
 
2007
 
 
2008
 
 
2009
static Cardinal 
 
2010
NumManaged(
 
2011
        XmScaleWidget sw,
 
2012
        Widget * first_man,
 
2013
        Widget * last_man)
 
2014
{
 
2015
    Cardinal i, num_managed = 0 ;
 
2016
    Widget first_tic = NULL, last_tic = NULL, c  ;
 
2017
 
 
2018
    for (i = 2; i < sw->composite.num_children; i++) {
 
2019
        c = sw->composite.children[i];
 
2020
        if (XtIsManaged(c) && 
 
2021
            !((Object)c)->object.being_destroyed) {
 
2022
            num_managed ++ ;        
 
2023
            if (!first_tic) first_tic = c ;
 
2024
            last_tic = c ;
 
2025
        }
 
2026
    }    
 
2027
 
 
2028
    if (first_man) *first_man = first_tic ;
 
2029
    if (last_man) *last_man = last_tic ;
 
2030
 
 
2031
    return num_managed + 2 ;
 
2032
}
 
2033
 
 
2034
 
 
2035
static Dimension 
 
2036
MajorLeadPad(
 
2037
        XmScaleWidget sw )
 
2038
{
 
2039
    XmScrollBarWidget sb = (XmScrollBarWidget)(sw->composite.children[1]);
 
2040
    int tmp1 = 0, tmp2;
 
2041
    Cardinal num_managed ;
 
2042
    Widget first_tic  ;
 
2043
 
 
2044
    num_managed = NumManaged(sw, &first_tic, NULL);
 
2045
 
 
2046
    if (num_managed > 3) {
 
2047
        if (sw->scale.orientation == XmHORIZONTAL)
 
2048
            tmp1 = (TotalWidth(first_tic) / 2) 
 
2049
                - LeadXTic(sb, sw);
 
2050
        else
 
2051
            tmp1 = (TotalHeight(first_tic) / 2) 
 
2052
                - LeadYTic(sb, sw);
 
2053
        
 
2054
    } else if (num_managed == 3) {
 
2055
        /*
 
2056
         * This is a potential non-terminal recursion.
 
2057
         *
 
2058
         * Currently MajorScrollSize has knowledge of this potential
 
2059
         * problem and has guards around the call to this procedure.
 
2060
         * Modify with care.
 
2061
         */
 
2062
        
 
2063
        if (sw->scale.orientation == XmHORIZONTAL)
 
2064
            tmp1 = ((int)TotalWidth(first_tic) - 
 
2065
                    (int)ScrollWidth(sw))/2;
 
2066
        else
 
2067
            tmp1 = ((int)TotalHeight(first_tic) - 
 
2068
                    (int)ScrollHeight(sw))/2;
 
2069
    }
 
2070
 
 
2071
    tmp1 -= (sb->primitive.highlight_thickness + sb->primitive.shadow_thickness);
 
2072
  
 
2073
    if (sw->scale.orientation == XmHORIZONTAL)
 
2074
        tmp2 = ((int)ValueTroughWidth(sw) / 2) - (int)LeadXTic(sb, sw);
 
2075
    else {
 
2076
        if (sw->scale.sliding_mode == XmTHERMOMETER) 
 
2077
            tmp2 = ((int)ValueTroughAscent(sw)) - (int)LeadYTic(sb, sw);
 
2078
        else 
 
2079
            tmp2 = ((int)ValueTroughHeight(sw) / 2) - (int)LeadYTic(sb, sw);
 
2080
    }
 
2081
 
 
2082
    tmp2 -= (sb->primitive.highlight_thickness
 
2083
             + sb->primitive.shadow_thickness);
 
2084
 
 
2085
    ASSIGN_MAX(tmp1, 0);
 
2086
    ASSIGN_MAX(tmp2, 0);
 
2087
 
 
2088
    return(MAX(tmp1, tmp2));
 
2089
}
 
2090
 
 
2091
 
 
2092
 
 
2093
static Dimension 
 
2094
MajorTrailPad(
 
2095
        XmScaleWidget sw )
 
2096
{
 
2097
    XmScrollBarWidget sb = (XmScrollBarWidget) (sw->composite.children[1]);
 
2098
    int tmp1 = 0, tmp2;
 
2099
    Cardinal num_managed ;
 
2100
    Widget first_tic, last_tic ;   
 
2101
 
 
2102
    num_managed = NumManaged(sw, &first_tic, &last_tic);
 
2103
   
 
2104
    if (num_managed > 3) {
 
2105
        if (sw->scale.orientation == XmHORIZONTAL)
 
2106
            tmp1 = ((int)TotalWidth(last_tic) / 2) 
 
2107
                                   - (int)TrailXTic(sb, sw);
 
2108
        else
 
2109
            tmp1 = ((int)TotalHeight(last_tic) / 2) 
 
2110
                                   - (int)TrailYTic(sb, sw); 
 
2111
    } else if (num_managed == 3) {
 
2112
        /*
 
2113
         * This is a potential non-terminal recursion.
 
2114
         *
 
2115
         * Currently MajorScrollSize has knowledge of this potential
 
2116
         * problem and has guards around the call to this procedure.
 
2117
         * Modify with care.
 
2118
         */
 
2119
        
 
2120
        if (sw->scale.orientation == XmHORIZONTAL)
 
2121
            tmp1 = ((int)TotalWidth(first_tic) - 
 
2122
                    (int)ScrollWidth(sw))/2;
 
2123
        else
 
2124
            tmp1 = ((int)TotalHeight(first_tic) - 
 
2125
                    (int)ScrollHeight(sw))/2;
 
2126
    }
 
2127
 
 
2128
    tmp1 -= (sb->primitive.highlight_thickness
 
2129
                + sb->primitive.shadow_thickness);
 
2130
 
 
2131
    if (sw->scale.orientation == XmHORIZONTAL)
 
2132
        tmp2 = ((int)ValueTroughWidth(sw) / 2) - (int)TrailXTic(sb, sw);
 
2133
    else {
 
2134
        if (sw->scale.sliding_mode == XmTHERMOMETER) 
 
2135
            tmp2 = ((int)ValueTroughDescent(sw)) - (int)TrailYTic(sb, sw);
 
2136
        else 
 
2137
            tmp2 = ((int)ValueTroughHeight(sw) / 2) - (int)TrailYTic(sb, sw);
 
2138
    }
 
2139
 
 
2140
    tmp2 -= (sb->primitive.highlight_thickness
 
2141
             + sb->primitive.shadow_thickness);
 
2142
 
 
2143
        
 
2144
    ASSIGN_MAX(tmp1, 0);
 
2145
    ASSIGN_MAX(tmp2, 0);
 
2146
 
 
2147
    return(MAX(tmp1, tmp2));
 
2148
}
 
2149
 
 
2150
 
 
2151
 
 
2152
static Dimension 
 
2153
ScrollWidth(
 
2154
        XmScaleWidget sw )
 
2155
{
 
2156
    int tmp = 0;
 
2157
    
 
2158
    if (sw->scale.orientation == XmVERTICAL) {
 
2159
        if (!(tmp = sw->scale.scale_width))
 
2160
            tmp = SCALE_DEFAULT_MINOR_SIZE;
 
2161
        else
 
2162
            tmp = sw->scale.scale_width;
 
2163
    } else {
 
2164
        if (!(tmp = sw->scale.scale_width)) {
 
2165
            if (sw->core.width != 0) {
 
2166
                Cardinal num_managed ;
 
2167
 
 
2168
                num_managed = NumManaged(sw, NULL, NULL);
 
2169
                /* Have to catch an indirect recursion here */
 
2170
                if (num_managed > 3)
 
2171
                    tmp = (int)sw->core.width 
 
2172
                        - (MajorLeadPad(sw) + MajorTrailPad(sw));
 
2173
                else {
 
2174
                    /* Magic to handle excessively wide values */
 
2175
                    int tmp1, tmp2;
 
2176
                    XmScrollBarWidget sb = (XmScrollBarWidget)
 
2177
                        sw->composite.children[1];
 
2178
                    
 
2179
                    tmp1 = ((int)ValueTroughWidth(sw) / 2) - 
 
2180
                        (int)LeadXTic(sb, sw);
 
2181
                    tmp2 = ((int)ValueTroughWidth(sw) / 2) - 
 
2182
                        (int)TrailXTic(sb, sw);
 
2183
                    ASSIGN_MAX(tmp1, 0);
 
2184
                    ASSIGN_MAX(tmp2, 0);
 
2185
                    tmp = (int)sw->core.width - tmp1 - tmp2;
 
2186
                }
 
2187
            }
 
2188
        }
 
2189
        
 
2190
        if (tmp <= 0) {
 
2191
            Cardinal num_managed ;
 
2192
 
 
2193
            num_managed = NumManaged(sw, NULL, NULL);
 
2194
 
 
2195
            if (num_managed > 2) {
 
2196
                /* Have to catch an indirect recursion here */
 
2197
                if (num_managed > 3) {
 
2198
                    Dimension tic, diff;
 
2199
                    XmScrollBarWidget sb = (XmScrollBarWidget)
 
2200
                        sw->composite.children[1];
 
2201
                    
 
2202
                    tmp = (num_managed - 2)* MaxLabelWidth(sw);
 
2203
                    
 
2204
                    tic = sb->primitive.highlight_thickness
 
2205
                        + sb->primitive.shadow_thickness
 
2206
                            + (Dimension) (((float) SLIDER_SIZE( sw) / 2.0) 
 
2207
                                           + 0.5);
 
2208
                    
 
2209
                    diff = tic - ((int)MaxLabelWidth(sw) / 2);
 
2210
                    
 
2211
                    if (diff > 0) tmp+= (2 * diff);
 
2212
                }
 
2213
                else
 
2214
                    tmp = MaxLabelWidth(sw);
 
2215
            }
 
2216
        }
 
2217
        
 
2218
        if (tmp <= 0) tmp = SCALE_DEFAULT_MAJOR_SIZE;
 
2219
    }
 
2220
    
 
2221
    return((Dimension) tmp);
 
2222
}
 
2223
 
 
2224
static Dimension 
 
2225
ScrollHeight(
 
2226
        XmScaleWidget sw )
 
2227
{
 
2228
    int tmp;
 
2229
    
 
2230
    if (sw->scale.orientation == XmHORIZONTAL) {
 
2231
        if (!(tmp = sw->scale.scale_height))
 
2232
            tmp = SCALE_DEFAULT_MINOR_SIZE;
 
2233
        else
 
2234
            tmp = sw->scale.scale_height;
 
2235
    }   else {
 
2236
        if (!(tmp = sw->scale.scale_height)){
 
2237
            if (sw->core.height != 0)
 
2238
                {
 
2239
                    Cardinal num_managed ;
 
2240
 
 
2241
                    num_managed = NumManaged(sw, NULL, NULL);
 
2242
                    /* Have to catch an indirect recursion here */
 
2243
                    if (num_managed > 3)
 
2244
                        tmp = (int)sw->core.height 
 
2245
                            - (MajorLeadPad(sw) + MajorTrailPad(sw));
 
2246
                    else 
 
2247
                        tmp = sw->core.height;
 
2248
                }
 
2249
        }
 
2250
 
 
2251
        if (tmp <= 0){
 
2252
            Cardinal num_managed ;
 
2253
 
 
2254
            num_managed = NumManaged(sw, NULL, NULL);
 
2255
 
 
2256
            if (num_managed > 2){
 
2257
                /* Have to catch an indirect recursion here */
 
2258
                    if (num_managed > 3) {
 
2259
                        Dimension tic, diff;
 
2260
                        XmScrollBarWidget sb = (XmScrollBarWidget)
 
2261
                            sw->composite.children[1];
 
2262
                        
 
2263
                        tmp = (num_managed - 2)* MaxLabelHeight(sw);
 
2264
                        
 
2265
                        tic = sb->primitive.highlight_thickness
 
2266
                            + sb->primitive.shadow_thickness
 
2267
                                + (Dimension) (((float) SLIDER_SIZE(sw) / 2.0) 
 
2268
                                               + 0.5);
 
2269
                        
 
2270
                        diff = tic - (MaxLabelHeight(sw) / 2);
 
2271
                        
 
2272
                        if (diff > 0) tmp+= (2 * diff);
 
2273
                    }
 
2274
                else
 
2275
                    tmp = MaxLabelHeight(sw);
 
2276
            }
 
2277
        }
 
2278
        
 
2279
        if (tmp <= 0) tmp = SCALE_DEFAULT_MAJOR_SIZE;
 
2280
    }
 
2281
    
 
2282
    return((Dimension)tmp);
 
2283
}
 
2284
 
 
2285
 
 
2286
 
 
2287
static void 
 
2288
LayoutHorizontalLabels(
 
2289
                       XmScaleWidget sw,
 
2290
                       XRectangle *scrollBox,
 
2291
                       XRectangle *labelBox,
 
2292
                       Widget instigator )
 
2293
{
 
2294
        Dimension first_tic_dim, last_tic_dim;
 
2295
        float tic_interval, tmp ;
 
2296
        XmScrollBarWidget sb = (XmScrollBarWidget)
 
2297
                (sw->composite.children[1]);
 
2298
        Widget w, first_tic;
 
2299
        int i;
 
2300
        Position x, y, y1;
 
2301
        Cardinal num_managed ;
 
2302
 
 
2303
        y1 = labelBox->y + labelBox->height;
 
2304
 
 
2305
        num_managed = NumManaged(sw, &first_tic, NULL);
 
2306
 
 
2307
        if (num_managed > 3)
 
2308
        {
 
2309
          first_tic_dim = scrollBox->x + LeadXTic(sb, sw);
 
2310
          last_tic_dim = (scrollBox->x + sb->core.width) - TrailXTic(sb, sw);
 
2311
          tic_interval = (float)(last_tic_dim - first_tic_dim)
 
2312
            / (num_managed - 3);
 
2313
          
 
2314
          for (i = 2, tmp = first_tic_dim;
 
2315
               i < sw->composite.num_children;
 
2316
               i++)
 
2317
            {
 
2318
              if (LayoutIsRtoLM(sw) &&
 
2319
                  sw->scale.processing_direction == XmMAX_ON_LEFT)
 
2320
                w = sw->composite.children[sw->composite.num_children - i + 1];
 
2321
              else
 
2322
                w = sw->composite.children[i];
 
2323
 
 
2324
              if (!XtIsManaged(w) ||
 
2325
                  ((Object)w)->object.being_destroyed) continue ;
 
2326
 
 
2327
              x = (int) tmp - (TotalWidth(w) / 2);
 
2328
              y = y1 - TotalHeight(w);
 
2329
              if (instigator != w)
 
2330
                XmeConfigureObject(w, x, y,
 
2331
                                   w->core.width, w->core.height,
 
2332
                                   w->core.border_width);
 
2333
              else {
 
2334
                w->core.x = x ;
 
2335
                w->core.y = y ;
 
2336
              }
 
2337
 
 
2338
              tmp += tic_interval ;
 
2339
            }
 
2340
        }
 
2341
        else if (num_managed == 3)
 
2342
        {
 
2343
                w = first_tic;
 
2344
                y = y1 - TotalHeight(w);
 
2345
                if (XtIsManaged(w) &&
 
2346
                    !((Object)w)->object.being_destroyed) {
 
2347
 
 
2348
                    tmp = (sb->scrollBar.slider_area_width - 
 
2349
                           TotalWidth(w)) / 2;
 
2350
                    x = scrollBox->x + sb->scrollBar.slider_area_x 
 
2351
                        + (int) tmp ;
 
2352
                    if (instigator != w)
 
2353
                        XmeConfigureObject(w, x, y, w->core.width, 
 
2354
                                           w->core.height,
 
2355
                                           w->core.border_width);
 
2356
                    else {
 
2357
                        w->core.x = x ;
 
2358
                        w->core.y = y ;
 
2359
                    }
 
2360
                }
 
2361
        }
 
2362
}
 
2363
 
 
2364
static void 
 
2365
LayoutHorizontalScale(
 
2366
        XmScaleWidget sw,
 
2367
        XtWidgetGeometry * desired,
 
2368
        Widget instigator)
 
2369
{
 
2370
        int diff_w, diff_h, tdiff;
 
2371
        XRectangle labelBox, valueBox, scrollBox, titleBox;
 
2372
 
 
2373
        diff_w = XtWidth(sw) - desired->width;
 
2374
        diff_h = XtHeight(sw) - desired->height;
 
2375
 
 
2376
        
 
2377
        titleBox.height = TitleHeight(sw);
 
2378
        scrollBox.height = ScrollHeight(sw);
 
2379
        valueBox.height = ValueTroughHeight(sw);
 
2380
        labelBox.height = MaxLabelHeight(sw);
 
2381
                
 
2382
        /* Figure out all of the y locations */
 
2383
        if (diff_h >= 0)
 
2384
        {
 
2385
                /* 
 
2386
                 * We place the title, scrollbar, and value from the right
 
2387
                 */
 
2388
                titleBox.y = XtHeight(sw) - titleBox.height;
 
2389
                scrollBox.y = titleBox.y - scrollBox.height;
 
2390
 
 
2391
                if (sw->scale.show_value == XmNEAR_BORDER) {
 
2392
                    valueBox.y = 0;
 
2393
                    labelBox.y = scrollBox.y - labelBox.height;
 
2394
                } else { /* NEAR_SLIDER or NONE */
 
2395
                    labelBox.y = 0;
 
2396
                    valueBox.y = scrollBox.y - valueBox.height;
 
2397
                }
 
2398
        }
 
2399
        else if ((tdiff = diff_h + TitleHeight(sw)) >= 0)
 
2400
        {
 
2401
                /* Place from the left and let the title get clipped */
 
2402
 
 
2403
                if (sw->scale.show_value == XmNEAR_BORDER) {
 
2404
                    valueBox.y = 0;
 
2405
                    labelBox.y = valueBox.y + valueBox.height;
 
2406
                } else { /* NEAR_SLIDER or NONE */
 
2407
                    labelBox.y = 0;
 
2408
                    valueBox.y = labelBox.y + labelBox.height;
 
2409
                }
 
2410
 
 
2411
                scrollBox.y = valueBox.y + valueBox.height;
 
2412
                
 
2413
                titleBox.y = scrollBox.y + scrollBox.height;
 
2414
        }
 
2415
        else if ((tdiff += ValueTroughHeight(sw)) >= 0)
 
2416
        {
 
2417
                /*
 
2418
                 * The title is outside the window, and the labels are
 
2419
                 * allowed overwrite (occlude) the value display region
 
2420
                 */
 
2421
                titleBox.y = XtHeight(sw);
 
2422
                scrollBox.y = titleBox.y - scrollBox.height;
 
2423
 
 
2424
                if (sw->scale.show_value == XmNEAR_BORDER) {
 
2425
                    valueBox.y = 0;
 
2426
                    labelBox.y = scrollBox.y - labelBox.height;
 
2427
                } else { /* NEAR_SLIDER or NONE */
 
2428
                    valueBox.y = scrollBox.y - valueBox.height;
 
2429
                    labelBox.y = 0;
 
2430
                }  
 
2431
        }
 
2432
        else if ((tdiff += MaxLabelHeight(sw)) >= 0)
 
2433
        {
 
2434
                /*
 
2435
                 * The title is outside the window, the value trough is 
 
2436
                 * completely coincident with the label region, and the
 
2437
                 * labels are clipped from the left
 
2438
                 */
 
2439
                titleBox.y = XtHeight(sw);
 
2440
                scrollBox.y = titleBox.y - scrollBox.height;
 
2441
                labelBox.y = scrollBox.y - labelBox.height;
 
2442
                valueBox.y = scrollBox.y - valueBox.height;
 
2443
        }
 
2444
        else
 
2445
        {
 
2446
                /*
 
2447
                 * Just center the scrollbar in the available space.
 
2448
                 */
 
2449
                titleBox.y = XtHeight(sw);
 
2450
                valueBox.y = titleBox.y;
 
2451
                labelBox.y = valueBox.y;
 
2452
                scrollBox.y = (XtHeight(sw) - ScrollHeight(sw)) / 2;
 
2453
        }
 
2454
 
 
2455
        if (diff_w >= 0)
 
2456
        {
 
2457
                scrollBox.x = MajorLeadPad(sw);
 
2458
                scrollBox.width = ScrollWidth(sw);
 
2459
        }
 
2460
        else
 
2461
        {
 
2462
                Dimension sb_min, avail, lp, tp;
 
2463
                XmScrollBarWidget sb = (XmScrollBarWidget)
 
2464
                        (sw->composite.children[1]);
 
2465
 
 
2466
                sb_min = (2 * sb->primitive.highlight_thickness)
 
2467
                        + (4 * sb->primitive.shadow_thickness)
 
2468
                        + SLIDER_SIZE( sw);
 
2469
                
 
2470
                lp = MajorLeadPad(sw);
 
2471
                tp = MajorTrailPad(sw);
 
2472
                avail = XtWidth(sw) - lp - tp;
 
2473
 
 
2474
                if (avail < sb_min)
 
2475
                {
 
2476
                        scrollBox.width = sb_min;
 
2477
                        scrollBox.x = (XtWidth(sw) - sb_min) / 2;
 
2478
                }
 
2479
                else
 
2480
                {
 
2481
                        scrollBox.width = avail;
 
2482
                        scrollBox.x = lp;
 
2483
                }
 
2484
        }
 
2485
 
 
2486
        if (LayoutIsRtoLM(sw))
 
2487
        {
 
2488
           titleBox.x = ScrollWidth(sw) - TitleWidth(sw);
 
2489
           XmeConfigureObject(sw->composite.children[0],
 
2490
                              titleBox.x, titleBox.y,
 
2491
                              (sw->composite.children[0])->core.width,
 
2492
                              (sw->composite.children[0])->core.height,
 
2493
                              (sw->composite.children[0])->core.border_width);
 
2494
        }
 
2495
        else
 
2496
          if (instigator != sw->composite.children[0])
 
2497
            XmeConfigureObject(sw->composite.children[0], 0, titleBox.y,
 
2498
                               (sw->composite.children[0])->core.width,
 
2499
                               (sw->composite.children[0])->core.height,
 
2500
                               (sw->composite.children[0])->core.border_width);
 
2501
          else {
 
2502
            sw->composite.children[0]->core.x = 0 ;
 
2503
            sw->composite.children[0]->core.y = titleBox.y ;
 
2504
          }
 
2505
        
 
2506
        
 
2507
        if (instigator != sw->composite.children[1])
 
2508
            XmeConfigureObject(sw->composite.children[1],
 
2509
                               scrollBox.x, scrollBox.y,
 
2510
                               scrollBox.width, scrollBox.height, 0);
 
2511
        else {
 
2512
            sw->composite.children[1]->core.x = scrollBox.x ;
 
2513
            sw->composite.children[1]->core.y = scrollBox.y ;
 
2514
            sw->composite.children[1]->core.width = scrollBox.width ;
 
2515
            sw->composite.children[1]->core.height = scrollBox.height ;
 
2516
            sw->composite.children[1]->core.border_width = 0 ;
 
2517
        }
 
2518
        
 
2519
        SetScrollBarData(sw);
 
2520
                
 
2521
        LayoutHorizontalLabels(sw, &scrollBox, &labelBox, instigator);
 
2522
}
 
2523
 
 
2524
static void 
 
2525
LayoutVerticalLabels(
 
2526
                     XmScaleWidget sw,
 
2527
                     XRectangle *scrollBox,
 
2528
                     XRectangle *labelBox,
 
2529
                     Widget instigator )
 
2530
{
 
2531
        Dimension first_tic_dim, last_tic_dim;
 
2532
        XmScrollBarWidget sb = (XmScrollBarWidget)
 
2533
                (sw->composite.children[1]);
 
2534
        Widget w, first_tic;
 
2535
        int i;
 
2536
        float tmp, tic_interval;
 
2537
        Position x, x1, y;
 
2538
        Cardinal num_managed ;
 
2539
        
 
2540
        num_managed = NumManaged(sw, &first_tic, NULL);
 
2541
 
 
2542
        x1 = labelBox->x + labelBox->width;
 
2543
 
 
2544
        if (num_managed > 3)
 
2545
        {
 
2546
                first_tic_dim = scrollBox->y + LeadYTic(sb, sw);
 
2547
                last_tic_dim = (scrollBox->y + sb->core.height) - 
 
2548
                    TrailYTic(sb, sw);
 
2549
                tic_interval = (float)(last_tic_dim - first_tic_dim)
 
2550
                        / (num_managed - 3);
 
2551
 
 
2552
                for (i = 2, tmp = first_tic_dim;
 
2553
                        i < sw->composite.num_children;
 
2554
                        i++)
 
2555
                {
 
2556
                        w = sw->composite.children[i];
 
2557
                        if (!XtIsManaged(w) ||
 
2558
                            ((Object)w)->object.being_destroyed) continue ;
 
2559
 
 
2560
                        y = (int) tmp - (TotalHeight(w) / 2);
 
2561
                        if (LayoutIsRtoLM(sw))
 
2562
                          x = labelBox->x;
 
2563
                        else
 
2564
                          x = x1 - TotalWidth(w);
 
2565
                        if (instigator != w)
 
2566
                            XmeConfigureObject(w, x, y,
 
2567
                                               w->core.width, w->core.height,
 
2568
                                               w->core.border_width);
 
2569
                        else {
 
2570
                            w->core.x = x ;
 
2571
                            w->core.y = y ;
 
2572
                        }
 
2573
 
 
2574
                        tmp += tic_interval ;
 
2575
                }
 
2576
        }
 
2577
        else if (num_managed == 3)
 
2578
        {
 
2579
                w = first_tic;
 
2580
                if (XtIsManaged(w) &&
 
2581
                    !((Object)w)->object.being_destroyed) {
 
2582
 
 
2583
                    x = x1 - TotalWidth(w);
 
2584
                    tmp = (sb->scrollBar.slider_area_height - 
 
2585
                           TotalHeight(w)) / 2;
 
2586
                    y = scrollBox->y + sb->scrollBar.slider_area_y 
 
2587
                        + (int) tmp;
 
2588
                    if (instigator != w)
 
2589
                        XmeConfigureObject(w, x, y, w->core.width, 
 
2590
                                           w->core.height,
 
2591
                                           w->core.border_width);
 
2592
                    else {
 
2593
                        w->core.x = x ;
 
2594
                        w->core.y = y ;
 
2595
                    }
 
2596
                }
 
2597
        }
 
2598
}
 
2599
 
 
2600
static void 
 
2601
LayoutVerticalScale(
 
2602
        XmScaleWidget sw,
 
2603
        XtWidgetGeometry * desired,
 
2604
        Widget instigator)
 
2605
{
 
2606
        int diff_w, diff_h, tdiff;
 
2607
        XRectangle labelBox, valueBox, scrollBox, titleBox;
 
2608
 
 
2609
        diff_w = XtWidth(sw) - desired->width;
 
2610
        diff_h = XtHeight(sw) - desired->height;
 
2611
 
 
2612
        titleBox.width = TitleWidth(sw);
 
2613
        scrollBox.width = ScrollWidth(sw);
 
2614
        valueBox.width = ValueTroughWidth(sw);
 
2615
        labelBox.width = MaxLabelWidth(sw);
 
2616
 
 
2617
        /* Figure out all of the x locations */
 
2618
        if (diff_w >= 0)
 
2619
        {
 
2620
          if (LayoutIsRtoLM(sw)) {
 
2621
            /* 
 
2622
             * Place the title, scrollbar, and value from the left 
 
2623
             */
 
2624
            titleBox.x = 0;
 
2625
            scrollBox.x = titleBox.x + titleBox.width;
 
2626
 
 
2627
            if (sw->scale.show_value == XmNEAR_BORDER) {
 
2628
              valueBox.x = XtWidth(sw) - valueBox.width;
 
2629
              labelBox.x = scrollBox.x + scrollBox.width;
 
2630
            } else { /* NEAR_SLIDER or NONE */
 
2631
              valueBox.x = scrollBox.x + scrollBox.width;
 
2632
              labelBox.x = XtWidth(sw) - labelBox.width;
 
2633
            }
 
2634
          } else {
 
2635
            /* 
 
2636
             * We place the title, scrollbar, and value from the right
 
2637
             */
 
2638
            titleBox.x = XtWidth(sw) - titleBox.width;
 
2639
            scrollBox.x = titleBox.x - scrollBox.width;
 
2640
 
 
2641
            if (sw->scale.show_value == XmNEAR_BORDER) {
 
2642
              valueBox.x = 0;
 
2643
              labelBox.x = scrollBox.x - labelBox.width;
 
2644
            } else { /* NEAR_SLIDER or NONE */
 
2645
              valueBox.x = scrollBox.x - valueBox.width;
 
2646
              labelBox.x = 0;
 
2647
            }
 
2648
          }
 
2649
        }
 
2650
        else if ((tdiff = diff_w + TitleWidth(sw)) >= 0)
 
2651
        {
 
2652
          if (LayoutIsRtoLM(sw)) {
 
2653
            /* Place from the right and let the title get clipped */
 
2654
            if (sw->scale.show_value == XmNEAR_BORDER) {
 
2655
              valueBox.x = XtWidth(sw) - labelBox.width;
 
2656
              labelBox.x = valueBox.x - valueBox.width;
 
2657
              scrollBox.x = labelBox.x - scrollBox.width;
 
2658
            } else { /* NEAR_SLIDER or NONE */
 
2659
              labelBox.x = XtWidth(sw) - labelBox.width;
 
2660
              valueBox.x = labelBox.x - valueBox.width;
 
2661
              scrollBox.x = valueBox.x - scrollBox.width;
 
2662
            }
 
2663
            
 
2664
            titleBox.x = scrollBox.x - titleBox.width;
 
2665
          } else {
 
2666
            /* Place from the left and let the title get clipped */
 
2667
            if (sw->scale.show_value == XmNEAR_BORDER) {
 
2668
                valueBox.x = 0;
 
2669
                labelBox.x = valueBox.x + valueBox.width;
 
2670
                scrollBox.x = labelBox.x + labelBox.width;
 
2671
            } else { /* NEAR_SLIDER or NONE */
 
2672
                labelBox.x = 0;
 
2673
                valueBox.x = labelBox.x + labelBox.width;
 
2674
                scrollBox.x = valueBox.x + valueBox.width;
 
2675
            }
 
2676
            
 
2677
            titleBox.x = scrollBox.x + scrollBox.width;
 
2678
          }
 
2679
        }
 
2680
        else if ((tdiff += ValueTroughWidth(sw)) >= 0)
 
2681
        {
 
2682
                /*
 
2683
                 * The title is outside the window, and the labels are
 
2684
                 * allowed overwrite (occlude) the value display region
 
2685
                 */
 
2686
                if (LayoutIsRtoLM(sw))
 
2687
                {
 
2688
                   titleBox.x = -titleBox.width;
 
2689
                   scrollBox.x = 0;
 
2690
                   if (sw->scale.show_value == XmNEAR_BORDER) {
 
2691
                     labelBox.x = scrollBox.x + scrollBox.width;
 
2692
                     valueBox.x = XtWidth(sw) - valueBox.width;
 
2693
                   } else { /* NEAR_SLIDER or NONE */
 
2694
                     valueBox.x = scrollBox.x + scrollBox.width;
 
2695
                     labelBox.x = XtWidth(sw) - labelBox.width;
 
2696
                   }
 
2697
                 } else {
 
2698
                   titleBox.x = XtWidth(sw);
 
2699
                   scrollBox.x = titleBox.x - scrollBox.width;
 
2700
                   
 
2701
                   if (sw->scale.show_value == XmNEAR_BORDER) {
 
2702
                     labelBox.x = scrollBox.x - labelBox.width;
 
2703
                     valueBox.x = 0;
 
2704
                   } else { /* NEAR_SLIDER or NONE */
 
2705
                     valueBox.x = scrollBox.x - valueBox.width;
 
2706
                     labelBox.x = 0;
 
2707
                   }
 
2708
                 }
 
2709
        }
 
2710
        else if ((tdiff += MaxLabelWidth(sw)) >= 0)
 
2711
        {
 
2712
                /*
 
2713
                 * The title is outside the window, the value trough is 
 
2714
                 * completely coincident with the label region, and the
 
2715
                 * labels are clipped from the left
 
2716
                 */
 
2717
                titleBox.x = XtWidth(sw);
 
2718
                scrollBox.x = titleBox.x - scrollBox.width;
 
2719
                valueBox.x = scrollBox.x - valueBox.width;
 
2720
                labelBox.x = scrollBox.x - labelBox.width;
 
2721
                if (LayoutIsRtoLM(sw))
 
2722
                {
 
2723
                   titleBox.x = -titleBox.width;
 
2724
                   scrollBox.x = 0;
 
2725
                   valueBox.x = scrollBox.x + scrollBox.width;
 
2726
                   labelBox.x = scrollBox.x + scrollBox.width;
 
2727
                }
 
2728
        }
 
2729
        else
 
2730
            {
 
2731
                /*
 
2732
                 * Just center the scrollbar in the available space.
 
2733
                 */
 
2734
                titleBox.x = XtWidth(sw);
 
2735
                valueBox.x = titleBox.x;
 
2736
                labelBox.x = valueBox.x;
 
2737
                scrollBox.x = (XtWidth(sw) - ScrollWidth(sw)) / 2;
 
2738
            }
 
2739
 
 
2740
        if (diff_h >= 0)
 
2741
        {
 
2742
                scrollBox.y = MajorLeadPad(sw);
 
2743
                scrollBox.height = ScrollHeight(sw);
 
2744
        }
 
2745
        else
 
2746
        {
 
2747
                Dimension sb_min, avail, lp, tp;
 
2748
                XmScrollBarWidget sb = (XmScrollBarWidget)
 
2749
                        (sw->composite.children[1]);
 
2750
 
 
2751
                sb_min = (2 * sb->primitive.highlight_thickness)
 
2752
                        + (4 * sb->primitive.shadow_thickness)
 
2753
                        + SLIDER_SIZE( sw);
 
2754
                
 
2755
                lp = MajorLeadPad(sw);
 
2756
                tp = MajorTrailPad(sw);
 
2757
                avail = XtHeight(sw) - lp - tp;
 
2758
 
 
2759
                if (avail < sb_min)
 
2760
                {
 
2761
                        scrollBox.height = sb_min;
 
2762
                        scrollBox.y = (XtHeight(sw) - sb_min) / 2;
 
2763
                }
 
2764
                else
 
2765
                {
 
2766
                        scrollBox.height = avail;
 
2767
                        scrollBox.y = lp;
 
2768
                }
 
2769
        }
 
2770
 
 
2771
        if (instigator != sw->composite.children[0])
 
2772
            XmeConfigureObject(sw->composite.children[0],
 
2773
                               titleBox.x, 0,
 
2774
                               (sw->composite.children[0])->core.width,
 
2775
                               (sw->composite.children[0])->core.height,
 
2776
                               (sw->composite.children[0])->core.border_width);
 
2777
        else {
 
2778
            sw->composite.children[0]->core.x = titleBox.x ;
 
2779
            sw->composite.children[0]->core.y = 0 ;
 
2780
        }
 
2781
            
 
2782
        if (instigator != sw->composite.children[1])
 
2783
            XmeConfigureObject(sw->composite.children[1],
 
2784
                               scrollBox.x, scrollBox.y,
 
2785
                               scrollBox.width, scrollBox.height, 0);
 
2786
        else {
 
2787
            sw->composite.children[1]->core.x = scrollBox.x ;
 
2788
            sw->composite.children[1]->core.y = scrollBox.y ;
 
2789
            sw->composite.children[1]->core.width = scrollBox.width ;
 
2790
            sw->composite.children[1]->core.height = scrollBox.height ;
 
2791
            sw->composite.children[1]->core.border_width = 0 ;
 
2792
        }
 
2793
         
 
2794
        SetScrollBarData(sw);
 
2795
        
 
2796
        LayoutVerticalLabels(sw, &scrollBox, &labelBox, instigator);
 
2797
}
 
2798
 
 
2799
 
 
2800
 
 
2801
 
 
2802
/************************************************************************/
 
2803
static void 
 
2804
GetValueString(
 
2805
        XmScaleWidget sw,
 
2806
        int value,
 
2807
        String buffer)
 
2808
{
 
2809
    register int i;
 
2810
    int  diff, dec_point_size;
 
2811
    struct lconv *loc_values;
 
2812
        
 
2813
    if (sw->scale.decimal_points > 0) {
 
2814
      /* Add one to decimal points to get leading zero, since
 
2815
         only US sometimes skips this zero, not other countries */
 
2816
      sprintf (buffer,"%.*d", sw->scale.decimal_points+1, value);
 
2817
 
 
2818
      diff = strlen(buffer) - sw->scale.decimal_points;
 
2819
      loc_values = localeconv();
 
2820
      dec_point_size = strlen(loc_values->decimal_point);
 
2821
 
 
2822
      for (i = strlen(buffer); i >= diff; i--)
 
2823
        buffer[i+dec_point_size] = buffer[i];
 
2824
      
 
2825
      for (i=0; i<dec_point_size; i++)
 
2826
        buffer[diff+i] = loc_values->decimal_point[i];
 
2827
 
 
2828
    } else
 
2829
      sprintf (buffer,"%d", value);
 
2830
}
 
2831
 
 
2832
 
 
2833
 
 
2834
/************************************************************************
 
2835
 *
 
2836
 *  ShowValue
 
2837
 *     Display or erase the slider value.
 
2838
 *
 
2839
 ************************************************************************/
 
2840
static void 
 
2841
ShowValue(
 
2842
        XmScaleWidget sw)
 
2843
{
 
2844
#if USE_XFT
 
2845
    Dimension x, y, width, height;
 
2846
#else
 
2847
    int x, y, width, height;
 
2848
#endif
 
2849
    XCharStruct width_return;
 
2850
    char buffer[256];
 
2851
    int direction, descent;
 
2852
    XmScrollBarWidget scrollbar;
 
2853
    Region value_region = sw->scale.value_region;
 
2854
    XRectangle value_rect;
 
2855
    XmString tmp_str;
 
2856
    
 
2857
    if (!XtIsRealized((Widget)sw)) return;
 
2858
    
 
2859
    x = sw->scale.show_value_x;
 
2860
    y = sw->scale.show_value_y;
 
2861
    width = sw->scale.show_value_width;
 
2862
    height = sw->scale.show_value_height;
 
2863
    
 
2864
    if (!sw->scale.show_value) { /* turn off the value display */
 
2865
        
 
2866
        if (width) { /* We were displaying, so we must clear it */
 
2867
            
 
2868
            XClearArea (XtDisplay (sw), XtWindow (sw), x, y, width, 
 
2869
                        height, FALSE);
 
2870
            value_rect.x = x;
 
2871
            value_rect.y = y;
 
2872
            value_rect.width = width;
 
2873
            value_rect.height = height;
 
2874
            XIntersectRegion(null_region, value_region, value_region);
 
2875
            XUnionRectWithRegion(&value_rect, value_region, value_region);
 
2876
            XmeRedisplayGadgets( (Widget) sw, NULL, value_region);
 
2877
        }
 
2878
        sw->scale.show_value_width = 0;
 
2879
        return;
 
2880
    }
 
2881
    
 
2882
    /*
 
2883
     * Time for the real work.
 
2884
     */
 
2885
    
 
2886
    if (width)  {
 
2887
        /* Clear the old one */
 
2888
        value_rect.x = x;
 
2889
        value_rect.y = y;
 
2890
        value_rect.width = width;
 
2891
        value_rect.height = height;
 
2892
        XIntersectRegion(null_region, value_region, value_region);
 
2893
        XClearArea(XtDisplay(sw), XtWindow(sw), x, y, width, height, FALSE);
 
2894
        XUnionRectWithRegion(&value_rect, value_region, value_region);
 
2895
        XmeRedisplayGadgets( (Widget) sw, NULL, value_region);
 
2896
    }
 
2897
    
 
2898
    /*  Get a string representation of the new value  */
 
2899
    
 
2900
    GetValueString(sw, sw->scale.value, buffer);
 
2901
 
 
2902
    /*  Calculate the x, y, width, and height of the string to display  */
 
2903
    
 
2904
#if USE_XFT
 
2905
    XmStringExtent(sw->scale.font_list, tmp_str = XmStringCreateSimple(buffer),
 
2906
                  &width, &height);
 
2907
    XmStringFree(tmp_str);
 
2908
    sw->scale.show_value_width = width;
 
2909
    sw->scale.show_value_height = height;
 
2910
#else
 
2911
    XTextExtents (sw->scale.font_struct, buffer, strlen(buffer),
 
2912
                  &direction, &height, &descent, &width_return);
 
2913
    width = width_return.rbearing - width_return.lbearing;
 
2914
    sw->scale.show_value_width = width;
 
2915
    sw->scale.show_value_height = height + descent;
 
2916
#endif
 
2917
 
 
2918
    scrollbar = (XmScrollBarWidget) sw->composite.children[1];
 
2919
    
 
2920
    if (sw->scale.orientation == XmHORIZONTAL) {
 
2921
#if USE_XFT
 
2922
        x = scrollbar->core.x
 
2923
            + scrollbar->scrollBar.slider_x;
 
2924
            + scrollbar->scrollBar.slider_width / 2;
 
2925
        if (sw->scale.show_value == XmNEAR_BORDER) 
 
2926
            /*tmp: should store the max */ 
 
2927
            y = scrollbar->core.y - MaxLabelHeight(sw) - height - 3;
 
2928
        else /* NEAR_SLIDER or NONE */ 
 
2929
            y = scrollbar->core.y - height - 3;  
 
2930
#else
 
2931
        x = scrollbar->core.x
 
2932
            + scrollbar->scrollBar.slider_x
 
2933
            + ((sw->scale.sliding_mode)?
 
2934
                scrollbar->scrollBar.slider_width: 0)
 
2935
                - (width_return.rbearing - SLIDER_SIZE( sw)) / 2;
 
2936
        if (sw->scale.show_value == XmNEAR_BORDER) 
 
2937
            /*tmp: should store the max */ 
 
2938
            y = scrollbar->core.y - MaxLabelHeight(sw) - 3;
 
2939
        else /* NEAR_SLIDER or NONE */ 
 
2940
            y = scrollbar->core.y - 3;  
 
2941
#endif
 
2942
    } else {
 
2943
        if (sw->scale.show_value == XmNEAR_BORDER) {
 
2944
            if (LayoutIsRtoLM(sw))
 
2945
                x = scrollbar->core.x + scrollbar->core.width + 
 
2946
                    MaxLabelWidth(sw);
 
2947
            else
 
2948
#if USE_XFT
 
2949
                x = scrollbar->core.x - MaxLabelWidth(sw) -
 
2950
                    sw->scale.show_value_width - SCALE_VALUE_MARGIN;
 
2951
#else
 
2952
                x = scrollbar->core.x - MaxLabelWidth(sw) - 
 
2953
                    width_return.rbearing - SCALE_VALUE_MARGIN;
 
2954
#endif
 
2955
        } else { /* NEAR_SLIDER or NONE */
 
2956
            if (LayoutIsRtoLM(sw))
 
2957
                x = scrollbar->core.x + scrollbar->core.width;
 
2958
            else
 
2959
#if USE_XFT
 
2960
                x = scrollbar->core.x - sw->scale.show_value_width;
 
2961
#else
 
2962
                x = scrollbar->core.x - width_return.rbearing;
 
2963
#endif
 
2964
        }
 
2965
#if USE_XFT
 
2966
        y = scrollbar->core.y + scrollbar->scrollBar.slider_y
 
2967
            + SLIDER_SIZE(sw)/2 - height/2;
 
2968
#else
 
2969
        y = scrollbar->core.y + scrollbar->scrollBar.slider_y
 
2970
            + SLIDER_SIZE(sw) + ((height - SLIDER_SIZE( sw)) / 2) - 3;
 
2971
#endif
 
2972
    }
 
2973
    
 
2974
#ifndef USE_XFT
 
2975
    sw->scale.show_value_x = x + width_return.lbearing;
 
2976
#endif
 
2977
    sw->scale.show_value_y = y - height + 1;
 
2978
    
 
2979
    
 
2980
    /*  Display the string  */
 
2981
    XSetClipMask(XtDisplay(sw), sw->scale.foreground_GC, None);
 
2982
#if USE_XFT
 
2983
    XClearWindow(XtDisplay(sw), XtWindow(sw));
 
2984
    XmStringDraw(XtDisplay(sw), XtWindow(sw), sw->scale.font_list,
 
2985
                    tmp_str = XmStringCreateSimple(buffer),
 
2986
                    sw->scale.foreground_GC,
 
2987
                    x, y, width, XmALIGNMENT_CENTER,
 
2988
                    sw->manager.string_direction,
 
2989
                    NULL);
 
2990
    XmStringFree(tmp_str);
 
2991
#else
 
2992
    XDrawImageString (XtDisplay(sw), XtWindow(sw),
 
2993
                 sw->scale.foreground_GC, x, y, buffer, strlen(buffer));
 
2994
#endif
 
2995
}
 
2996
 
 
2997
 
 
2998
/*********************************************************************
 
2999
 *
 
3000
 * CalcScrollBarData
 
3001
 * Figure out the scale derived attributes of the scrollbar child.
 
3002
 *
 
3003
 *********************************************************************/
 
3004
static void 
 
3005
CalcScrollBarData(
 
3006
        XmScaleWidget sw,
 
3007
        int *pvalue,
 
3008
        int *pslider_size,
 
3009
        int *pincrement,
 
3010
        int *ppage )
 
3011
{
 
3012
    int slider_size, increment, page, value ;
 
3013
    Dimension scrollbar_size;
 
3014
    float sb_value, tmp;
 
3015
    XmScrollBarWidget scrollbar = 
 
3016
            (XmScrollBarWidget) sw->composite.children[1];
 
3017
    register int ht = scrollbar->primitive.highlight_thickness;
 
3018
    register int st = scrollbar->primitive.shadow_thickness;
 
3019
    int size;
 
3020
    
 
3021
        /*  Adjust the slider size to take SLIDER_SIZE area.    */
 
3022
        /*  Adjust value to be in the bounds of the scrollbar.  */
 
3023
 
 
3024
    if (scrollbar->scrollBar.orientation == XmHORIZONTAL)
 
3025
        scrollbar_size = scrollbar->scrollBar.slider_area_width + 2 *(ht +st);
 
3026
    else
 
3027
        scrollbar_size = scrollbar->scrollBar.slider_area_height + 2 *(ht +st);
 
3028
 
 
3029
    size = scrollbar_size - 2 * (sw->scale.highlight_thickness
 
3030
                 + sw->manager.shadow_thickness) ;
 
3031
 
 
3032
    /* prevent divide by zero error and integer rollover */
 
3033
    if (size <= 0)
 
3034
                scrollbar_size = 1;
 
3035
        else
 
3036
            /* this looks suspicious to me, but it is bc to let it in */
 
3037
                scrollbar_size -= 2 * (sw->scale.highlight_thickness
 
3038
                        + sw->manager.shadow_thickness);
 
3039
 
 
3040
    slider_size = (SCROLLBAR_MAX / scrollbar_size) * SLIDER_SIZE( sw);
 
3041
 
 
3042
    /*
 
3043
     * Now error check our arithmetic
 
3044
     */
 
3045
    if (slider_size < 0)
 
3046
        slider_size = SCROLLBAR_MAX;   
 
3047
    else if (slider_size < 1)
 
3048
        slider_size = 1;
 
3049
    else if (slider_size > SCROLLBAR_MAX)
 
3050
        slider_size = SCROLLBAR_MAX;
 
3051
 
 
3052
    sb_value = (float) (sw->scale.value - sw->scale.minimum) / 
 
3053
                (float) (sw->scale.maximum - sw->scale.minimum);
 
3054
    sb_value = sb_value * (float) (SCROLLBAR_MAX - slider_size);
 
3055
        
 
3056
    value = (int) sb_value;
 
3057
 
 
3058
    ASSIGN_MIN(value, SCROLLBAR_MAX - slider_size);
 
3059
    ASSIGN_MAX(value, 0);
 
3060
 
 
3061
    /* Set up the increment processing correctly */
 
3062
 
 
3063
    tmp = (float) SCROLLBAR_MAX - (float) slider_size;
 
3064
 
 
3065
    increment = (int) ((tmp / 
 
3066
                (float) (sw->scale.maximum - sw->scale.minimum)) + 0.5);
 
3067
    ASSIGN_MAX(increment, 1);
 
3068
 
 
3069
    page = sw->scale.scale_multiple * (increment);
 
3070
    ASSIGN_MAX(page, 1);
 
3071
 
 
3072
    *pvalue = value ;
 
3073
    *pslider_size = slider_size ;
 
3074
    *pincrement = increment ;
 
3075
    *ppage = page ;
 
3076
}
 
3077
 
 
3078
 
 
3079
/*********************************************************************
 
3080
 *
 
3081
 * SetScrollBarData
 
3082
 *   Call CalcScrollBarData and do a setvalues on the SB.
 
3083
 *
 
3084
 *********************************************************************/
 
3085
static void 
 
3086
SetScrollBarData(
 
3087
        XmScaleWidget sw)
 
3088
{
 
3089
    int slider_size, increment, page, value ;
 
3090
    Arg args[5] ;
 
3091
    Cardinal n = 0 ;
 
3092
    XmScrollBarWidget scrollbar = 
 
3093
            (XmScrollBarWidget) sw->composite.children[1];
 
3094
    
 
3095
    CalcScrollBarData(sw, &value, &slider_size, &increment, &page);
 
3096
 
 
3097
    SET(XmNvalue, value);               
 
3098
    SET(XmNsliderSize, slider_size);    
 
3099
    SET(XmNincrement, increment);               
 
3100
    SET(XmNpageIncrement, page);                
 
3101
 
 
3102
    XtSetValues ((Widget)scrollbar, args, n);
 
3103
}
 
3104
 
 
3105
 
 
3106
 
 
3107
 
 
3108
/*********************************************************************
 
3109
 *
 
3110
 *  ValueChanged
 
3111
 *      Callback procedure invoked from the scrollbars value being changed.
 
3112
 *
 
3113
 *********************************************************************/
 
3114
/*ARGSUSED*/
 
3115
static void 
 
3116
ValueChanged(
 
3117
        Widget wid,
 
3118
        XtPointer closure,      /* unused */
 
3119
        XtPointer call_data )
 
3120
{
 
3121
    XmScaleWidget sw = (XmScaleWidget) XtParent (wid);
 
3122
    XmScrollBarCallbackStruct * scroll_callback =
 
3123
        (XmScrollBarCallbackStruct *) call_data; 
 
3124
    XmScaleCallbackStruct scale_callback;
 
3125
    float sb_value;
 
3126
    XmScrollBarWidget sb = (XmScrollBarWidget)(sw->composite.children[1]);
 
3127
 
 
3128
    sb_value = (float) scroll_callback->value 
 
3129
             / (float) (SCROLLBAR_MAX - sb->scrollBar.slider_size);
 
3130
    sb_value = (sb_value * (float) (sw->scale.maximum - sw->scale.minimum))
 
3131
               + (float) sw->scale.minimum;
 
3132
    
 
3133
    /* Set up the round off correctly */
 
3134
    if (sb_value < 0.0) sb_value -= 0.5;
 
3135
    else if (sb_value > 0.0) sb_value += 0.5;
 
3136
    
 
3137
    sw->scale.value = (int) sb_value;
 
3138
 
 
3139
    ShowValue (sw);
 
3140
    
 
3141
    scale_callback.event = scroll_callback->event;
 
3142
    scale_callback.reason = scroll_callback->reason;
 
3143
    scale_callback.value = sw->scale.value;
 
3144
    
 
3145
    if (scale_callback.reason == XmCR_DRAG)
 
3146
        XtCallCallbackList((Widget) sw, sw->scale.drag_callback,
 
3147
                           &scale_callback);
 
3148
    else /* value changed and to_top and to_bottom */
 
3149
        {
 
3150
            scale_callback.reason = XmCR_VALUE_CHANGED;
 
3151
            XtCallCallbackList((Widget) sw,
 
3152
                               sw->scale.value_changed_callback, 
 
3153
                               &scale_callback);
 
3154
        }
 
3155
}
 
3156
 
 
3157
 
 
3158
 
 
3159
/************************************************************************
 
3160
 *
 
3161
 * StartDrag:
 
3162
 * This routine is performed by the initiator when a drag starts 
 
3163
 * (in this case, when mouse button 2 was pressed).  It starts 
 
3164
 * the drag processing, and establishes a drag context
 
3165
 *
 
3166
 ************************************************************************/
 
3167
/*ARGSUSED*/
 
3168
static void 
 
3169
StartDrag (Widget  w, 
 
3170
           XtPointer data,      /* unused */
 
3171
           XEvent  *event, 
 
3172
           Boolean *cont)       /* unused */
 
3173
{
 
3174
   Widget drag_icon;
 
3175
   Arg             args[10];
 
3176
   Cardinal        n;
 
3177
   XmScaleWidget sw = (XmScaleWidget) w ;
 
3178
   XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay(w));
 
3179
 
 
3180
   /* CDE - allow user to not drag labels and label subclasses
 
3181
      also,  disable drag if enable_btn1_transfer is set to
 
3182
      BUTTON2_ADJUST and the trigger was button2 */
 
3183
   if (! dpy -> display.enable_unselectable_drag ||
 
3184
       (dpy -> display.enable_btn1_transfer == XmBUTTON2_ADJUST &&
 
3185
        event && event -> xany.type == ButtonPress &&
 
3186
        event -> xbutton.button == 2)) return;
 
3187
 
 
3188
   /* first check that the click is OK: button 2 and in the value label */
 
3189
   if ((!sw->scale.show_value) ||
 
3190
       (event->xbutton.button != Button2) ||
 
3191
       ((event->xbutton.x < sw->scale.show_value_x) ||
 
3192
        (event->xbutton.y < sw->scale.show_value_y) ||
 
3193
        (event->xbutton.x > sw->scale.show_value_x + 
 
3194
         sw->scale.show_value_width) ||
 
3195
        (event->xbutton.y > sw->scale.show_value_y +
 
3196
         sw->scale.show_value_height))) return ;
 
3197
   
 
3198
   drag_icon = XmeGetTextualDragIcon(w);
 
3199
 
 
3200
   n = 0;
 
3201
   XtSetArg(args[n], XmNcursorBackground, sw->core.background_pixel);  n++;
 
3202
   XtSetArg(args[n], XmNcursorForeground, sw->manager.foreground);  n++;
 
3203
   XtSetArg(args[n], XmNsourceCursorIcon, drag_icon);  n++; 
 
3204
   XtSetArg(args[n], XmNdragOperations, XmDROP_COPY); n++ ;
 
3205
   (void) XmeDragSource(w, NULL, event, args, n);
 
3206
}
 
3207
 
 
3208
 
 
3209
/************************************************************************
 
3210
 *
 
3211
 * DragConvertProc:
 
3212
 * This routine returns the value of the scale, 
 
3213
 * converted into compound text. 
 
3214
 *
 
3215
 ************************************************************************/
 
3216
/*ARGSUSED*/
 
3217
static void
 
3218
DragConvertCallback (Widget w, 
 
3219
                     XtPointer client_data, /* unused */
 
3220
                     XmConvertCallbackStruct *cs)
 
3221
{
 
3222
   enum { XmACOMPOUND_TEXT, XmATARGETS, XmA_MOTIF_EXPORT_TARGETS,
 
3223
          XmA_MOTIF_CLIPBOARD_TARGETS, XmAUTF8_STRING, NUM_ATOMS };
 
3224
   static char *atom_names[] = { 
 
3225
     XmSCOMPOUND_TEXT, XmSTARGETS, XmS_MOTIF_EXPORT_TARGETS,
 
3226
     XmS_MOTIF_CLIPBOARD_TARGETS, XmSUTF8_STRING };
 
3227
 
 
3228
   char          tmpstring[100];
 
3229
   char         *strlist;
 
3230
   char         *passtext;
 
3231
   XmScaleWidget sw = (XmScaleWidget) w;
 
3232
   Atom          atoms[XtNumber(atom_names)];
 
3233
   XTextProperty tp;
 
3234
   Atom          type = None ;
 
3235
   XtPointer     value = NULL ;
 
3236
   unsigned long size = 0 ;
 
3237
   int           format = 8 ;
 
3238
      
 
3239
   assert(XtNumber(atom_names) == NUM_ATOMS);
 
3240
   XInternAtoms(XtDisplay(w), atom_names, XtNumber(atom_names), False, atoms);
 
3241
 
 
3242
   /* Begin fixing the bug OSF 4846 */
 
3243
   /* get the value of the scale and convert it to compound text */
 
3244
   GetValueString(sw, sw->scale.value, tmpstring);
 
3245
 
 
3246
   if (cs -> target == atoms[XmATARGETS] ||
 
3247
       cs -> target == atoms[XmA_MOTIF_EXPORT_TARGETS] ||
 
3248
       cs -> target == atoms[XmA_MOTIF_CLIPBOARD_TARGETS]) {
 
3249
     int count = 0;
 
3250
     Atom *targs;
 
3251
 
 
3252
     if (cs -> target == atoms[XmATARGETS]) 
 
3253
       targs = XmeStandardTargets(w, 3, &count);
 
3254
     else
 
3255
       targs = (Atom *) XtMalloc(sizeof(Atom) * 3);
 
3256
 
 
3257
     value = (XtPointer) targs;
 
3258
     targs[count] = XA_STRING; count++;
 
3259
     targs[count] = atoms[XmACOMPOUND_TEXT]; count++;
 
3260
     targs[count] = atoms[XmAUTF8_STRING]; count++;
 
3261
     size = count;
 
3262
     type = XA_ATOM;
 
3263
     format = 32;
 
3264
   } 
 
3265
 
 
3266
   if (cs -> target == XA_STRING ||
 
3267
       cs -> target == atoms[XmAUTF8_STRING]) {
 
3268
     /* handle plain STRING and UTF8_STRING first */
 
3269
     type = cs -> target;
 
3270
     value = (XtPointer) XtNewString(tmpstring);
 
3271
     size = strlen((char*) value);
 
3272
     format = 8;
 
3273
   }
 
3274
 
 
3275
   /* this routine processes only compound text now */
 
3276
   if (cs -> target == atoms[XmACOMPOUND_TEXT]) {
 
3277
     strlist = tmpstring; 
 
3278
     tp.value = NULL;
 
3279
     XmbTextListToTextProperty(XtDisplay(w), &strlist, 1, 
 
3280
                               XCompoundTextStyle, &tp);
 
3281
     passtext = XtNewString((char*)tp.value);
 
3282
     XtFree((char*)tp.value);
 
3283
     /* End fixing the bug OSF 4846 */
 
3284
 
 
3285
     /* format the value for transfer.  convert the value from
 
3286
      * compound string to compound text for the transfer */
 
3287
     type = atoms[XmACOMPOUND_TEXT];
 
3288
     value = (XtPointer) passtext;
 
3289
     size = strlen(passtext);
 
3290
     format = 8;
 
3291
   }
 
3292
 
 
3293
   _XmConvertComplete(w, value, size, format, type, cs);
 
3294
}
 
3295
 
 
3296
 
 
3297
 
 
3298
/************************************************************************
 
3299
 *
 
3300
 *  WidgetNavigable class method
 
3301
 *
 
3302
 ************************************************************************/
 
3303
static XmNavigability
 
3304
WidgetNavigable(
 
3305
        Widget wid)
 
3306
{   
 
3307
  if(    XtIsSensitive(wid)
 
3308
     &&  ((XmManagerWidget) wid)->manager.traversal_on    )
 
3309
    {   
 
3310
      XmNavigationType nav_type
 
3311
                           = ((XmManagerWidget) wid)->manager.navigation_type ;
 
3312
      
 
3313
      if(    (nav_type == XmSTICKY_TAB_GROUP)
 
3314
         ||  (nav_type == XmEXCLUSIVE_TAB_GROUP)
 
3315
         ||  (    (nav_type == XmTAB_GROUP)
 
3316
              &&  !_XmShellIsExclusive( wid))    )
 
3317
        {
 
3318
          return XmDESCENDANTS_TAB_NAVIGABLE ;
 
3319
        }
 
3320
    }
 
3321
  return XmNOT_NAVIGABLE ;
 
3322
}
 
3323
 
 
3324
 
 
3325
/************************************************************************
 
3326
 *
 
3327
 *      External API functions.
 
3328
 *
 
3329
 ************************************************************************/
 
3330
 
 
3331
 
 
3332
/************************************************************************
 
3333
 *
 
3334
 *  XmScaleSetValue
 
3335
 *
 
3336
 ************************************************************************/
 
3337
void 
 
3338
XmScaleSetValue(
 
3339
        Widget w,
 
3340
        int value )
 
3341
{
 
3342
    XmScaleWidget sw = (XmScaleWidget) w;
 
3343
    XtAppContext app = XtWidgetToApplicationContext(w);
 
3344
 
 
3345
    _XmAppLock(app);
 
3346
 
 
3347
    if (value < sw->scale.minimum) {
 
3348
        XmeWarning( (Widget) sw, MESSAGE2);
 
3349
        _XmAppUnlock(app);
 
3350
        return ;
 
3351
    }
 
3352
 
 
3353
    if (value > sw->scale.maximum) {
 
3354
        XmeWarning( (Widget) sw, MESSAGE3);
 
3355
        _XmAppUnlock(app);
 
3356
        return ;
 
3357
    }  
 
3358
 
 
3359
    sw->scale.value = value ;
 
3360
    SetScrollBarData(sw);
 
3361
    ShowValue(sw);
 
3362
    
 
3363
    _XmAppUnlock(app);
 
3364
}
 
3365
 
 
3366
 
 
3367
 
 
3368
 
 
3369
/************************************************************************
 
3370
 *
 
3371
 *  XmScaleGetValue
 
3372
 *
 
3373
 ************************************************************************/
 
3374
void 
 
3375
XmScaleGetValue(
 
3376
        Widget w,
 
3377
        int *value )
 
3378
{
 
3379
   XmScaleWidget sw = (XmScaleWidget) w;
 
3380
   XtAppContext app = XtWidgetToApplicationContext(w);
 
3381
 
 
3382
   _XmAppLock(app);
 
3383
   *value = sw->scale.value;
 
3384
   _XmAppUnlock(app);
 
3385
}
 
3386
 
 
3387
/************************************************************************
 
3388
 *
 
3389
 *  XmCreateScale
 
3390
 *
 
3391
 ************************************************************************/
 
3392
Widget 
 
3393
XmCreateScale(
 
3394
        Widget parent,
 
3395
        char *name,
 
3396
        ArgList arglist,
 
3397
        Cardinal argcount )
 
3398
{
 
3399
   return (XtCreateWidget(name, xmScaleWidgetClass, 
 
3400
                          parent, arglist, argcount));
 
3401
}
 
3402
 
 
3403
Widget 
 
3404
XmVaCreateScale(
 
3405
        Widget parent,
 
3406
        char *name,
 
3407
        ...)
 
3408
{
 
3409
    register Widget w;
 
3410
    va_list var;
 
3411
    int count;
 
3412
    
 
3413
    Va_start(var,name);
 
3414
    count = XmeCountVaListSimple(var);
 
3415
    va_end(var);
 
3416
 
 
3417
    
 
3418
    Va_start(var, name);
 
3419
    w = XmeVLCreateWidget(name, 
 
3420
                         xmScaleWidgetClass, 
 
3421
                         parent, False, 
 
3422
                         var, count);
 
3423
    va_end(var);   
 
3424
    return w;
 
3425
    
 
3426
}
 
3427
Widget 
 
3428
XmVaCreateManagedScale(
 
3429
        Widget parent,
 
3430
        char *name,
 
3431
        ...)
 
3432
{
 
3433
    Widget w = NULL;
 
3434
    va_list var;
 
3435
    int count;
 
3436
    
 
3437
    Va_start(var, name);
 
3438
    count = XmeCountVaListSimple(var);
 
3439
    va_end(var);
 
3440
    
 
3441
    Va_start(var, name);
 
3442
    w = XmeVLCreateWidget(name, 
 
3443
                         xmScaleWidgetClass, 
 
3444
                         parent, True, 
 
3445
                         var, count);
 
3446
    va_end(var);   
 
3447
    return w;
 
3448
    
 
3449
}