summaryrefslogtreecommitdiffstats
path: root/tk8.6/win/tkWinScrlbr.c
diff options
context:
space:
mode:
authorWilliam Joye <wjoye@cfa.harvard.edu>2018-12-25 19:55:50 (GMT)
committerWilliam Joye <wjoye@cfa.harvard.edu>2018-12-25 19:55:50 (GMT)
commitff51550ee89b473c63df78de6b2a413f21105687 (patch)
treebcdca927ed2a7b05c647b9a6bfdfd4a7ca5c730e /tk8.6/win/tkWinScrlbr.c
parent01cbf5b15ea760408c24288ccb5cf8e0af9aa299 (diff)
downloadblt-ff51550ee89b473c63df78de6b2a413f21105687.zip
blt-ff51550ee89b473c63df78de6b2a413f21105687.tar.gz
blt-ff51550ee89b473c63df78de6b2a413f21105687.tar.bz2
update tcl/tk
Diffstat (limited to 'tk8.6/win/tkWinScrlbr.c')
-rw-r--r--tk8.6/win/tkWinScrlbr.c701
1 files changed, 0 insertions, 701 deletions
diff --git a/tk8.6/win/tkWinScrlbr.c b/tk8.6/win/tkWinScrlbr.c
deleted file mode 100644
index 1b3717e..0000000
--- a/tk8.6/win/tkWinScrlbr.c
+++ /dev/null
@@ -1,701 +0,0 @@
-/*
- * tkWinScrollbar.c --
- *
- * This file implements the Windows specific portion of the scrollbar
- * widget.
- *
- * Copyright (c) 1996 by Sun Microsystems, Inc.
- *
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
- */
-
-#include "tkWinInt.h"
-#include "tkScrollbar.h"
-
-/*
- * The following constant is used to specify the maximum scroll position. This
- * value is limited by the Win32 API to either 16-bits or 32-bits, depending
- * on the context. For now we'll just use a value small enough to fit in
- * 16-bits, but which gives us 4-digits of precision.
- */
-
-#define MAX_SCROLL 10000
-
-/*
- * Declaration of Windows specific scrollbar structure.
- */
-
-typedef struct WinScrollbar {
- TkScrollbar info; /* Generic scrollbar info. */
- WNDPROC oldProc; /* Old window procedure. */
- int lastVertical; /* 1 if was vertical at last refresh. */
- HWND hwnd; /* Current window handle. */
- int winFlags; /* Various flags; see below. */
-} WinScrollbar;
-
-/*
- * Flag bits for native scrollbars:
- *
- * IN_MODAL_LOOP: Non-zero means this scrollbar is in the middle
- * of a modal loop.
- * ALREADY_DEAD: Non-zero means this scrollbar has been
- * destroyed, but has not been cleaned up.
- */
-
-#define IN_MODAL_LOOP 1
-#define ALREADY_DEAD 2
-
-/*
- * Cached system metrics used to determine scrollbar geometry.
- */
-
-static int initialized = 0;
-static int hArrowWidth, hThumb; /* Horizontal control metrics. */
-static int vArrowHeight, vThumb; /* Vertical control metrics. */
-
-TCL_DECLARE_MUTEX(winScrlbrMutex)
-
-/*
- * Declarations for functions defined in this file.
- */
-
-static Window CreateProc(Tk_Window tkwin, Window parent,
- ClientData instanceData);
-static void ModalLoop(WinScrollbar *, XEvent *eventPtr);
-static LRESULT CALLBACK ScrollbarProc(HWND hwnd, UINT message, WPARAM wParam,
- LPARAM lParam);
-static void UpdateScrollbar(WinScrollbar *scrollPtr);
-static void UpdateScrollbarMetrics(void);
-
-/*
- * The class procedure table for the scrollbar widget.
- */
-
-const Tk_ClassProcs tkpScrollbarProcs = {
- sizeof(Tk_ClassProcs), /* size */
- NULL, /* worldChangedProc */
- CreateProc, /* createProc */
- NULL /* modalProc */
-};
-
-static void
-WinScrollbarEventProc(ClientData clientData, XEvent *eventPtr)
-{
- WinScrollbar *scrollPtr = clientData;
-
- if (eventPtr->type == ButtonPress) {
- ModalLoop(scrollPtr, eventPtr);
- } else {
- TkScrollbarEventProc(clientData, eventPtr);
- }
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * TkpCreateScrollbar --
- *
- * Allocate a new TkScrollbar structure.
- *
- * Results:
- * Returns a newly allocated TkScrollbar structure.
- *
- * Side effects:
- * Registers an event handler for the widget.
- *
- *----------------------------------------------------------------------
- */
-
-TkScrollbar *
-TkpCreateScrollbar(
- Tk_Window tkwin)
-{
- WinScrollbar *scrollPtr;
-
- if (!initialized) {
- Tcl_MutexLock(&winScrlbrMutex);
- UpdateScrollbarMetrics();
- initialized = 1;
- Tcl_MutexUnlock(&winScrlbrMutex);
- }
-
- scrollPtr = ckalloc(sizeof(WinScrollbar));
- scrollPtr->winFlags = 0;
- scrollPtr->hwnd = NULL;
-
- Tk_CreateEventHandler(tkwin,
- ExposureMask|StructureNotifyMask|FocusChangeMask|ButtonPressMask,
- WinScrollbarEventProc, scrollPtr);
-
- return (TkScrollbar *) scrollPtr;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * UpdateScrollbar --
- *
- * This function updates the position and size of the scrollbar thumb
- * based on the current settings.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Moves the thumb.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-UpdateScrollbar(
- WinScrollbar *scrollPtr)
-{
- SCROLLINFO scrollInfo;
- double thumbSize;
-
- /*
- * Update the current scrollbar position and shape.
- */
-
- scrollInfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
- scrollInfo.cbSize = sizeof(scrollInfo);
- scrollInfo.nMin = 0;
- scrollInfo.nMax = MAX_SCROLL;
- thumbSize = (scrollPtr->info.lastFraction - scrollPtr->info.firstFraction);
- scrollInfo.nPage = ((UINT) (thumbSize * (double) MAX_SCROLL)) + 1;
- if (thumbSize < 1.0) {
- scrollInfo.nPos = (int)
- ((scrollPtr->info.firstFraction / (1.0-thumbSize))
- * (MAX_SCROLL - (scrollInfo.nPage - 1)));
- } else {
- scrollInfo.nPos = 0;
-
- /*
- * Disable the scrollbar when there is nothing to scroll. This is
- * standard Windows style (see eg Notepad). Also prevents possible
- * crash on XP+ systems [Bug #624116].
- */
-
- scrollInfo.fMask |= SIF_DISABLENOSCROLL;
- }
- SetScrollInfo(scrollPtr->hwnd, SB_CTL, &scrollInfo, TRUE);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * CreateProc --
- *
- * This function creates a new Scrollbar control, subclasses the
- * instance, and generates a new Window object.
- *
- * Results:
- * Returns the newly allocated Window object, or None on failure.
- *
- * Side effects:
- * Causes a new Scrollbar control to come into existence.
- *
- *----------------------------------------------------------------------
- */
-
-static Window
-CreateProc(
- Tk_Window tkwin, /* Token for window. */
- Window parentWin, /* Parent of new window. */
- ClientData instanceData) /* Scrollbar instance data. */
-{
- DWORD style;
- Window window;
- HWND parent;
- TkWindow *winPtr;
- WinScrollbar *scrollPtr = (WinScrollbar *)instanceData;
-
- parent = Tk_GetHWND(parentWin);
-
- if (scrollPtr->info.vertical) {
- style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
- | SBS_VERT;
- } else {
- style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
- | SBS_HORZ;
- }
-
- scrollPtr->hwnd = CreateWindow(TEXT("SCROLLBAR"), NULL, style,
- Tk_X(tkwin), Tk_Y(tkwin), Tk_Width(tkwin), Tk_Height(tkwin),
- parent, NULL, Tk_GetHINSTANCE(), NULL);
-
- /*
- * Ensure new window is inserted into the stacking order at the correct
- * place.
- */
-
- SetWindowPos(scrollPtr->hwnd, HWND_TOP, 0, 0, 0, 0,
- SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
-
- for (winPtr = ((TkWindow*)tkwin)->nextPtr; winPtr != NULL;
- winPtr = winPtr->nextPtr) {
- if ((winPtr->window != None) && !(winPtr->flags & TK_TOP_HIERARCHY)) {
- TkWinSetWindowPos(scrollPtr->hwnd, Tk_GetHWND(winPtr->window),
- Below);
- break;
- }
- }
-
- scrollPtr->lastVertical = scrollPtr->info.vertical;
- scrollPtr->oldProc = (WNDPROC)SetWindowLongPtr(scrollPtr->hwnd,
- GWLP_WNDPROC, (LONG_PTR) ScrollbarProc);
- window = Tk_AttachHWND(tkwin, scrollPtr->hwnd);
-
- UpdateScrollbar(scrollPtr);
- return window;
-}
-
-/*
- *--------------------------------------------------------------
- *
- * TkpDisplayScrollbar --
- *
- * This procedure redraws the contents of a scrollbar window. It is
- * invoked as a do-when-idle handler, so it only runs when there's
- * nothing else for the application to do.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Information appears on the screen.
- *
- *--------------------------------------------------------------
- */
-
-void
-TkpDisplayScrollbar(
- ClientData clientData) /* Information about window. */
-{
- WinScrollbar *scrollPtr = (WinScrollbar *) clientData;
- Tk_Window tkwin = scrollPtr->info.tkwin;
-
- scrollPtr->info.flags &= ~REDRAW_PENDING;
- if ((tkwin == NULL) || !Tk_IsMapped(tkwin)) {
- return;
- }
-
- /*
- * Destroy and recreate the scrollbar control if the orientation has
- * changed.
- */
-
- if (scrollPtr->lastVertical != scrollPtr->info.vertical) {
- HWND hwnd = Tk_GetHWND(Tk_WindowId(tkwin));
-
- SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) scrollPtr->oldProc);
- DestroyWindow(hwnd);
-
- CreateProc(tkwin, Tk_WindowId(Tk_Parent(tkwin)),
- (ClientData) scrollPtr);
- } else {
- UpdateScrollbar(scrollPtr);
- }
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TkpDestroyScrollbar --
- *
- * Free data structures associated with the scrollbar control.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Restores the default control state.
- *
- *----------------------------------------------------------------------
- */
-
-void
-TkpDestroyScrollbar(
- TkScrollbar *scrollPtr)
-{
- WinScrollbar *winScrollPtr = (WinScrollbar *)scrollPtr;
- HWND hwnd = winScrollPtr->hwnd;
-
- if (hwnd) {
- SetWindowLongPtr(hwnd, GWLP_WNDPROC, (INT_PTR) winScrollPtr->oldProc);
- if (winScrollPtr->winFlags & IN_MODAL_LOOP) {
- ((TkWindow *)scrollPtr->tkwin)->flags |= TK_DONT_DESTROY_WINDOW;
- SetParent(hwnd, NULL);
- }
- }
- winScrollPtr->winFlags |= ALREADY_DEAD;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * UpdateScrollbarMetrics --
- *
- * This function retrieves the current system metrics for a scrollbar.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Updates the geometry cache info for all scrollbars.
- *
- *----------------------------------------------------------------------
- */
-
-void
-UpdateScrollbarMetrics(void)
-{
- int arrowWidth = GetSystemMetrics(SM_CXVSCROLL);
-
- hArrowWidth = GetSystemMetrics(SM_CXHSCROLL);
- hThumb = GetSystemMetrics(SM_CXHTHUMB);
- vArrowHeight = GetSystemMetrics(SM_CYVSCROLL);
- vThumb = GetSystemMetrics(SM_CYVTHUMB);
-
- sprintf(tkDefScrollbarWidth, "%d", arrowWidth);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TkpComputeScrollbarGeometry --
- *
- * After changes in a scrollbar's size or configuration, this procedure
- * recomputes various geometry information used in displaying the
- * scrollbar.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The scrollbar will be displayed differently.
- *
- *----------------------------------------------------------------------
- */
-
-void
-TkpComputeScrollbarGeometry(
- register TkScrollbar *scrollPtr)
- /* Scrollbar whose geometry may have
- * changed. */
-{
- int fieldLength, minThumbSize;
-
- /*
- * Windows doesn't use focus rings on scrollbars, but we still perform
- * basic sanity checks to appease backwards compatibility.
- */
-
- if (scrollPtr->highlightWidth < 0) {
- scrollPtr->highlightWidth = 0;
- }
-
- if (scrollPtr->vertical) {
- scrollPtr->arrowLength = vArrowHeight;
- fieldLength = Tk_Height(scrollPtr->tkwin);
- minThumbSize = vThumb;
- } else {
- scrollPtr->arrowLength = hArrowWidth;
- fieldLength = Tk_Width(scrollPtr->tkwin);
- minThumbSize = hThumb;
- }
- fieldLength -= 2*scrollPtr->arrowLength;
- if (fieldLength < 0) {
- fieldLength = 0;
- }
- scrollPtr->sliderFirst = (int) ((double)fieldLength
- * scrollPtr->firstFraction);
- scrollPtr->sliderLast = (int) ((double)fieldLength
- * scrollPtr->lastFraction);
-
- /*
- * Adjust the slider so that some piece of it is always displayed in the
- * scrollbar and so that it has at least a minimal width (so it can be
- * grabbed with the mouse).
- */
-
- if (scrollPtr->sliderFirst > fieldLength) {
- scrollPtr->sliderFirst = fieldLength;
- }
- if (scrollPtr->sliderFirst < 0) {
- scrollPtr->sliderFirst = 0;
- }
- if (scrollPtr->sliderLast < (scrollPtr->sliderFirst
- + minThumbSize)) {
- scrollPtr->sliderLast = scrollPtr->sliderFirst + minThumbSize;
- }
- if (scrollPtr->sliderLast > fieldLength) {
- scrollPtr->sliderLast = fieldLength;
- }
- scrollPtr->sliderFirst += scrollPtr->arrowLength;
- scrollPtr->sliderLast += scrollPtr->arrowLength;
-
- /*
- * Register the desired geometry for the window (leave enough space for
- * the two arrows plus a minimum-size slider, plus border around the whole
- * window, if any). Then arrange for the window to be redisplayed.
- */
-
- if (scrollPtr->vertical) {
- Tk_GeometryRequest(scrollPtr->tkwin,
- scrollPtr->width, 2*scrollPtr->arrowLength + minThumbSize);
- } else {
- Tk_GeometryRequest(scrollPtr->tkwin,
- 2*scrollPtr->arrowLength + minThumbSize, scrollPtr->width);
- }
- Tk_SetInternalBorder(scrollPtr->tkwin, 0);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * ScrollbarProc --
- *
- * This function is call by Windows whenever an event occurs on a
- * scrollbar control created by Tk.
- *
- * Results:
- * Standard Windows return value.
- *
- * Side effects:
- * May generate events.
- *
- *----------------------------------------------------------------------
- */
-
-static LRESULT CALLBACK
-ScrollbarProc(
- HWND hwnd,
- UINT message,
- WPARAM wParam,
- LPARAM lParam)
-{
- LRESULT result;
- POINT point;
- WinScrollbar *scrollPtr;
- Tk_Window tkwin = Tk_HWNDToWindow(hwnd);
-
- if (tkwin == NULL) {
- Tcl_Panic("ScrollbarProc called on an invalid HWND");
- }
- scrollPtr = (WinScrollbar *)((TkWindow*)tkwin)->instanceData;
-
- switch(message) {
- case WM_HSCROLL:
- case WM_VSCROLL: {
- Tcl_Interp *interp;
- Tcl_DString cmdString;
- int command = LOWORD(wParam);
- int code;
-
- GetCursorPos(&point);
- Tk_TranslateWinEvent(NULL, WM_MOUSEMOVE, 0,
- MAKELPARAM(point.x, point.y), &result);
-
- if (command == SB_ENDSCROLL) {
- return 0;
- }
-
- /*
- * Bail out immediately if there isn't a command to invoke.
- */
-
- if (scrollPtr->info.commandSize == 0) {
- Tcl_ServiceAll();
- return 0;
- }
-
- Tcl_DStringInit(&cmdString);
- Tcl_DStringAppend(&cmdString, scrollPtr->info.command,
- scrollPtr->info.commandSize);
-
- if (command == SB_LINELEFT || command == SB_LINERIGHT) {
- Tcl_DStringAppendElement(&cmdString, "scroll");
- Tcl_DStringAppendElement(&cmdString,
- (command == SB_LINELEFT ) ? "-1" : "1");
- Tcl_DStringAppendElement(&cmdString, "units");
- } else if (command == SB_PAGELEFT || command == SB_PAGERIGHT) {
- Tcl_DStringAppendElement(&cmdString, "scroll");
- Tcl_DStringAppendElement(&cmdString,
- (command == SB_PAGELEFT ) ? "-1" : "1");
- Tcl_DStringAppendElement(&cmdString, "pages");
- } else {
- char valueString[TCL_DOUBLE_SPACE];
- double pos = 0.0;
-
- switch (command) {
- case SB_THUMBPOSITION:
- pos = ((double)HIWORD(wParam)) / MAX_SCROLL;
- break;
- case SB_THUMBTRACK:
- pos = ((double)HIWORD(wParam)) / MAX_SCROLL;
- break;
- case SB_TOP:
- pos = 0.0;
- break;
- case SB_BOTTOM:
- pos = 1.0;
- break;
- }
-
- Tcl_PrintDouble(NULL, pos, valueString);
- Tcl_DStringAppendElement(&cmdString, "moveto");
- Tcl_DStringAppendElement(&cmdString, valueString);
- }
-
- interp = scrollPtr->info.interp;
- code = Tcl_EvalEx(interp, cmdString.string, -1, TCL_EVAL_GLOBAL);
- if (code != TCL_OK && code != TCL_CONTINUE && code != TCL_BREAK) {
- Tcl_AddErrorInfo(interp, "\n (scrollbar command)");
- Tcl_BackgroundException(interp, code);
- }
- Tcl_DStringFree(&cmdString);
-
- Tcl_ServiceAll();
- return 0;
- }
-
- default:
- if (Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
- return result;
- }
- }
- return CallWindowProc(scrollPtr->oldProc, hwnd, message, wParam, lParam);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TkpConfigureScrollbar --
- *
- * This procedure is called after the generic code has finished
- * processing configuration options, in order to configure platform
- * specific options.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-void
-TkpConfigureScrollbar(
- register TkScrollbar *scrollPtr)
- /* Information about widget; may or may not
- * already have values for some fields. */
-{
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * ModalLoop --
- *
- * This function is invoked in response to a ButtonPress event.
- * It resends the event to the Scrollbar window procedure,
- * which in turn enters a modal loop.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-ModalLoop(
- WinScrollbar *scrollPtr,
- XEvent *eventPtr)
-{
- int oldMode;
-
- if (scrollPtr->hwnd) {
- Tcl_Preserve((ClientData)scrollPtr);
- scrollPtr->winFlags |= IN_MODAL_LOOP;
- oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
- TkWinResendEvent(scrollPtr->oldProc, scrollPtr->hwnd, eventPtr);
- (void) Tcl_SetServiceMode(oldMode);
- scrollPtr->winFlags &= ~IN_MODAL_LOOP;
- if (scrollPtr->hwnd && scrollPtr->winFlags & ALREADY_DEAD) {
- DestroyWindow(scrollPtr->hwnd);
- }
- Tcl_Release((ClientData)scrollPtr);
- }
-}
-
-/*
- *--------------------------------------------------------------
- *
- * TkpScrollbarPosition --
- *
- * Determine the scrollbar element corresponding to a given position.
- *
- * Results:
- * One of TOP_ARROW, TOP_GAP, etc., indicating which element of the
- * scrollbar covers the position given by (x, y). If (x,y) is outside the
- * scrollbar entirely, then OUTSIDE is returned.
- *
- * Side effects:
- * None.
- *
- *--------------------------------------------------------------
- */
-
-int
-TkpScrollbarPosition(
- register TkScrollbar *scrollPtr,
- /* Scrollbar widget record. */
- int x, int y) /* Coordinates within scrollPtr's window. */
-{
- int length, width, tmp;
-
- if (scrollPtr->vertical) {
- length = Tk_Height(scrollPtr->tkwin);
- width = Tk_Width(scrollPtr->tkwin);
- } else {
- tmp = x;
- x = y;
- y = tmp;
- length = Tk_Width(scrollPtr->tkwin);
- width = Tk_Height(scrollPtr->tkwin);
- }
-
- if ((x < scrollPtr->inset) || (x >= (width - scrollPtr->inset))
- || (y < scrollPtr->inset) || (y >= (length - scrollPtr->inset))) {
- return OUTSIDE;
- }
-
- /*
- * All of the calculations in this procedure mirror those in
- * TkpDisplayScrollbar. Be sure to keep the two consistent.
- */
-
- if (y < (scrollPtr->inset + scrollPtr->arrowLength)) {
- return TOP_ARROW;
- }
- if (y < scrollPtr->sliderFirst) {
- return TOP_GAP;
- }
- if (y < scrollPtr->sliderLast) {
- return SLIDER;
- }
- if (y >= (length - (scrollPtr->arrowLength + scrollPtr->inset))) {
- return BOTTOM_ARROW;
- }
- return BOTTOM_GAP;
-}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */