OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [tk/] [win/] [tkWinScrlbr.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
2
 * tkWinScrollbar.c --
3
 *
4
 *      This file implements the Windows specific portion of the scrollbar
5
 *      widget.
6
 *
7
 * Copyright (c) 1996 by Sun Microsystems, Inc.
8
 *
9
 * See the file "license.terms" for information on usage and redistribution
10
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
11
 *
12
 * RCS: @(#) $Id: tkWinScrlbr.c,v 1.1.1.1 2002-01-16 10:26:03 markom Exp $
13
 */
14
 
15
#include "tkWinInt.h"
16
#include "tkScrollbar.h"
17
 
18
 
19
/*
20
 * The following constant is used to specify the maximum scroll position.
21
 * This value is limited by the Win32 API to either 16-bits or 32-bits,
22
 * depending on the context.  For now we'll just use a value small
23
 * enough to fit in 16-bits, but which gives us 4-digits of precision.
24
 */
25
 
26
#define MAX_SCROLL 10000
27
 
28
/*
29
 * Declaration of Windows specific scrollbar structure.
30
 */
31
 
32
typedef struct WinScrollbar {
33
    TkScrollbar info;           /* Generic scrollbar info. */
34
    WNDPROC oldProc;            /* Old window procedure. */
35
    int lastVertical;           /* 1 if was vertical at last refresh. */
36
    HWND hwnd;                  /* Current window handle. */
37
    int winFlags;               /* Various flags; see below. */
38
} WinScrollbar;
39
 
40
/*
41
 * Flag bits for native scrollbars:
42
 *
43
 * IN_MODAL_LOOP:               Non-zero means this scrollbar is in the middle
44
 *                              of a modal loop.
45
 * ALREADY_DEAD:                Non-zero means this scrollbar has been
46
 *                              destroyed, but has not been cleaned up.
47
 */
48
 
49
#define IN_MODAL_LOOP   1
50
#define ALREADY_DEAD    2
51
 
52
/*
53
 * Cached system metrics used to determine scrollbar geometry.
54
 */
55
 
56
static int initialized = 0;
57
static int hArrowWidth, hThumb; /* Horizontal control metrics. */
58
static int vArrowWidth, vArrowHeight, vThumb; /* Vertical control metrics. */
59
 
60
/*
61
 * This variable holds the default width for a scrollbar in string
62
 * form for use in a Tk_ConfigSpec.
63
 */
64
 
65
static char defWidth[8];
66
 
67
/*
68
 * Declarations for functions defined in this file.
69
 */
70
 
71
static Window           CreateProc _ANSI_ARGS_((Tk_Window tkwin,
72
                            Window parent, ClientData instanceData));
73
static void             ModalLoopProc _ANSI_ARGS_((Tk_Window tkwin,
74
                            XEvent *eventPtr));
75
static int              ScrollbarBindProc _ANSI_ARGS_((ClientData clientData,
76
                            Tcl_Interp *interp, XEvent *eventPtr,
77
                            Tk_Window tkwin, KeySym keySym));
78
static LRESULT CALLBACK ScrollbarProc _ANSI_ARGS_((HWND hwnd, UINT message,
79
                            WPARAM wParam, LPARAM lParam));
80
static void             UpdateScrollbar _ANSI_ARGS_((
81
                            WinScrollbar *scrollPtr));
82
static void             UpdateScrollbarMetrics _ANSI_ARGS_((void));
83
 
84
/*
85
 * The class procedure table for the scrollbar widget.
86
 */
87
 
88
TkClassProcs tkpScrollbarProcs = {
89
    CreateProc,                 /* createProc */
90
    NULL,                       /* geometryProc */
91
    ModalLoopProc,              /* modalProc */
92
};
93
 
94
 
95
/*
96
 *----------------------------------------------------------------------
97
 *
98
 * TkpCreateScrollbar --
99
 *
100
 *      Allocate a new TkScrollbar structure.
101
 *
102
 * Results:
103
 *      Returns a newly allocated TkScrollbar structure.
104
 *
105
 * Side effects:
106
 *      Registers an event handler for the widget.
107
 *
108
 *----------------------------------------------------------------------
109
 */
110
 
111
TkScrollbar *
112
TkpCreateScrollbar(tkwin)
113
    Tk_Window tkwin;
114
{
115
    WinScrollbar *scrollPtr;
116
    TkWindow *winPtr = (TkWindow *)tkwin;
117
 
118
    if (!initialized) {
119
        UpdateScrollbarMetrics();
120
        initialized = 1;
121
    }
122
 
123
    scrollPtr = (WinScrollbar *) ckalloc(sizeof(WinScrollbar));
124
    scrollPtr->winFlags = 0;
125
    scrollPtr->hwnd = NULL;
126
 
127
    Tk_CreateEventHandler(tkwin,
128
            ExposureMask|StructureNotifyMask|FocusChangeMask,
129
            TkScrollbarEventProc, (ClientData) scrollPtr);
130
 
131
    if (!Tcl_GetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL)) {
132
        Tcl_SetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL,
133
                (ClientData)1);
134
        TkCreateBindingProcedure(winPtr->mainPtr->interp,
135
                winPtr->mainPtr->bindingTable,
136
                (ClientData)Tk_GetUid("Scrollbar"), "<ButtonPress>",
137
                ScrollbarBindProc, NULL, NULL);
138
    }
139
 
140
    return (TkScrollbar*) scrollPtr;
141
}
142
 
143
/*
144
 *----------------------------------------------------------------------
145
 *
146
 * UpdateScrollbar --
147
 *
148
 *      This function updates the position and size of the scrollbar
149
 *      thumb based on the current settings.
150
 *
151
 * Results:
152
 *      None.
153
 *
154
 * Side effects:
155
 *      Moves the thumb.
156
 *
157
 *----------------------------------------------------------------------
158
 */
159
 
160
static void
161
UpdateScrollbar(scrollPtr)
162
    WinScrollbar *scrollPtr;
163
{
164
    SCROLLINFO scrollInfo;
165
    double thumbSize;
166
 
167
    /*
168
     * Update the current scrollbar position and shape.
169
     */
170
 
171
    scrollInfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
172
    scrollInfo.cbSize = sizeof(scrollInfo);
173
    scrollInfo.nMin = 0;
174
    scrollInfo.nMax = MAX_SCROLL;
175
    thumbSize = (scrollPtr->info.lastFraction - scrollPtr->info.firstFraction);
176
    if (tkpIsWin32s) {
177
        scrollInfo.nPage = 0;
178
    } else {
179
        scrollInfo.nPage = ((UINT) (thumbSize * (double) MAX_SCROLL)) + 1;
180
    }
181
    if (thumbSize < 1.0) {
182
        scrollInfo.nPos = (int)
183
            ((scrollPtr->info.firstFraction / (1.0-thumbSize))
184
                    * (MAX_SCROLL - (scrollInfo.nPage - 1)));
185
    } else {
186
        scrollInfo.nPos = 0;
187
    }
188
    SetScrollInfo(scrollPtr->hwnd, SB_CTL, &scrollInfo, TRUE);
189
}
190
 
191
/*
192
 *----------------------------------------------------------------------
193
 *
194
 * CreateProc --
195
 *
196
 *      This function creates a new Scrollbar control, subclasses
197
 *      the instance, and generates a new Window object.
198
 *
199
 * Results:
200
 *      Returns the newly allocated Window object, or None on failure.
201
 *
202
 * Side effects:
203
 *      Causes a new Scrollbar control to come into existence.
204
 *
205
 *----------------------------------------------------------------------
206
 */
207
 
208
static Window
209
CreateProc(tkwin, parentWin, instanceData)
210
    Tk_Window tkwin;            /* Token for window. */
211
    Window parentWin;           /* Parent of new window. */
212
    ClientData instanceData;    /* Scrollbar instance data. */
213
{
214
    DWORD style;
215
    Window window;
216
    HWND parent;
217
    TkWindow *winPtr;
218
    WinScrollbar *scrollPtr = (WinScrollbar *)instanceData;
219
 
220
    parent = Tk_GetHWND(parentWin);
221
 
222
    if (scrollPtr->info.vertical) {
223
        style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
224
            | SBS_VERT | SBS_RIGHTALIGN;
225
    } else {
226
        style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
227
            | SBS_HORZ | SBS_BOTTOMALIGN;
228
    }
229
 
230
    scrollPtr->hwnd = CreateWindow("SCROLLBAR", NULL, style,
231
            Tk_X(tkwin), Tk_Y(tkwin), Tk_Width(tkwin), Tk_Height(tkwin),
232
            parent, NULL, Tk_GetHINSTANCE(), NULL);
233
 
234
    /*
235
     * Ensure new window is inserted into the stacking order at the correct
236
     * place.
237
     */
238
 
239
    SetWindowPos(scrollPtr->hwnd, HWND_TOP, 0, 0, 0, 0,
240
                    SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
241
 
242
    for (winPtr = ((TkWindow*)tkwin)->nextPtr; winPtr != NULL;
243
         winPtr = winPtr->nextPtr) {
244
        if ((winPtr->window != None) && !(winPtr->flags & TK_TOP_LEVEL)) {
245
            TkWinSetWindowPos(scrollPtr->hwnd, Tk_GetHWND(winPtr->window),
246
                    Below);
247
            break;
248
        }
249
    }
250
 
251
    scrollPtr->lastVertical = scrollPtr->info.vertical;
252
    scrollPtr->oldProc = (WNDPROC)SetWindowLong(scrollPtr->hwnd, GWL_WNDPROC,
253
            (DWORD) ScrollbarProc);
254
    window = Tk_AttachHWND(tkwin, scrollPtr->hwnd);
255
 
256
    UpdateScrollbar(scrollPtr);
257
    return window;
258
}
259
 
260
/*
261
 *--------------------------------------------------------------
262
 *
263
 * TkpDisplayScrollbar --
264
 *
265
 *      This procedure redraws the contents of a scrollbar window.
266
 *      It is invoked as a do-when-idle handler, so it only runs
267
 *      when there's nothing else for the application to do.
268
 *
269
 * Results:
270
 *      None.
271
 *
272
 * Side effects:
273
 *      Information appears on the screen.
274
 *
275
 *--------------------------------------------------------------
276
 */
277
 
278
void
279
TkpDisplayScrollbar(clientData)
280
    ClientData clientData;      /* Information about window. */
281
{
282
    WinScrollbar *scrollPtr = (WinScrollbar *) clientData;
283
    Tk_Window tkwin = scrollPtr->info.tkwin;
284
 
285
    scrollPtr->info.flags &= ~REDRAW_PENDING;
286
    if ((tkwin == NULL) || !Tk_IsMapped(tkwin)) {
287
        return;
288
    }
289
 
290
    /*
291
     * Destroy and recreate the scrollbar control if the orientation
292
     * has changed.
293
     */
294
 
295
    if (scrollPtr->lastVertical != scrollPtr->info.vertical) {
296
        HWND hwnd = Tk_GetHWND(Tk_WindowId(tkwin));
297
 
298
        SetWindowLong(hwnd, GWL_WNDPROC, (DWORD) scrollPtr->oldProc);
299
        DestroyWindow(hwnd);
300
 
301
        CreateProc(tkwin, Tk_WindowId(Tk_Parent(tkwin)),
302
                (ClientData) scrollPtr);
303
    } else {
304
        UpdateScrollbar(scrollPtr);
305
    }
306
}
307
 
308
/*
309
 *----------------------------------------------------------------------
310
 *
311
 * TkpDestroyScrollbar --
312
 *
313
 *      Free data structures associated with the scrollbar control.
314
 *
315
 * Results:
316
 *      None.
317
 *
318
 * Side effects:
319
 *      Restores the default control state.
320
 *
321
 *----------------------------------------------------------------------
322
 */
323
 
324
void
325
TkpDestroyScrollbar(scrollPtr)
326
    TkScrollbar *scrollPtr;
327
{
328
    WinScrollbar *winScrollPtr = (WinScrollbar *)scrollPtr;
329
    HWND hwnd = winScrollPtr->hwnd;
330
    if (hwnd) {
331
        SetWindowLong(hwnd, GWL_WNDPROC, (DWORD) winScrollPtr->oldProc);
332
        if (winScrollPtr->winFlags & IN_MODAL_LOOP) {
333
            ((TkWindow *)scrollPtr->tkwin)->flags |= TK_DONT_DESTROY_WINDOW;
334
            SetParent(hwnd, NULL);
335
        }
336
    }
337
    winScrollPtr->winFlags |= ALREADY_DEAD;
338
}
339
 
340
/*
341
 *----------------------------------------------------------------------
342
 *
343
 * UpdateScrollbarMetrics --
344
 *
345
 *      This function retrieves the current system metrics for a
346
 *      scrollbar.
347
 *
348
 * Results:
349
 *      None.
350
 *
351
 * Side effects:
352
 *      Updates the geometry cache info for all scrollbars.
353
 *
354
 *----------------------------------------------------------------------
355
 */
356
 
357
void
358
UpdateScrollbarMetrics()
359
{
360
    Tk_ConfigSpec *specPtr;
361
 
362
    hArrowWidth = GetSystemMetrics(SM_CXHSCROLL);
363
    hThumb = GetSystemMetrics(SM_CXHTHUMB);
364
    vArrowWidth = GetSystemMetrics(SM_CXVSCROLL);
365
    vArrowHeight = GetSystemMetrics(SM_CYVSCROLL);
366
    vThumb = GetSystemMetrics(SM_CYVTHUMB);
367
 
368
    sprintf(defWidth, "%d", vArrowWidth);
369
    for (specPtr = tkpScrollbarConfigSpecs; specPtr->type != TK_CONFIG_END;
370
            specPtr++) {
371
        if (specPtr->offset == Tk_Offset(TkScrollbar, width)) {
372
            specPtr->defValue = defWidth;
373
        }
374
    }
375
}
376
 
377
/*
378
 *----------------------------------------------------------------------
379
 *
380
 * TkpComputeScrollbarGeometry --
381
 *
382
 *      After changes in a scrollbar's size or configuration, this
383
 *      procedure recomputes various geometry information used in
384
 *      displaying the scrollbar.
385
 *
386
 * Results:
387
 *      None.
388
 *
389
 * Side effects:
390
 *      The scrollbar will be displayed differently.
391
 *
392
 *----------------------------------------------------------------------
393
 */
394
 
395
void
396
TkpComputeScrollbarGeometry(scrollPtr)
397
    register TkScrollbar *scrollPtr;    /* Scrollbar whose geometry may
398
                                         * have changed. */
399
{
400
    int fieldLength, minThumbSize;
401
 
402
    /*
403
     * Windows doesn't use focus rings on scrollbars, but we still
404
     * perform basic sanity checks to appease backwards compatibility.
405
     */
406
 
407
    if (scrollPtr->highlightWidth < 0) {
408
        scrollPtr->highlightWidth = 0;
409
    }
410
 
411
    if (scrollPtr->vertical) {
412
        scrollPtr->arrowLength = vArrowHeight;
413
        fieldLength = Tk_Height(scrollPtr->tkwin);
414
        minThumbSize = vThumb;
415
    } else {
416
        scrollPtr->arrowLength = hArrowWidth;
417
        fieldLength = Tk_Width(scrollPtr->tkwin);
418
        minThumbSize = hThumb;
419
    }
420
    fieldLength -= 2*scrollPtr->arrowLength;
421
    if (fieldLength < 0) {
422
        fieldLength = 0;
423
    }
424
    scrollPtr->sliderFirst = (int) ((double)fieldLength
425
            * scrollPtr->firstFraction);
426
    scrollPtr->sliderLast = (int) ((double)fieldLength
427
            * scrollPtr->lastFraction);
428
 
429
    /*
430
     * Adjust the slider so that some piece of it is always
431
     * displayed in the scrollbar and so that it has at least
432
     * a minimal width (so it can be grabbed with the mouse).
433
     */
434
 
435
    if (scrollPtr->sliderFirst > fieldLength) {
436
        scrollPtr->sliderFirst = fieldLength;
437
    }
438
    if (scrollPtr->sliderFirst < 0) {
439
        scrollPtr->sliderFirst = 0;
440
    }
441
    if (scrollPtr->sliderLast < (scrollPtr->sliderFirst
442
            + minThumbSize)) {
443
        scrollPtr->sliderLast = scrollPtr->sliderFirst + minThumbSize;
444
    }
445
    if (scrollPtr->sliderLast > fieldLength) {
446
        scrollPtr->sliderLast = fieldLength;
447
    }
448
    scrollPtr->sliderFirst += scrollPtr->arrowLength;
449
    scrollPtr->sliderLast += scrollPtr->arrowLength;
450
 
451
    /*
452
     * Register the desired geometry for the window (leave enough space
453
     * for the two arrows plus a minimum-size slider, plus border around
454
     * the whole window, if any).  Then arrange for the window to be
455
     * redisplayed.
456
     */
457
 
458
    if (scrollPtr->vertical) {
459
        Tk_GeometryRequest(scrollPtr->tkwin,
460
                scrollPtr->width, 2*scrollPtr->arrowLength + minThumbSize);
461
    } else {
462
        Tk_GeometryRequest(scrollPtr->tkwin,
463
                2*scrollPtr->arrowLength + minThumbSize, scrollPtr->width);
464
    }
465
    Tk_SetInternalBorder(scrollPtr->tkwin, 0);
466
}
467
 
468
/*
469
 *----------------------------------------------------------------------
470
 *
471
 * ScrollbarProc --
472
 *
473
 *      This function is call by Windows whenever an event occurs on
474
 *      a scrollbar control created by Tk.
475
 *
476
 * Results:
477
 *      Standard Windows return value.
478
 *
479
 * Side effects:
480
 *      May generate events.
481
 *
482
 *----------------------------------------------------------------------
483
 */
484
 
485
static LRESULT CALLBACK
486
ScrollbarProc(hwnd, message, wParam, lParam)
487
    HWND hwnd;
488
    UINT message;
489
    WPARAM wParam;
490
    LPARAM lParam;
491
{
492
    LRESULT result;
493
    POINT point;
494
    WinScrollbar *scrollPtr;
495
    Tk_Window tkwin = Tk_HWNDToWindow(hwnd);
496
 
497
    if (tkwin == NULL) {
498
        panic("ScrollbarProc called on an invalid HWND");
499
    }
500
    scrollPtr = (WinScrollbar *)((TkWindow*)tkwin)->instanceData;
501
 
502
    switch(message) {
503
        case WM_HSCROLL:
504
        case WM_VSCROLL: {
505
            Tcl_Interp *interp;
506
            Tcl_DString cmdString;
507
            int command = LOWORD(wParam);
508
            int code;
509
 
510
            GetCursorPos(&point);
511
            Tk_TranslateWinEvent(NULL, WM_MOUSEMOVE, 0,
512
                    MAKELPARAM(point.x, point.y), &result);
513
 
514
            if (command == SB_ENDSCROLL) {
515
                return 0;
516
            }
517
 
518
            /*
519
             * Bail out immediately if there isn't a command to invoke.
520
             */
521
 
522
            if (scrollPtr->info.commandSize == 0) {
523
                Tcl_ServiceAll();
524
                return 0;
525
            }
526
 
527
            Tcl_DStringInit(&cmdString);
528
            Tcl_DStringAppend(&cmdString, scrollPtr->info.command,
529
                    scrollPtr->info.commandSize);
530
 
531
            if (command == SB_LINELEFT || command == SB_LINERIGHT) {
532
                Tcl_DStringAppendElement(&cmdString, "scroll");
533
                Tcl_DStringAppendElement(&cmdString,
534
                        (command == SB_LINELEFT ) ? "-1" : "1");
535
                Tcl_DStringAppendElement(&cmdString, "units");
536
            } else if (command == SB_PAGELEFT || command == SB_PAGERIGHT) {
537
                Tcl_DStringAppendElement(&cmdString, "scroll");
538
                Tcl_DStringAppendElement(&cmdString,
539
                        (command == SB_PAGELEFT ) ? "-1" : "1");
540
                Tcl_DStringAppendElement(&cmdString, "pages");
541
            } else {
542
                char valueString[TCL_DOUBLE_SPACE];
543
                double pos = 0.0;
544
                switch (command) {
545
                    case SB_THUMBPOSITION:
546
                        pos = ((double)HIWORD(wParam)) / MAX_SCROLL;
547
                        break;
548
 
549
                    case SB_THUMBTRACK:
550
                        pos = ((double)HIWORD(wParam)) / MAX_SCROLL;
551
                        break;
552
 
553
                    case SB_TOP:
554
                        pos = 0.0;
555
                        break;
556
 
557
                    case SB_BOTTOM:
558
                        pos = 1.0;
559
                        break;
560
                }
561
                sprintf(valueString, "%g", pos);
562
                Tcl_DStringAppendElement(&cmdString, "moveto");
563
                Tcl_DStringAppendElement(&cmdString, valueString);
564
            }
565
 
566
            interp = scrollPtr->info.interp;
567
            code = Tcl_GlobalEval(interp, cmdString.string);
568
            if (code != TCL_OK && code != TCL_CONTINUE && code != TCL_BREAK) {
569
                Tcl_AddErrorInfo(interp, "\n    (scrollbar command)");
570
                Tcl_BackgroundError(interp);
571
            }
572
            Tcl_DStringFree(&cmdString);
573
 
574
            Tcl_ServiceAll();
575
            return 0;
576
        }
577
 
578
        default:
579
            if (Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
580
                return result;
581
            }
582
    }
583
    return CallWindowProc(scrollPtr->oldProc, hwnd, message, wParam, lParam);
584
}
585
 
586
/*
587
 *----------------------------------------------------------------------
588
 *
589
 * TkpConfigureScrollbar --
590
 *
591
 *      This procedure is called after the generic code has finished
592
 *      processing configuration options, in order to configure
593
 *      platform specific options.
594
 *
595
 * Results:
596
 *      None.
597
 *
598
 * Side effects:
599
 *      None.
600
 *
601
 *----------------------------------------------------------------------
602
 */
603
 
604
void
605
TkpConfigureScrollbar(scrollPtr)
606
    register TkScrollbar *scrollPtr;    /* Information about widget;  may or
607
                                         * may not already have values for
608
                                         * some fields. */
609
{
610
}
611
 
612
/*
613
 *--------------------------------------------------------------
614
 *
615
 * ScrollbarBindProc --
616
 *
617
 *      This procedure is invoked when the default <ButtonPress>
618
 *      binding on the Scrollbar bind tag fires.
619
 *
620
 * Results:
621
 *      None.
622
 *
623
 * Side effects:
624
 *      The event enters a modal loop.
625
 *
626
 *--------------------------------------------------------------
627
 */
628
 
629
static int
630
ScrollbarBindProc(clientData, interp, eventPtr, tkwin, keySym)
631
    ClientData clientData;
632
    Tcl_Interp *interp;
633
    XEvent *eventPtr;
634
    Tk_Window tkwin;
635
    KeySym keySym;
636
{
637
    TkWindow *winPtr = (TkWindow*)tkwin;
638
    if (eventPtr->type == ButtonPress) {
639
        winPtr->flags |= TK_DEFER_MODAL;
640
    }
641
    return TCL_OK;
642
}
643
 
644
/*
645
 *----------------------------------------------------------------------
646
 *
647
 * ModalLoopProc --
648
 *
649
 *      This function is invoked at the end of the event processing
650
 *      whenever the ScrollbarBindProc has been invoked for a ButtonPress
651
 *      event.
652
 *
653
 * Results:
654
 *      None.
655
 *
656
 * Side effects:
657
 *      Enters a modal loop.
658
 *
659
 *----------------------------------------------------------------------
660
 */
661
 
662
static void
663
ModalLoopProc(tkwin, eventPtr)
664
    Tk_Window tkwin;
665
    XEvent *eventPtr;
666
{
667
    TkWindow *winPtr = (TkWindow*)tkwin;
668
    WinScrollbar *scrollPtr = (WinScrollbar *) winPtr->instanceData;
669
    int oldMode;
670
 
671
    Tcl_Preserve((ClientData)scrollPtr);
672
    scrollPtr->winFlags |= IN_MODAL_LOOP;
673
    oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
674
    TkWinResendEvent(scrollPtr->oldProc, scrollPtr->hwnd, eventPtr);
675
    (void) Tcl_SetServiceMode(oldMode);
676
    scrollPtr->winFlags &= ~IN_MODAL_LOOP;
677
    if (scrollPtr->hwnd && scrollPtr->winFlags & ALREADY_DEAD) {
678
        DestroyWindow(scrollPtr->hwnd);
679
    }
680
    Tcl_Release((ClientData)scrollPtr);
681
}
682
 
683
/*
684
 *--------------------------------------------------------------
685
 *
686
 * TkpScrollbarPosition --
687
 *
688
 *      Determine the scrollbar element corresponding to a
689
 *      given position.
690
 *
691
 * Results:
692
 *      One of TOP_ARROW, TOP_GAP, etc., indicating which element
693
 *      of the scrollbar covers the position given by (x, y).  If
694
 *      (x,y) is outside the scrollbar entirely, then OUTSIDE is
695
 *      returned.
696
 *
697
 * Side effects:
698
 *      None.
699
 *
700
 *--------------------------------------------------------------
701
 */
702
 
703
int
704
TkpScrollbarPosition(scrollPtr, x, y)
705
    register TkScrollbar *scrollPtr;    /* Scrollbar widget record. */
706
    int x, y;                           /* Coordinates within scrollPtr's
707
                                         * window. */
708
{
709
    int length, width, tmp;
710
 
711
    if (scrollPtr->vertical) {
712
        length = Tk_Height(scrollPtr->tkwin);
713
        width = Tk_Width(scrollPtr->tkwin);
714
    } else {
715
        tmp = x;
716
        x = y;
717
        y = tmp;
718
        length = Tk_Width(scrollPtr->tkwin);
719
        width = Tk_Height(scrollPtr->tkwin);
720
    }
721
 
722
    if ((x < scrollPtr->inset) || (x >= (width - scrollPtr->inset))
723
            || (y < scrollPtr->inset) || (y >= (length - scrollPtr->inset))) {
724
        return OUTSIDE;
725
    }
726
 
727
    /*
728
     * All of the calculations in this procedure mirror those in
729
     * TkpDisplayScrollbar.  Be sure to keep the two consistent.
730
     */
731
 
732
    if (y < (scrollPtr->inset + scrollPtr->arrowLength)) {
733
        return TOP_ARROW;
734
    }
735
    if (y < scrollPtr->sliderFirst) {
736
        return TOP_GAP;
737
    }
738
    if (y < scrollPtr->sliderLast) {
739
        return SLIDER;
740
    }
741
    if (y >= (length - (scrollPtr->arrowLength + scrollPtr->inset))) {
742
        return BOTTOM_ARROW;
743
    }
744
    return BOTTOM_GAP;
745
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.