home *** CD-ROM | disk | FTP | other *** search
- /*
- ==============================================================================
- Project: POV-Ray
-
- Version: 3
-
- File Name: Printf2Window.c
-
- Description:
- General-purpose printf-capturing routines that allow a console-like
- output window for c programs that otherwise prefer to use printf/fprintf.
- This code was "inspired heavily" from sources such as MacDTS'es TESample,
- MacApp's Transcript window, and previous code of mine. It is fairly well
- self-contained, and works in MPW C 3.2 and Think C 5.0.
-
- This is the main source file, containing the private definitions and
- code to implement all the needed external and internal support functions.
-
- Related Files:
- Stdio_p2w.h - generic header for sources that would otherwise use <stdio.h>
- Printf2Window.h - Mac-specific header for p2w routines
- Printf2Window.c - the main source for the p2w routines
- ------------------------------------------------------------------------------
- Author:
- Eduard [esp] Schwan
- ------------------------------------------------------------------------------
- from Persistence of Vision(tm) Ray Tracer
- Copyright 1996 Persistence of Vision Team
- ------------------------------------------------------------------------------
- NOTICE: This source code file is provided so that users may experiment
- with enhancements to POV-Ray and to port the software to platforms other
- than those supported by the POV-Ray Team. There are strict rules under
- which you are permitted to use this file. The rules are in the file
- named POVLEGAL.DOC which should be distributed with this file. If
- POVLEGAL.DOC is not available or for more info please contact the POV-Ray
- Team Coordinator by leaving a message in CompuServe's Graphics Developer's
- Forum. The latest version of POV-Ray may be found there as well.
-
- This program is based on the popular DKB raytracer version 2.12.
- DKBTrace was originally written by David K. Buck.
- DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
- ------------------------------------------------------------------------------
- Change History:
- 920318 [esp] Created.
- 920325 [esp] Added init/Terminate, major redesign of std c fns.
- 920327 [esp] Robustized AddCString code that handles TERec-is-full delete logic
- 920329 [esp] Added AdjustScrollBars call in AddCString to update scrollers as text is added
- 920330 [esp] Updated file header with copyright & related files info
- 920401 [esp] Added p2wSignature to window record for safety checking
- 920402 [esp] Fixed cr/lf bug in bottleneck routine
- 920412 [esp] Fixed potential integer overflow in comparison in AddCString routine
- 920412 [esp] Added most function header comments, added windBounds support in Newp2wWindow, fixed scroller activate bug
- 920413 [esp] Fixed misbehavin' scrollbars hilite upon activate/deactivate
- 920521 [esp] Made the non-resource based code work.
- 920529 [esp] Changed type defs to have trailing _t for ANSI consistency
- 920529 [esp] Added p2w_SetTextFont function to allow easy fontsize switching
- 920603 [esp] Initialized newly alloc'ed ctrls to VISIBLE
- 920816 [esp] Added p2w_SelectAll routine
- 920901 [esp] reduced kMaxTELength to 32000 so TeachText doesn't choke on >32000 sized files!
- 920905 [esp] Fixed scrollbars so they're inactive on window creation.
- 920912 [esp] Added windID parm to NewWindow call
- 921011 [esp] Updated bottleneck to handle fopen() file I/O too (pass-through)
- 921128 [esp] Fixed bug in p2w_fputs: the newline went to stdout, not stream!
- 931001 [esp] version 2.0 finished (Released on 10/4/93)
- 931119 [djh] 2.0.1 conditionally compiles for PPC machines, keyword __powerc
- 940416 [PFS] 2.2.1 greatly reworked to clean up PPC support and provide CodeWarrior projects
- 940430 [esp] Preliminary 3.0a1 work
- 950825 [esp] Fixed to ignore various control chars (like backspace)
- 951226 [esp] Fixed activate/deactivate aesthetic bugs, started updating toolbox names
- ==============================================================================
- */
-
- #include "printf2window.h" /* our defs AND stdio.h for sprintf, etc. */
- #include "screenUtils.h" /* GetMaxGrowRect */
-
- /* Standard C library headers */
- #include <stdarg.h> // ANSI C variable length argument support
- #include <string.h> // strlen
-
- /* Macintosh-specific headers */
- #include <Types.h>
- #include <Controls.h>
- #include <Dialogs.h>
- #include <Files.h>
- #include <Memory.h>
- #include <OSUtils.h>
- #include <Resources.h>
- #include <Windows.h>
- #include <Scrap.h>
-
- #if !defined(THINK_C)
- #include <strings.h> /*p2cstr*/
- #endif // THINK_C
-
-
- #if defined(powerc) || defined (__powerc)
- // even Apple has fixed this... no longer needed
- // extern QDGlobals qd;
- #endif
-
- // ==== Constant definitions
-
- // Comment USE_P2W_RESOURCES out to create the controls from scratch..
- // Leave it in to create them from resources
-
- // #define USE_P2W_RESOURCES true
-
-
- // Resource IDs of supporting p2w resources
-
- #if defined(USE_P2W_RESOURCES)
- #define kp2w_VScrollID 9601
- #define kp2w_HScrollID 9602
- #endif // USE_P2W_RESOURCES
-
-
- // Magic p2w window record signature value
-
- #define kp2wWindowSignature 'p2w '
-
-
- // kTextMargin is the number of pixels we leave blank at the edge of the window.
-
- #define kTextMargin 2
-
-
- // kControlInvisible is used to 'turn off' controls (i.e., cause the control not
- // to be redrawn as a result of some Control Manager call such as SetControlValue)
- // by being put into the contrlVis field of the record. kControlVisible is used
- // the same way to 'turn on' the control.
-
- #define kControlInvisible 0
- #define kControlVisible 0xFF
-
-
- // kControlHiliteActive is used to activate controls (contrlHilite)
- // kControlHiliteInactive is used to deactivate controls (contrlHilite)
-
- #define kControlHiliteActive 0
- #define kControlHiliteInactive 0xFF
-
-
- // kButtonScroll is how many pixels to scroll horizontally when the button part
- // of the horizontal scrollbar is pressed.
-
- #define kButtonScroll 4
-
- // kScrollbarAdjust and kScrollbarWidth are used in calculating
- // values for control positioning and sizing.
-
- #define kScrollbarWidth 16
- #define kScrollbarAdjust (kScrollbarWidth - 1)
-
-
- // kScrollTweek compensates for off-by-one requirements of the scrollbars
- // to have borders coincide with the growbox.
-
- #define kScrollTweek 2
-
-
- // kMaxTELength is an arbitrary number used to limit the length of text in the TERec
- // so that various errors won't occur from too many characters in the text. When the
- // string to be added exceeds kMaxTELength, then strlen+kTEDeleteChunkSize
- // characters will be deleted from the beginning of the TERec. This lets the TE
- // buffer stay pretty full while characters "fall off the top" of the buffer, and
- // insures that the performance delay of deleting from the front of the buffer
- // only happens every once in awhile, instead of for every single additional
- // string added. kTEDeleteChunkSize should probably be between 1k and 20k..
-
- #define kMaxTELength 32000 // 32000 is pretty close to 32767, OK SimpleText?
- #define kTEDeleteChunkSize 6000 // should be between 1000 and 20000
-
-
- // kMinDocSize is the smallest horiz/vert size of a grown window.
-
- #define kMinDocSize 100
-
-
- // kMaxStdIOBuffSize is the largest supported size of a single formatted
- // stdio C string. Note that internally, a relocatable buffer of this size
- // will be allocated.
-
- #define kMaxStdIOBuffSize 1024
-
-
- // internal macro definitions
-
- // Define some structure accessing macros for efficiency.
- #define GET_HIWORD(aLong) (((aLong)>>16)&0x0FFFFL)
- #define GET_LOWORD(aLong) ((aLong)&0x0FFFFL)
- #define GET_TOPLEFT_POINT(aRect) (*(Point*)&(aRect).top)
- #define GET_BOTRIGHT_POINT(aRect) (*(Point*)&(aRect).bottom)
- #define GET_RECT_WIDTH(aRect) ((aRect).right - (aRect).left)
- #define GET_RECT_HEIGHT(aRect) ((aRect).bottom - (aRect).top)
- #define IS_P2W_WINDOW(p2wPtr) (((p2w_WindowPtr_t)p2wPtr)->p2wSignature == kp2wWindowSignature)
-
- /*
- ----------------------------------
- prototypes for internal routines
- ----------------------------------
- */
-
- static void p2wi_GetTERect(const p2w_WindowPtr_t thep2wWindow, Rect *teRect);
- static void p2wi_AdjustTE(const p2w_WindowPtr_t thep2wWindow);
- static void p2wi_AdjustViewRect(TEHandle p2wTE);
- static void p2wi_CommonAdjustScroller(const Boolean isVert, const p2w_WindowPtr_t thep2wWindow,
- ControlHandle control, TEHandle theTEHandle/*, const Boolean canRedraw*/);
- static void p2wi_AdjustScrollValues(const p2w_WindowPtr_t thep2wWindow/*, const Boolean doRedraw*/);
- static void p2wi_AdjustScrollSizes(const p2w_WindowPtr_t thep2wWindow);
- static void p2wi_AdjustScrollbars(const p2w_WindowPtr_t thep2wWindow, const Boolean doResize);
- static void p2wi_ResizeWindow(const p2w_WindowPtr_t thep2wWindow);
- static void p2wi_GetLocalUpdateRegion(const p2w_WindowPtr_t thep2wWindow, RgnHandle localRgn);
- static void p2wi_CommonScrollAction(ControlHandle control, short *amount);
- pascal void p2wi_VScrollActionProc(ControlHandle control, short part);
- pascal void p2wi_HScrollActionProc(ControlHandle control, short part);
- static int p2wi_StdCOut_BottleNeck(FILE *stream);
- static int p2wi_vfprintf(FILE *stream, const char *format, va_list va_args);
-
-
-
- /*
- ----------------------------------
- global variable definitions
- ----------------------------------
- */
-
- static Handle p2w_Stdio_OutBuf_Hdl = NULL;
- static p2w_WindowPtr_t local_p2wWindow = NULL;
-
- static ControlActionUPP p2wi_VScrollActionUPP = NULL;
- static ControlActionUPP p2wi_HScrollActionUPP = NULL;
-
-
- /*---------------------------------------------------------------------*/
- /*==== Main interface routines ====*/
-
-
- /*
- ******************************************************************************
- Name:
- p2w_Init
- ------------------------------------------------------------------------------
- Purpose:
- Primary (one-time) initialization of the p2w routines
- ------------------------------------------------------------------------------
- Description:
- pre-allocates internal storage & initializes variables
- ------------------------------------------------------------------------------
- Parameters:
- void
- ------------------------------------------------------------------------------
- When Used:
- Called once, when the application starts up
- ******************************************************************************
- */
- OSErr p2w_Init(void)
- {
- OSErr anError = noErr;
-
- // allocate an output character stream buffer to use
- p2w_Stdio_OutBuf_Hdl = NewHandle(kMaxStdIOBuffSize + sizeof(short));
- anError = MemError();
- local_p2wWindow = NULL;
-
- p2wi_VScrollActionUPP = NewControlActionProc(p2wi_VScrollActionProc);
- p2wi_HScrollActionUPP = NewControlActionProc(p2wi_HScrollActionProc);
-
- return anError;
- } // p2w_Init
-
-
-
- /*
- ******************************************************************************
- Name:
- p2w_Terminate
- ------------------------------------------------------------------------------
- Purpose:
- Primary (one-time) destruction of the p2w routines
- ------------------------------------------------------------------------------
- Description:
- de-allocates internal storage & invalidates variables
- ------------------------------------------------------------------------------
- Parameters:
- void
- ------------------------------------------------------------------------------
- When Used:
- Called once, when the application is shutting down
- ******************************************************************************
- */
- OSErr p2w_Terminate(void)
- {
- OSErr anError = noErr;
-
- if (p2w_Stdio_OutBuf_Hdl)
- {
- DisposeHandle(p2w_Stdio_OutBuf_Hdl);
- anError = MemError();
- }
- p2w_Stdio_OutBuf_Hdl = NULL;
- local_p2wWindow = NULL;
-
- return anError;
- } // p2w_Terminate
-
-
-
- /*
- ******************************************************************************
- Name:
- p2w_NewWindow
- ------------------------------------------------------------------------------
- Purpose:
- Creates a new p2w window structure for use by other p2w routines.
- ------------------------------------------------------------------------------
- Description:
- Creates a p2w window (either from resources or from parameters),
- initializes it, and shows it if asked.
- ------------------------------------------------------------------------------
- Parameters:
- windID if 0, create window from scratch, if > 0, use as ID for GetNewWindow
- windBoundsPtr Where to place the new window on the screen.
- If NULL, the resource bounds will be used.
- windTitle The Pascal title string to use for the new window.
- If NULL, resource title will be used.
- windIsVisible TRUE will show window after creation, FALSE will leave hidden.
- windFont Text Font to use for new window.
- windFontSize Text Font Size tose for new window.
- anError Returns any error code, or zero (noErr) if all went OK.
- ------------------------------------------------------------------------------
- When Used:
- Called when a new p2w window needs to be allocated. It may or may not
- be shown at this time. It will be opened in the back. This call mainly
- creates the window structures.
- ******************************************************************************
- */
- p2w_WindowPtr_t p2w_NewWindow( const short windID,
- const Rect *windBoundsPtr,
- const Str255 windTitle,
- const Boolean windIsVisible,
- const int windFont,
- const short windFontSize,
- OSErr *anError)
- {
- WindowPtr aWindow;
- Rect destRect, viewRect, screenRect;
- p2w_WindowPtr_t p2wWPtr = NULL;
- GrafPtr savedPort;
-
- GetPort(&savedPort); // I'll be back..
-
- /* how big is the screen */
- screenRect = qd.screenBits.bounds;
-
- /* allocate space for our extended p2window record */
- p2wWPtr = (p2w_WindowPtr_t)NewPtr(sizeof(p2w_WindowRecord_t));
- *anError = MemError();
- if (!*anError)
- {
- // initialize the p2w record
-
- p2wWPtr->p2wSignature = kp2wWindowSignature; // bless this special window record
- p2wWPtr->p2wOpenedOK = false; // until actually opened later
- p2wWPtr->p2wTEHandle = NULL;
- p2wWPtr->p2wVScroller = NULL;
- p2wWPtr->p2wHScroller = NULL;
- p2wWPtr->p2wClickHandler = NULL;
- p2wWPtr->p2wMaxDocWidth = GET_RECT_WIDTH(screenRect) - kScrollbarWidth - 2*kTextMargin - 10;
- p2wWPtr->p2wAlwaysScrollToBottom = true;
-
- /* now create the Window */
- if (windID > 0)
- { // get from resource
- aWindow = GetNewWindow(windID, p2wWPtr, (WindowPtr)NULL);
- *anError = ResError();
- }
- else
- { // Create from scratch, also moves/sizes appropriately
- aWindow = NewWindow(p2wWPtr, windBoundsPtr, windTitle, windIsVisible, documentProc,
- (WindowPtr)NULL, false/*hasGoAway*/, 0/*refcon*/);
- *anError = MemError();
- }
- }
-
- /* Move the window to user-specified position? */
- /* Do this only if getting from resources - already done (above) otherwise */
- if (windID > 0)
- {
- if ((!*anError) && (windBoundsPtr != NULL))
- {
- MoveWindow(aWindow, (*windBoundsPtr).left, (*windBoundsPtr).top, false);
- SizeWindow(aWindow, GET_RECT_WIDTH(*windBoundsPtr), GET_RECT_HEIGHT(*windBoundsPtr), false);
- }
- }
-
- if (!*anError)
- {
- // now its OK to call CloseWindow later..
- p2wWPtr->p2wOpenedOK = true;
-
- SetPort(aWindow);
-
- /* Set its title to what the user passed in, if non-null */
- /* Do this only if getting from resources - already done (above) otherwise */
- if (windID > 0)
- if (windTitle) // not a NULL pointer?
- if (*windTitle) // not an empty string?
- SetWTitle(aWindow, windTitle); // then do it!
-
- /* set up the font in the port */
- p2w_SetTextFont(p2wWPtr, windFont, windFontSize);
-
- /* set up the EditText buffer & area */
- p2wi_GetTERect(p2wWPtr, &viewRect);
- destRect = viewRect;
- destRect.right = destRect.left + p2wWPtr->p2wMaxDocWidth;
- p2wWPtr->p2wTEHandle = TENew(&destRect, &viewRect);
- *anError = MemError();
- }
-
- if (!*anError)
- {
- p2wi_AdjustViewRect(p2wWPtr->p2wTEHandle);
- }
-
- /* Create vertical scrollbar */
- if (!*anError)
- {
- #if defined(USE_P2W_RESOURCES)
- p2wWPtr->p2wVScroller = GetNewControl(kp2w_VScrollID, aWindow);
- *anError = ResError();
- #else
- p2wWPtr->p2wVScroller = NewControl(aWindow, &(*aWindow).portRect, "\pp2w_Vert", false, 0, 0, 1, scrollBarProc, 0);
- *anError = MemError();
- #endif // USE_P2W_RESOURCES
- }
-
- /* Create horizontal scrollbar */
- if (!*anError)
- {
- #if defined(USE_P2W_RESOURCES)
- p2wWPtr->p2wHScroller = GetNewControl(kp2w_HScrollID, aWindow);
- *anError = ResError();
- #else
- p2wWPtr->p2wHScroller = NewControl(aWindow, &(*aWindow).portRect, "\pp2w_Horz", false, 0, 0, 1, scrollBarProc, 0);
- *anError = MemError();
- #endif // USE_P2W_RESOURCES
- }
-
- // adjust & draw the controls, draw the window
- if (!*anError)
- {
- // turn on auto-scrolling and outline hilighting
- TEDeactivate(p2wWPtr->p2wTEHandle);
- /*
- turn on autoscrolling if/when we add a clickloop proc...
- (void)TEFeatureFlag(teFAutoScr, teBitSet, p2wWPtr->p2wTEHandle);
- */
- (void)TEFeatureFlag(teFOutlineHilite, teBitSet, p2wWPtr->p2wTEHandle);
- p2wi_AdjustScrollbars(p2wWPtr, true/*kResize*/);
- // Our window comes up in back, so turn OFF visibility of scrollbar initially
- HideControl(p2wWPtr->p2wVScroller);
- HideControl(p2wWPtr->p2wHScroller);
- if (windIsVisible)
- ShowWindow(aWindow);
- }
-
- // Return to port after storm
- SetPort(savedPort); // I'm back..
-
- // close & dispose if any errors happened!
- if (*anError)
- {
- p2w_DisposeWindow(p2wWPtr);
- // if errors happened, don't give user any pointers
- p2wWPtr = NULL;
- }
-
- // remember this for the StdIO routines later..
- local_p2wWindow = p2wWPtr;
-
- return (p2wWPtr);
-
- } // p2w_NewWindow
-
-
-
- /*
- ******************************************************************************
- Name:
- p2w_DisposeWindow
- ------------------------------------------------------------------------------
- Purpose:
- Deletes an existing p2w window structure and its related TE danglies.
- ------------------------------------------------------------------------------
- Description:
- Disposes of the TE record, closes the window/grafport, and disposes
- of the window/grafport itself.
- ------------------------------------------------------------------------------
- Parameters:
- the_p2wPtr The p2w window to dispose.
- ------------------------------------------------------------------------------
- When Used:
- Called when a p2w window is no longer needed.
- ******************************************************************************
- */
- void p2w_DisposeWindow(p2w_WindowPtr_t the_p2wPtr)
- {
- // Is the window pointer not null?
- if (the_p2wPtr)
- // is this really one of our p2w windows?
- // (We don't want to dispose extra stuff if it's really
- // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
- if (IS_P2W_WINDOW(the_p2wPtr))
- {
- // Dispose Window/GrafPort danglies if opened ok
- if (the_p2wPtr->p2wOpenedOK)
- CloseWindow((WindowPtr)the_p2wPtr);
- // Dispose of our TE Record
- if (the_p2wPtr->p2wTEHandle)
- TEDispose(the_p2wPtr->p2wTEHandle);
- // set fields back to nil, to help catch anyone touching them after dispose!
- the_p2wPtr->p2wOpenedOK = false;
- the_p2wPtr->p2wTEHandle = NULL;
- the_p2wPtr->p2wVScroller = NULL;
- the_p2wPtr->p2wHScroller = NULL;
- the_p2wPtr->p2wClickHandler = NULL;
- // Dispose our version of window record itself now
- DisposePtr((Ptr)the_p2wPtr);
- local_p2wWindow = NULL;
- }
- } // p2w_DisposeWindow
-
-
- /*
- ******************************************************************************
- Name:
- p2w_SetTextFont
- ------------------------------------------------------------------------------
- Purpose:
- Changes the Font Type and Size in the p2w window.
- ------------------------------------------------------------------------------
- Description:
- ------------------------------------------------------------------------------
- Parameters:
- the_p2wPtr The p2w window to update.
- newFontType The Font type to change to (monaco, courier, times, etc.)
- newFontSize The Font type to change to (9,10,12,etc.)
- ------------------------------------------------------------------------------
- When Used:
- Called when text is to be added to the p2w window.
- ******************************************************************************
- */
- void p2w_SetTextFont
- ( p2w_WindowPtr_t the_p2wPtr,
- short newFontType,
- short newFontSize)
- {
- GrafPtr savedPort;
-
- GetPort(&savedPort); // I'll be back..
-
- // is this really one of our p2w windows?
- // (We don't want to fiddle with extra stuff if it's really
- // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
- if (IS_P2W_WINDOW(the_p2wPtr))
- {
- // Tell our grafport that we have a new font
- SetPort((GrafPtr)the_p2wPtr);
- TextFont(newFontType);
- TextSize(newFontSize);
-
- // Tell our TextEdit record that we have a new font..
- if (the_p2wPtr->p2wTEHandle != NULL)
- { // TE Record is valid
- (**the_p2wPtr->p2wTEHandle).txFont = newFontType;
- (**the_p2wPtr->p2wTEHandle).txSize = newFontSize;
- // let the TE adjust to this new font!
- TECalText(the_p2wPtr->p2wTEHandle);
- TEUpdate(&the_p2wPtr->p2wWindowRec.port.portRect,the_p2wPtr->p2wTEHandle);
- }
- }
- // Return to port after storm
- SetPort(savedPort); // I'm back..
-
- } // p2w_SetTextFont
-
- /*
- ******************************************************************************
- Name:
- p2w_AlwaysScrollToBottom
- ------------------------------------------------------------------------------
- Purpose:
- Changes behavior of p2w to stay put, or always scroll to bottom
- ------------------------------------------------------------------------------
- Description:
- ------------------------------------------------------------------------------
- Parameters:
- the_p2wPtr The p2w window to update.
- ------------------------------------------------------------------------------
- When Used:
- Called when you want to set whether it always scrolls to bottom
- ******************************************************************************
- */
- void p2w_AlwaysScrollToBottom(p2w_WindowPtr_t the_p2wPtr, Boolean alwaysScroll)
- {
- if (the_p2wPtr) // if window ptr is valid
- // is this really one of our p2w windows?
- // (We don't want to fiddle with extra stuff if it's really
- // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
- if (IS_P2W_WINDOW(the_p2wPtr) && the_p2wPtr->p2wVScroller)
- {
- the_p2wPtr->p2wAlwaysScrollToBottom = alwaysScroll;
- }
- }
-
- /*
- ******************************************************************************
- Name:
- p2w_AlwaysScrollToBottomState
- ------------------------------------------------------------------------------
- Purpose:
- Changes behavior of p2w to stay put, or always scroll to bottom
- ------------------------------------------------------------------------------
- Description:
- ------------------------------------------------------------------------------
- Parameters:
- the_p2wPtr The p2w window to update.
- ------------------------------------------------------------------------------
- When Used:
- Called when you want to find out whether it always scrolls to bottom
- ******************************************************************************
- */
- Boolean p2w_AlwaysScrollToBottomState(p2w_WindowPtr_t the_p2wPtr)
- {
- if (the_p2wPtr) // if window ptr is valid
- // is this really one of our p2w windows?
- // (We don't want to fiddle with extra stuff if it's really
- // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
- if (IS_P2W_WINDOW(the_p2wPtr) && the_p2wPtr->p2wVScroller)
- {
- return the_p2wPtr->p2wAlwaysScrollToBottom;
- }
- return false;
- }
-
- /*
- ******************************************************************************
- Name:
- p2w_ScrollHome
- ------------------------------------------------------------------------------
- Purpose:
- Forcese the p2w window to scroll to the top and redraw.
- ------------------------------------------------------------------------------
- Description:
- ------------------------------------------------------------------------------
- Parameters:
- the_p2wPtr The p2w window to update.
- ------------------------------------------------------------------------------
- When Used:
- Called when you want to force the window to display the top of the text.
- ******************************************************************************
- */
- void p2w_ScrollHome(p2w_WindowPtr_t the_p2wPtr)
- {
- short controlMin,controlVal;
- int scrollAmt;
-
- if (the_p2wPtr) // if window ptr is valid
- // is this really one of our p2w windows?
- // (We don't want to fiddle with extra stuff if it's really
- // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
- if (IS_P2W_WINDOW(the_p2wPtr) && the_p2wPtr->p2wVScroller)
- {
- // get current scroll settings
- controlMin = GetControlMinimum(the_p2wPtr->p2wVScroller);
- controlVal = GetControlValue(the_p2wPtr->p2wVScroller);
-
- // calculate how far to scroll to get back to the top
- scrollAmt = controlVal-controlMin;
- if (scrollAmt>0)
- {
- // set scrollbar to top/min
- SetControlValue(the_p2wPtr->p2wVScroller, controlMin);
- // scroll the TE record to match the scrollbars
- p2wi_AdjustTE(the_p2wPtr);
- // re-draw the scrollbars, forcing them to go to the top
- p2wi_AdjustScrollbars(the_p2wPtr, true); // force redraw
- }
- }
- }
-
- /*
- ******************************************************************************
- Name:
- p2w_ScrollEnd
- ------------------------------------------------------------------------------
- Purpose:
- Forcese the p2w window to scroll to the bottom and redraw.
- ------------------------------------------------------------------------------
- Description:
- ------------------------------------------------------------------------------
- Parameters:
- the_p2wPtr The p2w window to update.
- ------------------------------------------------------------------------------
- When Used:
- Called when you want to force the window to display the end of the text.
- ******************************************************************************
- */
- void p2w_ScrollEnd(p2w_WindowPtr_t the_p2wPtr)
- {
- short controlMax,controlVal;
- int scrollAmt;
-
- if (the_p2wPtr) // if window ptr is valid
- // is this really one of our p2w windows?
- // (We don't want to fiddle with extra stuff if it's really
- // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
- if (IS_P2W_WINDOW(the_p2wPtr) && the_p2wPtr->p2wVScroller)
- {
- // get current scroll settings
- controlMax = GetControlMaximum(the_p2wPtr->p2wVScroller);
- controlVal = GetControlValue(the_p2wPtr->p2wVScroller);
-
- // calculate how far to scroll to get back to the top
- scrollAmt = controlMax-controlVal;
- if (scrollAmt>0)
- {
- // set scrollbar to top/min
- SetControlValue(the_p2wPtr->p2wVScroller, controlMax);
- // scroll the TE record to match the scrollbars
- p2wi_AdjustTE(the_p2wPtr);
- // re-draw the scrollbars, forcing them to go to the top
- p2wi_AdjustScrollbars(the_p2wPtr, true); // force redraw
- }
- }
- }
-
-
- /*
- ******************************************************************************
- Name:
- p2w_ScrollPageUp
- ------------------------------------------------------------------------------
- Purpose:
- Forces the p2w window to scroll a page.
- ------------------------------------------------------------------------------
- Description:
- ------------------------------------------------------------------------------
- Parameters:
- the_p2wPtr The p2w window to scroll.
- ------------------------------------------------------------------------------
- When Used:
- ******************************************************************************
- */
- void p2w_ScrollPageUp(p2w_WindowPtr_t the_p2wPtr)
- {
- if (the_p2wPtr) // if window ptr is valid
- // is this really one of our p2w windows?
- // (We don't want to fiddle with extra stuff if it's really
- // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
- if (IS_P2W_WINDOW(the_p2wPtr) && the_p2wPtr->p2wVScroller)
- {
- // Pretend to click page-up
- p2wi_VScrollActionProc(the_p2wPtr->p2wVScroller, kControlPageUpPart);
- }
- }
-
-
- /*
- ******************************************************************************
- Name:
- p2w_ScrollPageDown
- ------------------------------------------------------------------------------
- Purpose:
- Forces the p2w window to scroll a page.
- ------------------------------------------------------------------------------
- Description:
- ------------------------------------------------------------------------------
- Parameters:
- the_p2wPtr The p2w window to scroll.
- ------------------------------------------------------------------------------
- When Used:
- ******************************************************************************
- */
- void p2w_ScrollPageDown(p2w_WindowPtr_t the_p2wPtr)
- {
- if (the_p2wPtr) // if window ptr is valid
- // is this really one of our p2w windows?
- // (We don't want to fiddle with extra stuff if it's really
- // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
- if (IS_P2W_WINDOW(the_p2wPtr) && the_p2wPtr->p2wVScroller)
- {
- // Pretend to click page-up
- p2wi_VScrollActionProc(the_p2wPtr->p2wVScroller, kControlPageDownPart);
- }
- }
-
-
- /*
- ******************************************************************************
- Name:
- p2w_ScrollLineUp
- ------------------------------------------------------------------------------
- Purpose:
- Forces the p2w window to scroll a line.
- ------------------------------------------------------------------------------
- Description:
- ------------------------------------------------------------------------------
- Parameters:
- the_p2wPtr The p2w window to scroll.
- ------------------------------------------------------------------------------
- When Used:
- ******************************************************************************
- */
- void p2w_ScrollLineUp(p2w_WindowPtr_t the_p2wPtr)
- {
- if (the_p2wPtr) // if window ptr is valid
- // is this really one of our p2w windows?
- // (We don't want to fiddle with extra stuff if it's really
- // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
- if (IS_P2W_WINDOW(the_p2wPtr) && the_p2wPtr->p2wVScroller)
- {
- // Pretend to click page-up
- p2wi_VScrollActionProc(the_p2wPtr->p2wVScroller, kControlUpButtonPart);
- }
- }
-
-
- /*
- ******************************************************************************
- Name:
- p2w_ScrollLineDown
- ------------------------------------------------------------------------------
- Purpose:
- Forces the p2w window to scroll a line.
- ------------------------------------------------------------------------------
- Description:
- ------------------------------------------------------------------------------
- Parameters:
- the_p2wPtr The p2w window to scroll.
- ------------------------------------------------------------------------------
- When Used:
- ******************************************************************************
- */
- void p2w_ScrollLineDown(p2w_WindowPtr_t the_p2wPtr)
- {
- if (the_p2wPtr) // if window ptr is valid
- // is this really one of our p2w windows?
- // (We don't want to fiddle with extra stuff if it's really
- // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
- if (IS_P2W_WINDOW(the_p2wPtr) && the_p2wPtr->p2wVScroller)
- {
- // Pretend to click page-up
- p2wi_VScrollActionProc(the_p2wPtr->p2wVScroller, kControlDownButtonPart);
- }
- }
-
-
- /*
- ******************************************************************************
- Name:
- p2w_ScrollLeft
- ------------------------------------------------------------------------------
- Purpose:
- Forces the p2w window to scroll left.
- ------------------------------------------------------------------------------
- Description:
- ------------------------------------------------------------------------------
- Parameters:
- the_p2wPtr The p2w window to scroll.
- ------------------------------------------------------------------------------
- When Used:
- ******************************************************************************
- */
- void p2w_ScrollLeft(p2w_WindowPtr_t the_p2wPtr)
- {
- if (the_p2wPtr) // if window ptr is valid
- // is this really one of our p2w windows?
- // (We don't want to fiddle with extra stuff if it's really
- // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
- if (IS_P2W_WINDOW(the_p2wPtr) && the_p2wPtr->p2wHScroller)
- {
- // Pretend to click left arrow
- p2wi_HScrollActionProc(the_p2wPtr->p2wHScroller, kControlUpButtonPart);
- }
- }
-
-
- /*
- ******************************************************************************
- Name:
- p2w_ScrollRight
- ------------------------------------------------------------------------------
- Purpose:
- Forces the p2w window to scroll right.
- ------------------------------------------------------------------------------
- Description:
- ------------------------------------------------------------------------------
- Parameters:
- the_p2wPtr The p2w window to scroll.
- ------------------------------------------------------------------------------
- When Used:
- ******************************************************************************
- */
- void p2w_ScrollRight(p2w_WindowPtr_t the_p2wPtr)
- {
- if (the_p2wPtr) // if window ptr is valid
- // is this really one of our p2w windows?
- // (We don't want to fiddle with extra stuff if it's really
- // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
- if (IS_P2W_WINDOW(the_p2wPtr) && the_p2wPtr->p2wHScroller)
- {
- // Pretend to click page-up
- p2wi_HScrollActionProc(the_p2wPtr->p2wHScroller, kControlDownButtonPart);
- }
- }
-
-
- /*
- ******************************************************************************
- Name:
- p2w_AddCString
- ------------------------------------------------------------------------------
- Purpose:
- Adds the text in the C-style string passed to the p2w window.
- ------------------------------------------------------------------------------
- Description:
- ------------------------------------------------------------------------------
- Parameters:
- the_p2wPtr The p2w window to add to.
- theCStrPtr The string of text to add.
- p2w_AddCString function returns zero if ok, or an error #.
- ------------------------------------------------------------------------------
- When Used:
- Called when text is to be added to the p2w window.
- ******************************************************************************
- */
- OSErr p2w_AddCString(p2w_WindowPtr_t the_p2wPtr, const char * theCStrPtr, short size)
- {
- OSErr anError = noErr;
- long oldStart, oldEnd;
-
- if (the_p2wPtr && theCStrPtr) // if window and string ptrs are valid
- // is this really one of our p2w windows?
- // (We don't want to fiddle with extra stuff if it's really
- // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
- if (IS_P2W_WINDOW(the_p2wPtr))
- if (the_p2wPtr->p2wTEHandle)
- { // TE Record is valid
- if (size > 0) // if string is not empty, add it
- {
- // If TE is too full, need to delete some at beginning before adding
- // (this looks weird, but it is the Mathematically Correct way to
- // compare numbers close to the edge of 32767-land.. note that
- // teLength+size could overflow, so we subtract instead.)
- if ((**(the_p2wPtr->p2wTEHandle)).teLength > (kMaxTELength - size))
- {
- // Delete some text at beginning of TE
- TESetSelect(0, size+kTEDeleteChunkSize, the_p2wPtr->p2wTEHandle);
- TEDelete(the_p2wPtr->p2wTEHandle);
- }
- // Save selection start/end so we don't wipe out user's selection
- oldStart = (**the_p2wPtr->p2wTEHandle).selStart;
- oldEnd = (**the_p2wPtr->p2wTEHandle).selEnd;
- // go to very end of TE (-1 is really +65535 in TE Worlds!)
- TESetSelect(-1, -1, the_p2wPtr->p2wTEHandle);
- // stick it in there
- TEInsert(theCStrPtr, size, the_p2wPtr->p2wTEHandle);
- // restore user's selection before we redraw!
- (**the_p2wPtr->p2wTEHandle).selStart = oldStart;
- (**the_p2wPtr->p2wTEHandle).selEnd = oldEnd;
- // re-draw the scrollbars, since they may have changed
- p2wi_AdjustScrollbars(the_p2wPtr, true); // force redraw?
- /* now scroll the TE record to match the scrollbars */
- p2wi_AdjustTE(the_p2wPtr);
- } // size > 0
- } // TE Record is valid
- return(anError);
- } // p2w_AddCString
-
-
- /*
- ******************************************************************************
- Name:
- p2w_DrawWindow
- ------------------------------------------------------------------------------
- Purpose:
- Draw the contents of an application window.
- ------------------------------------------------------------------------------
- Description:
-
- ------------------------------------------------------------------------------
- Parameters:
-
- ------------------------------------------------------------------------------
- When Used:
-
- ******************************************************************************
- */
- void p2w_DrawWindow(const p2w_WindowPtr_t the_p2wPtr)
- {
- // is this really one of our p2w windows?
- // (We don't want to dispose extra stuff if it's really
- // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
- if (IS_P2W_WINDOW(the_p2wPtr))
- {
- // move in for the kill
- SetPort((WindowPtr)the_p2wPtr);
- // kill off old bits
- EraseRect(&((WindowPtr)the_p2wPtr)->portRect);
- // show them our text
- TEUpdate(&((WindowPtr)the_p2wPtr)->portRect, the_p2wPtr->p2wTEHandle);
- // redraw controls
- DrawControls((WindowPtr)the_p2wPtr);
- DrawGrowIcon((WindowPtr)the_p2wPtr);
- }
- } // p2w_DrawWindow
-
-
-
- /*
- ******************************************************************************
- Name:
- p2w_DoUpdate
- ------------------------------------------------------------------------------
- Purpose:
- Update (redraw) the contents of an application window.
- ------------------------------------------------------------------------------
- Description:
-
- ------------------------------------------------------------------------------
- Parameters:
-
- ------------------------------------------------------------------------------
- When Used:
-
- ******************************************************************************
- */
- void p2w_DoUpdate(const p2w_WindowPtr_t thep2wWindow)
- {
- // move in for the kill
- SetPort((WindowPtr)thep2wWindow);
- BeginUpdate((WindowPtr)thep2wWindow); /* this sets up the visRgn */
- if (!EmptyRgn(((WindowPtr)thep2wWindow)->visRgn)) /* draw if updating needs to be done */
- p2w_DrawWindow(thep2wWindow);
- EndUpdate((WindowPtr)thep2wWindow);
- } // p2w_DoUpdate
-
-
- /*
- ******************************************************************************
- Name:
- p2w_DoActivate
- ------------------------------------------------------------------------------
- Purpose:
- This is called when a window is activated or deactivated.
- It calls TextEdit to handle the selection.
- ------------------------------------------------------------------------------
- Description:
-
- ------------------------------------------------------------------------------
- Parameters:
-
- ------------------------------------------------------------------------------
- When Used:
-
- ******************************************************************************
- */
- void p2w_DoActivate(const p2w_WindowPtr_t thep2wWindow, Boolean becomingActive)
- {
-
- // is this really one of our p2w windows?
- // (We don't want to dispose extra stuff if it's really
- // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
- if (IS_P2W_WINDOW(thep2wWindow))
- {
- /* move in for the kill */
- SetPort((WindowPtr)thep2wWindow);
-
- if (becomingActive)
- {
- // RgnHandle tempRgn, clipRgn;
- // Rect growRect;
- // Since we don’t want TEActivate to draw a selection
- // in an area where we’re going to erase and redraw,
- // we’ll clip out the update region before calling it.
- /* don't do this...?
- tempRgn = NewRgn();
- clipRgn = NewRgn();
- if (tempRgn && clipRgn)
- {
- p2wi_GetLocalUpdateRegion(thep2wWindow, tempRgn); // get localized update region
- GetClip(clipRgn);
- DiffRgn(clipRgn, tempRgn, tempRgn); // subtract updateRgn from clipRgn
- SetClip(tempRgn);
- TEActivate(thep2wWindow->p2wTEHandle);
- SetClip(clipRgn); // restore the full-blown clipRgn
- DisposeRgn(tempRgn);
- DisposeRgn(clipRgn);
- }
- */TEActivate(thep2wWindow->p2wTEHandle);
-
- DrawGrowIcon((WindowPtr)thep2wWindow);
-
- // the controls must be redrawn on activation
- ShowControl(thep2wWindow->p2wVScroller);
- ShowControl(thep2wWindow->p2wHScroller);
- }
- else
- { /* De-Activating.. */
- /* the growbox should be changed immediately here */
- DrawGrowIcon((WindowPtr)thep2wWindow);
-
- TEDeactivate(thep2wWindow->p2wTEHandle);
-
- /* the controls must be hidden on deactivation */
- HideControl(thep2wWindow->p2wVScroller);
- HideControl(thep2wWindow->p2wHScroller);
-
- }
- }
- } // p2w_DoActivate
-
-
- /*
- ******************************************************************************
- Name:
- p2w_DoGrow
- ------------------------------------------------------------------------------
- Purpose:
- Called when a mouseDown occurs in the grow box of an active
- window. In order to eliminate any 'flicker', we want to
- invalidate only what is necessary. Since p2w_ResizeWindow
- invalidates the whole portRect, we save the old TE
- viewRect, intersect it with the new TE viewRect, and remove
- the result from the update region. However, we must make
- sure that any old update region that might have been around
- gets put back.
- ------------------------------------------------------------------------------
- Description:
-
- ------------------------------------------------------------------------------
- Parameters:
-
- ------------------------------------------------------------------------------
- When Used:
-
- ******************************************************************************
- */
- void p2w_DoGrow(const p2w_WindowPtr_t thep2wWindow, EventRecord *theEvent)
- {
- long growResult;
- Rect tempRect;
- // RgnHandle tempRgn;
-
- // is this really one of our p2w windows?
- // (We don't want to dispose extra stuff if it's really
- // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
- if (IS_P2W_WINDOW(thep2wWindow))
- {
- // move in for the kill
- SetPort((WindowPtr)thep2wWindow);
-
- /* set up limiting values */
- GetMaxGrowRect((WindowPtr)thep2wWindow, &tempRect); // ScreenUtils.h
- tempRect.left = kMinDocSize;
- tempRect.top = kMinDocSize;
-
- growResult = GrowWindow((WindowPtr)thep2wWindow, theEvent->where, &tempRect);
- /* see if it really changed size */
- if (growResult != 0)
- {
- // tempRect = (**thep2wWindow->p2wTEHandle).viewRect; /* save old text box */
- // tempRgn = NewRgn();
- // p2wi_GetLocalUpdateRegion(thep2wWindow, tempRgn); /* get localized update region */
- SizeWindow((WindowPtr)thep2wWindow, GET_LOWORD(growResult), GET_HIWORD(growResult), true);
- p2wi_ResizeWindow(thep2wWindow);
-
- /* calculate & validate the region that hasn’t changed, so it won’t get redrawn */
- // SectRect(&tempRect, &(**thep2wWindow->p2wTEHandle).viewRect, &tempRect);
- // ValidRect(&tempRect); /* take it out of update */
- // InvalRgn(tempRgn); /* put back any prior update */
- // DisposeRgn(tempRgn);
- }
- }
- } // p2w_DoGrow
-
-
- /*
- ******************************************************************************
- Name:
- p2w_DoZoom
- ------------------------------------------------------------------------------
- Purpose:
- Called when a mouseClick occurs in the zoom box of an active
- window. Everything has to get re-drawn here, so we don't mind
- that p2w_ResizeWindow invalidates the whole portRect.
- ------------------------------------------------------------------------------
- Description:
-
- ------------------------------------------------------------------------------
- Parameters:
-
- ------------------------------------------------------------------------------
- When Used:
-
- ******************************************************************************
- */
- void p2w_DoZoom(const p2w_WindowPtr_t thep2wWindow, short thePart)
- {
- // is this really one of our p2w windows?
- // (We don't want to dispose extra stuff if it's really
- // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
- if (IS_P2W_WINDOW(thep2wWindow))
- {
- // move in for the kill
- SetPort((WindowPtr)thep2wWindow);
- EraseRect(&((WindowPtr)thep2wWindow)->portRect);
- ZoomWindow((WindowPtr)thep2wWindow, thePart, (WindowPtr)thep2wWindow==FrontWindow());
- p2wi_ResizeWindow(thep2wWindow);
- }
- } // p2w_DoZoom
-
-
- /*
- ******************************************************************************
- Name:
- p2w_SelectAll
- ------------------------------------------------------------------------------
- Purpose:
- This will select the entire contents of a window.
- ------------------------------------------------------------------------------
- Description:
-
- ------------------------------------------------------------------------------
- Parameters:
-
- ------------------------------------------------------------------------------
- When Used:
-
- ******************************************************************************
- */
- void p2w_SelectAll(const p2w_WindowPtr_t thep2wWindow)
- {
- // is this really one of our p2w windows?
- // (We don't want to dispose extra stuff if it's really
- // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
- if (IS_P2W_WINDOW(thep2wWindow))
- {
- TESetSelect(0, -1, thep2wWindow->p2wTEHandle);
- }
- } // p2w_SelectAll
-
- /*
- ******************************************************************************
- Name:
- p2w_DoContentClick
- ------------------------------------------------------------------------------
- Purpose:
- This is called when a mouseDown occurs in the content of a window.
- ------------------------------------------------------------------------------
- Description:
-
- ------------------------------------------------------------------------------
- Parameters:
-
- ------------------------------------------------------------------------------
- When Used:
-
- ******************************************************************************
- */
- void p2w_DoContentClick(const p2w_WindowPtr_t thep2wWindow, EventRecord *theEvent)
- {
- Point mouse;
- ControlHandle control;
- short part, value;
- Boolean shiftDown;
- Rect teRect;
-
- // is this really one of our p2w windows?
- // (We don't want to dispose extra stuff if it's really
- // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
- if (IS_P2W_WINDOW(thep2wWindow))
- {
- SetPort((WindowPtr)thep2wWindow);
-
- /* get the click position */
- mouse = theEvent->where;
- GlobalToLocal(&mouse);
-
- /* see if we are in the viewRect. if so, we won’t check the controls */
- p2wi_GetTERect(thep2wWindow, &teRect);
- if (PtInRect(mouse, &teRect))
- {
- /* see if we need to extend the selection */
- shiftDown = (theEvent->modifiers & shiftKey) != 0; /* extend if Shift is down */
- TEClick(mouse, shiftDown, thep2wWindow->p2wTEHandle);
- }
- else
- {
- part = FindControl(mouse, (WindowPtr)thep2wWindow, &control);
- switch (part)
- {
- case 0: /* do nothing.. */
- break;
- case kControlIndicatorPart:
- value = GetControlValue(control);
- part = TrackControl(control, mouse, nil);
- if (part != 0)
- {
- value -= GetControlValue(control);
- /* value now has CHANGE in value; if value changed, scroll */
- if (value != 0)
- if (control == thep2wWindow->p2wVScroller)
- TEScroll(0, value * (*thep2wWindow->p2wTEHandle)->lineHeight, thep2wWindow->p2wTEHandle);
- else
- TEScroll(value, 0, thep2wWindow->p2wTEHandle);
- }
- break;
- default: /* they clicked in an arrow, so track & scroll */
- if (control == thep2wWindow->p2wVScroller)
- {
- value = TrackControl(control, mouse, p2wi_VScrollActionUPP);
- }
- else
- if (control == thep2wWindow->p2wHScroller)
- {
- value = TrackControl(control, mouse, p2wi_HScrollActionUPP);
- }
- break;
- }
- }
- }
- } // p2w_DoContentClick
-
-
- /*
- ******************************************************************************
- Name:
- p2w_DoKeyDown
- ------------------------------------------------------------------------------
- Purpose:
- Handle special keys, scroll window up/down.
- ------------------------------------------------------------------------------
- Description:
- ------------------------------------------------------------------------------
- Parameters:
- the_p2wPtr The p2w window to scroll.
- ------------------------------------------------------------------------------
- When Used:
- ******************************************************************************
- */
- void p2w_DoKeyDown(const p2w_WindowPtr_t the_p2wPtr, short theKeyCode)
- {
- if (the_p2wPtr) // if window ptr is valid
- // is this really one of our p2w windows?
- // (We don't want to fiddle with extra stuff if it's really
- // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
- if (IS_P2W_WINDOW(the_p2wPtr))
- {
- switch (theKeyCode)
- {
- case 0x73: // HOME
- p2w_ScrollHome(the_p2wPtr);
- break;
-
- case 0x77: // END
- p2w_ScrollEnd(the_p2wPtr);
- break;
-
- case 0x74: // page-up
- p2w_ScrollPageUp(the_p2wPtr);
- break;
-
- case 0x79: // page-down
- p2w_ScrollPageDown(the_p2wPtr);
- break;
-
- case 0x7b: // left-arrow
- case 0x3b:
- p2w_ScrollLeft(the_p2wPtr);
- break;
-
- case 0x7c: // right-arrow
- case 0x3c:
- p2w_ScrollRight(the_p2wPtr);
- break;
-
- case 0x7e: // up-arrow
- case 0x3e:
- p2w_ScrollLineUp(the_p2wPtr);
- break;
-
- case 0x7d: // down-arrow
- case 0x3d:
- p2w_ScrollLineDown(the_p2wPtr);
- break;
- }
- }
- }
-
-
-
- /*---------------------------------------------------------------------*/
- /*==== Private internal p2w routines ====*/
-
- /*
- ******************************************************************************
- Name:
- p2wi_GetTERect
- ------------------------------------------------------------------------------
- Purpose:
- Return a rectangle that is inset from the portRect by the
- size of the scrollbars, plus a bit.
- ------------------------------------------------------------------------------
- Description:
-
- ------------------------------------------------------------------------------
- Parameters:
-
- ------------------------------------------------------------------------------
- When Used:
-
- ******************************************************************************
- */
- static void p2wi_GetTERect(const p2w_WindowPtr_t thep2wWindow, Rect *teRect)
- {
- *teRect = ((WindowPtr)thep2wWindow)->portRect;
- InsetRect(teRect, kTextMargin, kTextMargin); /* adjust for margin */
- teRect->bottom = teRect->bottom - kScrollbarAdjust; /* and for the scrollbars */
- teRect->right = teRect->right - kScrollbarAdjust;
- } // p2wi_GetTERect
-
-
- /*
- ******************************************************************************
- Name:
- p2wi_AdjustTE
- ------------------------------------------------------------------------------
- Purpose:
- Scroll the TERec around to match up to the potentially updated scrollbar
- values. This is really useful when the window has been resized such that
- the scrollbars became inactive but the TERec was already scrolled.
- ------------------------------------------------------------------------------
- Description:
-
- ------------------------------------------------------------------------------
- Parameters:
-
- ------------------------------------------------------------------------------
- When Used:
-
- ******************************************************************************
- */
- static void p2wi_AdjustTE(const p2w_WindowPtr_t thep2wWindow)
- {
- short hVal,vVal;
- TEPtr te;
-
- vVal = GetControlValue(thep2wWindow->p2wVScroller);
- hVal = GetControlValue(thep2wWindow->p2wHScroller);
- te = *thep2wWindow->p2wTEHandle;
- TEScroll((te->viewRect.left - te->destRect.left) - hVal,
- (te->viewRect.top - te->destRect.top) - (vVal * te->lineHeight),
- thep2wWindow->p2wTEHandle);
- } // p2wi_AdjustTE
-
-
- /*
- ******************************************************************************
- Name:
- p2wi_AdjustViewRect
- ------------------------------------------------------------------------------
- Purpose:
- Update our TE view rect so it's the greatest multiple of
- the lineHeight that still fits in the old viewRect.
- ------------------------------------------------------------------------------
- Description:
-
- ------------------------------------------------------------------------------
- Parameters:
-
- ------------------------------------------------------------------------------
- When Used:
-
- ******************************************************************************
- */
- static void p2wi_AdjustViewRect(TEHandle p2wTE)
- {
- TEPtr te;
-
- te = *p2wTE;
- te->viewRect.bottom = (((te->viewRect.bottom - te->viewRect.top) / te->lineHeight)
- * te->lineHeight) + te->viewRect.top;
- } // p2wi_AdjustViewRect
-
-
- /*
- ******************************************************************************
- Name:
- p2wi_CommonAdjustScroller
- ------------------------------------------------------------------------------
- Purpose:
- Calculate the new control maximum value and current value,
- for the horizontal or vertical scrollbar. The vertical max
- is calculated by comparing the number of lines to the
- vertical size of the viewRect. The horizontal max is
- calculated by comparing the maximum document width to the
- width of the viewRect. The current values are set by
- comparing the offset between the view and destination
- rects. If necessary and we canRedraw, have the control be
- re-drawn by calling ShowControl.
- ------------------------------------------------------------------------------
- Description:
-
- ------------------------------------------------------------------------------
- Parameters:
-
- ------------------------------------------------------------------------------
- When Used:
- Called by p2wi_AdjustScrollValues, twice.
- ******************************************************************************
- */
- static void p2wi_CommonAdjustScroller(const Boolean isVert, const p2w_WindowPtr_t thep2wWindow,
- ControlHandle control, TEHandle theTEHandle/*, const Boolean canRedraw*/)
- {
- short value, lines, theMax;
- short oldValue, oldMax;
-
- // calculate new max and current values for this scrollbar
- oldValue = GetControlValue(control);
- oldMax = GetControlMaximum(control);
- if (isVert)
- {
- lines = (**theTEHandle).nLines;
- /* since nLines isn’t right if the last character is a return, check for that case */
- if ( *(*(**theTEHandle).hText + (**theTEHandle).teLength - 1) == '\n')
- lines += 1;
- theMax = lines
- - (
- ((**theTEHandle).viewRect.bottom - (**theTEHandle).viewRect.top)
- / (**theTEHandle).lineHeight
- );
- }
- else // horiz
- theMax = thep2wWindow->p2wMaxDocWidth
- - (
- (**theTEHandle).viewRect.right - (**theTEHandle).viewRect.left
- );
-
- if (theMax < 0) // insure positive
- theMax = 0;
- SetControlMaximum(control, theMax);
-
- if (isVert)
- {
- // always scroll to end?
- if (thep2wWindow->p2wAlwaysScrollToBottom)
- value = theMax;
- else
- value = ((**theTEHandle).viewRect.top - (**theTEHandle).destRect.top)
- / (**theTEHandle).lineHeight;
- }
- else // horiz
- value = (**theTEHandle).viewRect.left - (**theTEHandle).destRect.left;
-
- if ( value < 0 )
- value = 0;
- else
- if (value > theMax)
- value = theMax;
-
- SetControlValue(control, value);
-
- /* now redraw the control if it needs to be and can be */
- /*
- if (canRedraw || (max != oldMax) || (value != oldValue))
- {
- ShowControl(control);
- }
- */
- } // p2wi_CommonAdjustScroller
-
-
- /*
- ******************************************************************************
- Name:
- p2wi_AdjustScrollValues
- ------------------------------------------------------------------------------
- Purpose:
- Simply call the common adjust routine for both the vertical
- and horizontal scrollbars.
- ------------------------------------------------------------------------------
- Description:
-
- ------------------------------------------------------------------------------
- Parameters:
-
- ------------------------------------------------------------------------------
- When Used:
-
- ******************************************************************************
- */
- static void p2wi_AdjustScrollValues(const p2w_WindowPtr_t thep2wWindow)
- {
- // vertical
- p2wi_CommonAdjustScroller(true, thep2wWindow, thep2wWindow->p2wVScroller, thep2wWindow->p2wTEHandle);
- // horizontal
- p2wi_CommonAdjustScroller(false, thep2wWindow, thep2wWindow->p2wHScroller, thep2wWindow->p2wTEHandle);
- } // p2wi_AdjustScrollValues
-
-
-
- /*
- ******************************************************************************
- Name:
- p2wi_AdjustScrollSizes
- ------------------------------------------------------------------------------
- Purpose:
- Re-calculate the position and size of the viewRect and the
- scrollbars. The constant kScrollTweek compensates for the
- "off-by-one" requirements of the scrollbars that need their
- borders coinciding with the growbox.
- ------------------------------------------------------------------------------
- Description:
-
- ------------------------------------------------------------------------------
- Parameters:
-
- ------------------------------------------------------------------------------
- When Used:
-
- ******************************************************************************
- */
- static void p2wi_AdjustScrollSizes(const p2w_WindowPtr_t thep2wWindow)
- {
- Rect teRect;
-
- p2wi_GetTERect(thep2wWindow, &teRect); // start with TERect..
- (*thep2wWindow->p2wTEHandle)->viewRect = teRect;
- p2wi_AdjustViewRect(thep2wWindow->p2wTEHandle); /* snap to nearest line */
-
- /* move vertical scrollbar to nearest line */
- MoveControl(thep2wWindow->p2wVScroller,
- ((WindowPtr)thep2wWindow)->portRect.right - kScrollbarAdjust,
- -1);
- SizeControl(thep2wWindow->p2wVScroller,
- kScrollbarWidth,
- (((WindowPtr)thep2wWindow)->portRect.bottom
- - ((WindowPtr)thep2wWindow)->portRect.top)
- - (kScrollbarAdjust - kScrollTweek));
-
- /* move horizontal scrollbar to nearest line */
- MoveControl(thep2wWindow->p2wHScroller,
- -1,
- ((WindowPtr)thep2wWindow)->portRect.bottom - kScrollbarAdjust);
- SizeControl(thep2wWindow->p2wHScroller,
- (((WindowPtr)thep2wWindow)->portRect.right
- - ((WindowPtr)thep2wWindow)->portRect.left)
- - (kScrollbarAdjust - kScrollTweek),
- kScrollbarWidth);
- } // p2wi_AdjustScrollSizes
-
-
- /*
- ******************************************************************************
- Name:
- p2wi_AdjustScrollbars
- ------------------------------------------------------------------------------
- Purpose:
- Recalculate the scrollbar pos/values, and redraw if need be.
- ------------------------------------------------------------------------------
- Description:
- Turn off the controls by jamming a zero into their contrlVis fields
- (HideControl erases them and we don't want that). If the controls
- are to be resized as well, call the procedure to do that, then call
- the procedure to adjust the maximum and current values. Finally,
- re-enable the controls by jamming a $FF in their contrlVis fields.
- ------------------------------------------------------------------------------
- Parameters:
-
- ------------------------------------------------------------------------------
- When Used:
-
- ******************************************************************************
- */
- static void p2wi_AdjustScrollbars(const p2w_WindowPtr_t thep2wWindow, const Boolean doResize)
- {
- short oldHvis, oldVvis;
-
- /* remember original visibility settings */
- oldVvis = (**thep2wWindow->p2wVScroller).contrlVis;
- oldHvis = (**thep2wWindow->p2wHScroller).contrlVis;
-
- /* First, turn visibility of scrollbars off to eliminate unwanted redrawing */
- (**thep2wWindow->p2wVScroller).contrlVis = kControlInvisible; /* turn them off */
- (**thep2wWindow->p2wHScroller).contrlVis = kControlInvisible;
-
- /* move & size as needed */
- if (doResize)
- p2wi_AdjustScrollSizes(thep2wWindow);
-
- /* adjust constrols' max and current values */
- p2wi_AdjustScrollValues(thep2wWindow);
-
- /* Now, restore visibility in case we never had to ShowControl during adjustment */
- (**thep2wWindow->p2wVScroller).contrlVis = oldVvis; /* restore them */
- (**thep2wWindow->p2wHScroller).contrlVis = oldHvis;
-
- // don't do this?
- ShowControl(thep2wWindow->p2wVScroller);
- ShowControl(thep2wWindow->p2wHScroller);
-
- } // p2wi_AdjustScrollbars
-
-
- /*
- ******************************************************************************
- Name:
- p2wi_ResizeWindow
- ------------------------------------------------------------------------------
- Purpose:
- Called when the window has been resized to fix up the controls and content.
- ------------------------------------------------------------------------------
- Description:
-
- ------------------------------------------------------------------------------
- Parameters:
-
- ------------------------------------------------------------------------------
- When Used:
-
- ******************************************************************************
- */
- static void p2wi_ResizeWindow(const p2w_WindowPtr_t thep2wWindow)
- {
- p2wi_AdjustScrollbars(thep2wWindow, true);
- /* now scroll the TE record to match the scrollbars */
- p2wi_AdjustTE(thep2wWindow);
- InvalRect(&((WindowPtr)thep2wWindow)->portRect);
- } // p2wi_ResizeWindow
-
-
-
- /*
- ******************************************************************************
- Name:
- p2wi_GetLocalUpdateRegion
- ------------------------------------------------------------------------------
- Purpose:
- Returns the update region in local coordinates
- ------------------------------------------------------------------------------
- Description:
-
- ------------------------------------------------------------------------------
- Parameters:
-
- ------------------------------------------------------------------------------
- When Used:
-
- ******************************************************************************
- */
- static void p2wi_GetLocalUpdateRegion(const p2w_WindowPtr_t thep2wWindow, RgnHandle localRgn)
- {
- CopyRgn(((WindowPeek)thep2wWindow)->updateRgn, localRgn); /* save old update region */
- OffsetRgn(localRgn, ((WindowPtr)thep2wWindow)->portBits.bounds.left,
- ((WindowPtr)thep2wWindow)->portBits.bounds.top);
- } // p2wi_GetLocalUpdateRegion
-
-
-
- /*
- ******************************************************************************
- Name:
- p2wi_CommonScrollAction
- ------------------------------------------------------------------------------
- Purpose:
- Common algorithm for pinning the value of a control. It
- returns the actual amount the value of the control changed.
- Note the pinning is done for the sake of returning the
- amount the control value changed.
- ------------------------------------------------------------------------------
- Description:
-
- ------------------------------------------------------------------------------
- Parameters:
-
- ------------------------------------------------------------------------------
- When Used:
- Called by p2wi_HScrollActionProc, p2wi_VScrollActionProc
- ******************************************************************************
- */
- static void p2wi_CommonScrollAction(ControlHandle control, short *amount)
- {
- short value, max;
-
- /* get the current value.. */
- value = GetControlValue(control);
-
- /* and the biggest value */
- max = GetControlMaximum(control);
-
- *amount = value - *amount;
- if ( *amount < 0 )
- *amount = 0;
- else if ( *amount > max )
- *amount = max;
- SetControlValue(control, *amount);
-
- /* figure out the delta change */
- *amount = value - *amount;
- } // p2wi_CommonScrollAction
-
-
- /*
- ******************************************************************************
- Name:
- p2wi_VScrollActionProc
- ------------------------------------------------------------------------------
- Purpose:
- Determines how much to change the value of the vertical scrollbar by,
- and how much to scroll the TE record.
- ------------------------------------------------------------------------------
- Description:
-
- ------------------------------------------------------------------------------
- Parameters:
-
- ------------------------------------------------------------------------------
- When Used:
- Callback routine, called by toolbox
- ******************************************************************************
- */
- pascal void p2wi_VScrollActionProc(ControlHandle control, short part)
- {
- short amount;
- p2w_WindowPtr_t p2w_Window;
- TEPtr te;
-
- if (part != 0)
- { /* if it was actually in the control */
- p2w_Window = (p2w_WindowPtr_t)(*control)->contrlOwner;
- te = *p2w_Window->p2wTEHandle;
- switch (part)
- {
- case kControlUpButtonPart:
- case kControlDownButtonPart: /* one line */
- amount = 1;
- break;
- case kControlPageUpPart: /* one page */
- case kControlPageDownPart:
- amount = (te->viewRect.bottom - te->viewRect.top) / te->lineHeight;
- break;
- }
- if ((part == kControlDownButtonPart) || (part == kControlPageDownPart))
- amount = -amount; /* reverse direction if going down */
- p2wi_CommonScrollAction(control, &amount);
- if (amount != 0)
- TEScroll(0, amount * te->lineHeight, p2w_Window->p2wTEHandle);
- }
- } // p2wi_VScrollActionProc
-
-
- /*
- ******************************************************************************
- Name:
- p2wi_HScrollActionProc
- ------------------------------------------------------------------------------
- Purpose:
- Determines how much to change the value of the horizontal scrollbar by,
- and how much to scroll the TE record.
- ------------------------------------------------------------------------------
- Description:
-
- ------------------------------------------------------------------------------
- Parameters:
-
- ------------------------------------------------------------------------------
- When Used:
- Callback routine, called by toolbox
- ******************************************************************************
- */
- pascal void p2wi_HScrollActionProc(ControlHandle control, short part)
- {
- short amount;
- p2w_WindowPtr_t p2w_Window;
- TEPtr te;
-
- if (part != 0)
- { /* if it was actually in the control */
- p2w_Window = (p2w_WindowPtr_t)(*control)->contrlOwner;
- te = *p2w_Window->p2wTEHandle;
- switch (part)
- {
- case kControlUpButtonPart:
- case kControlDownButtonPart: /* some pixels */
- amount = kButtonScroll;
- break;
- case kControlPageUpPart: /* a whole page */
- case kControlPageDownPart:
- amount = te->viewRect.right - te->viewRect.left;
- break;
- }
- if ( (part == kControlDownButtonPart) || (part == kControlPageDownPart) )
- amount = -amount; /* reverse direction.. */
- p2wi_CommonScrollAction(control, &amount);
- if ( amount != 0 )
- TEScroll(amount, 0, p2w_Window->p2wTEHandle);
- }
- } // p2wi_HScrollActionProc
-
-
- /*---------------------------------------------------------------------*/
- /*==== Standard C library fns ====*/
-
- /*
- ******************************************************************************
- Name:
- p2wi_StdCOut_BottleNeck
- ------------------------------------------------------------------------------
- Purpose:
- Internal Standard C output replacement common bottleneck routine..
- This is what they all call to actually display the string/character.
- ------------------------------------------------------------------------------
- Description:
-
- ------------------------------------------------------------------------------
- Parameters:
-
- ------------------------------------------------------------------------------
- When Used:
-
- ******************************************************************************
- */
- static int p2wi_StdCOut_BottleNeck(FILE *stream)
- {
- int x;
- char *OutBuf, *outp;
- short OutSize;
-
- // get ahold of output buffer
- OutSize = **(short **)p2w_Stdio_OutBuf_Hdl;
- OutBuf = *p2w_Stdio_OutBuf_Hdl + sizeof(short);
- // make sure the string at least stops here! (maybe check strlen first for overflow errors?)
- *(OutBuf+kMaxStdIOBuffSize-1) = '\0';
-
- // If the output is for standard output (stderr/stdout) then capture it into our window,
- // else send it on to the standard C file output library routine.
- if ((stream == stderr) || (stream == stdout))
- {
- // Replace any line feeds (0x0a) with Macintosh carriage returns (0x0d)
- // This is mainly for Think C compatibility, since Think faithfully
- // literally adopted the K&R C idea (from Unix) that '\n' is really 0x0a,
- // and Apple's MPW C bends '\n' to 0x0d for better file compatibility.
-
- /*
- Note: For now, do this in both MPW and Think C. This will FORCE the mapping
- of any LFs to CRs. The main reason for doing this is to catch the odd times
- that the source code uses either '\r', or worse, '\0x0a' to embed returns!
- */
- outp = OutBuf;
- for (x = 0; x < OutSize; x++)
- {
- if (*outp == 0x0a)
- *outp = 0x0d;
- if ((*outp != 0x0d) && (*outp < ' ')) // any other control chars, convert to space
- *outp = ' ';
- outp++;
- }
-
- x = p2w_AddCString(local_p2wWindow, OutBuf, OutSize); // add it into window
- }
- else
- {
- // call a real std. C library routine. This allows output to real
- // stdio C files to pass through unmolested.
- x = fwrite(OutBuf, OutSize, 1, stream);
- }
-
- return x;
-
- } // p2wi_StdCOut_BottleNeck
-
-
- /*
- ******************************************************************************
- Name:
- p2wi_vfprintf
- ------------------------------------------------------------------------------
- Purpose:
- Internal common formatting handler for fprintf/printf
- ------------------------------------------------------------------------------
- Description:
-
- ------------------------------------------------------------------------------
- Parameters:
-
- ------------------------------------------------------------------------------
- When Used:
-
- ******************************************************************************
- */
- static int p2wi_vfprintf(FILE *stream, const char *format, va_list va_args)
- {
- int x;
- char *outBuf;
- short *OutSizePtr;
-
- // get ahold of output buffer
- HLock(p2w_Stdio_OutBuf_Hdl);
- OutSizePtr = (short *)*p2w_Stdio_OutBuf_Hdl;
- outBuf = *p2w_Stdio_OutBuf_Hdl + sizeof(short);
-
- #if defined(NEEDS_DEBUG)
- {
- // stick in a TE-length value debug into the TE record
- int daLen = (**(local_p2wWindow->p2wTEHandle)).teLength;
- sprintf(outBuf, "[%5d] ",daLen);
- *OutSizePtr = 8;
- x = p2wi_StdCOut_BottleNeck(stream);
- }
- #endif // NEEDS_DEBUG
-
- // use C library routine to do printf formatting of the string into buffer
- x = vsprintf(outBuf, format, va_args); // format it into a string
- *OutSizePtr = strlen(outBuf);
-
- // do the window output
- x = p2wi_StdCOut_BottleNeck(stream);
-
- // cut buffer adrift again..
- HUnlock(p2w_Stdio_OutBuf_Hdl);
-
- return x;
- } // p2wi_vfprintf
-
-
-
- int p2w_fflush(FILE *stream)
- {
- #pragma unused (stream)
- int x;
-
- /* major no-op, dude */
- x = 0;
- return x;
- } // p2w_fflush
-
-
-
-
- int p2w_fprintf(FILE *stream, const char *format, ...)
- {
- va_list va_args;
- int x;
-
- // use our bottleneck routine to do printf formatting
- va_start(va_args, format);
- x = p2wi_vfprintf(stream, format, va_args); // format it into a string
- va_end(va_args);
-
- return x;
- } // p2w_fprintf
-
-
- int p2w_fputc(int theChar, FILE *stream)
- {
- int x;
- char *outBuf;
- short *OutSizePtr;
-
- // get ahold of output buffer & make char into string
- HLock(p2w_Stdio_OutBuf_Hdl);
- OutSizePtr = (short *)*p2w_Stdio_OutBuf_Hdl;
- outBuf = *p2w_Stdio_OutBuf_Hdl + sizeof(short);
-
- outBuf[0] = theChar;
- outBuf[1] = '\0';
- *OutSizePtr = 1;
-
- x = p2wi_StdCOut_BottleNeck(stream);
-
- HUnlock(p2w_Stdio_OutBuf_Hdl);
-
- return x;
-
- } // p2w_fputc
-
-
- int p2w_fputs(const char *theString, FILE *stream)
- {
- int x;
- char *outBuf;
- short *OutSizePtr;
-
- // get ahold of output buffer
- HLock(p2w_Stdio_OutBuf_Hdl);
- OutSizePtr = (short *)*p2w_Stdio_OutBuf_Hdl;
- outBuf = *p2w_Stdio_OutBuf_Hdl + sizeof(short);
-
- // *OutSizePtr = kMaxStdIOBuffSize;
- // ...changed to... [esp]
- *OutSizePtr = strlen(theString);
-
- // Copy string into buffer & write it
- // BlockMove(theString, outBuf, kMaxStdIOBuffSize);
- // ...changed to... [esp]
- BlockMove(theString, outBuf, 1+(*OutSizePtr));
-
- x = p2wi_StdCOut_BottleNeck(stream);
-
- // "puts()" puts a newline afterwards..
- if ((stream == stderr) || (stream == stdout))
- p2w_putc('\n', stream);
-
- // cut buffer adrift again..
- HUnlock(p2w_Stdio_OutBuf_Hdl);
-
- return x;
- } // p2w_fputs
-
-
- int p2w_printf(const char * format, ...)
- {
- va_list va_args;
- int x;
-
- // use our bottleneck routine to do printf formatting
- va_start(va_args, format);
- x = p2wi_vfprintf(stdout, format, va_args); // format it into a string
- va_end(va_args);
-
- return x;
- } // p2w_printf
-
-
- int p2w_putc(int theChar, FILE *stream)
- {
- return p2w_fputc(theChar, stream);
- } // p2w_putc
-
-
- int p2w_putchar(const char theChar)
- {
- return p2w_fputc(theChar, stdout);
- } // p2w_putchar
-
-
- int p2w_puts(const char *theString)
- {
- return p2w_fputs(theString, stdout);
- } // p2w_puts
-