home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************
- * NCSA Telnet for the Macintosh *
- * *
- * National Center for Supercomputing Applications *
- * Software Development Group *
- * 152 Computing Applications Building *
- * 605 E. Springfield Ave. *
- * Champaign, IL 61820 *
- * *
- * Copyright (c) 1986-1994, *
- * Board of Trustees of the University of Illinois *
- ****************************************************************/
-
- #include <Drag.h>
- #include <CodeFragments.h>
-
- #include "wind.h"
-
- #include "maclook.proto.h" // For WindowPtr2WindRecPtr proto
- #include "rsinterf.proto.h"
- #include "parse.proto.h"
- #include "drag.proto.h"
-
- #ifdef MPW
- #pragma segment RS
- #endif
-
- Boolean gHaveDragMgr, gDropcanAcceptItems, gDropcursorInContent, gDropDestCanAcceptItems;
-
- #define kScrollbarSize 15
-
- pascal OSErr MyReceiveDropHandler(WindowPtr theWindow, unsigned long handlerRefCon,
- DragReference theDrag);
- PROTO_UPP(MyReceiveDropHandler, DragReceiveHandler);
- pascal OSErr MyTrackingHandler(short message, WindowPtr theWindow,
- void *handlerRefCon, DragReference theDrag);
- PROTO_UPP(MyTrackingHandler, DragTrackingHandler);
-
- static void LocalToGlobalRgn (RgnHandle rgn);
- static void OutlineRegion (RgnHandle theRgn);
-
- void MyDragInit(void)
- {
- OSErr err;
- long dragMgrAttr;
-
- err = Gestalt(gestaltDragMgrAttr, &dragMgrAttr);
- gHaveDragMgr = (err == noErr) && (dragMgrAttr & (1L << gestaltDragMgrPresent)) != 0;
- #ifdef powerc
- gHaveDragMgr = gHaveDragMgr &&
- (dragMgrAttr & (1L << gestaltPPCDragLibPresent)) != 0
- && ((long) InstallTrackingHandler) != kUnresolvedSymbolAddress;
-
-
- #endif
- // If the DragManager is available, install our tracking handlers
- if (gHaveDragMgr) {
- err = InstallTrackingHandler(MyTrackingHandlerUPP, nil, nil);
-
- if (err == noErr) {
- // If all is ok so far, install the rcv handler
- err = InstallReceiveHandler(MyReceiveDropHandlerUPP, nil, nil);
- if (err != noErr) {
- // If an error ocurred installing the rcv handler, remove the tracking handler
- RemoveTrackingHandler(MyTrackingHandlerUPP, nil);
- }
- }
-
- // If any error occurred, turn off DragManager support
- if (err != noErr) {
- gHaveDragMgr = false;
- }
- }
- }
-
- /* MyReceiveDropHandler
- * Called by the Drag Manager when a drop occurs over one of Telnet's windows. */
- SIMPLE_UPP(MyReceiveDropHandler, DragReceiveHandler);
- pascal OSErr MyReceiveDropHandler(WindowPtr theWindow, unsigned long handlerRefCon,
- DragReference theDrag)
- {
- OSErr result,memError;
- Handle dataH;
- unsigned short items, index;
- ItemReference theItem;
- DragAttributes attributes;
- Size textSize;
- short mouseDownModifiers, mouseUpModifiers;
- WindRecPtr tw;
-
- if (!gDropcanAcceptItems || !gDropcursorInContent)
- return(dragNotAcceptedErr);
-
- SetPort(theWindow);
-
- // No text yet
- dataH = nil;
-
- GetDragAttributes(theDrag, &attributes);
- GetDragModifiers(theDrag, 0L, &mouseDownModifiers, &mouseUpModifiers);
-
- // Loop through all of the drag items contained in this drag and collect the text
- // into the accumulation handle.
-
- CountDragItems(theDrag, &items);
-
- for (index = 1; index <= items; index++) {
- // Get the item's reference number, so we can refer to it.
- GetDragItemReferenceNumber(theDrag, index, &theItem);
-
- // Try to get the flags for a 'TEXT' flavor. If this returns noErr,
- // then we know that a 'TEXT' flavor exists in the item.
- result = GetFlavorDataSize(theDrag, theItem, 'TEXT', &textSize);
-
- if (result == noErr) {
- if (dataH == nil) { // No data yet, create a new handle for accumulation
- dataH = myNewHandle(textSize);
- if (dataH == nil) {
- return memFullErr; // Exit if there is an error
- }
- }
- else { // Append to existing TEXT data
- memError = mySetHandleSize(dataH, GetHandleSize(dataH) + textSize); // Grow the handle
- if (memError != noErr) {
- return memFullErr; // Exit if there is a problem
- }
- }
-
-
- // Temporarily lock down the accumlation handle
- HLock(dataH);
-
- // Get the drag data
- GetFlavorData(theDrag, theItem, 'TEXT', *dataH, &textSize, 0L);
-
- // Ok to unlock the accumulation handle
- HUnlock(dataH);
- }
- }
-
- // Get the length of all that was accumulated
- textSize = GetHandleSize(dataH);
-
- // If we actually received text, insert it into the destination.
- if (textSize != 0) {
- if (attributes & dragHasLeftSenderWindow) {
- HideDragHilite(theDrag);
- }
-
- HLock(dataH);
-
- // Send the text to the window.
- tw = WindowPtr2WindRecPtr(theWindow);
- if (tw != nil) {
- SendStringAsIfTyped(tw, *dataH, textSize);
- }
- HUnlock(dataH);
- }
-
- if (dataH != nil) {
- DisposeHandle(dataH);
- }
-
- return(noErr);
- }
-
- /* MyTrackingHandler
- * This is the drag tracking handler for windows in the DragText application.*/
- SIMPLE_UPP(MyTrackingHandler, DragTrackingHandler);
- pascal OSErr MyTrackingHandler(short message, WindowPtr theWindow,
- void *handlerRefCon, DragReference theDrag)
- {
- short result;
- unsigned short count, index;
- unsigned long flavorFlags, attributes;
- ItemReference theItem;
- RgnHandle theRgn, selectionRgn;
- Point theMouse, localMouse;
- Rect dragRect;
- GrafPtr savePort;
- Boolean inOriginalSelection;
-
- if ((message != dragTrackingEnterHandler) && (!gDropcanAcceptItems))
- return(noErr);
-
- if ((message != dragTrackingEnterHandler) && (message != dragTrackingEnterWindow)
- && (!gDropDestCanAcceptItems))
- return(noErr);
-
- GetDragAttributes(theDrag, &attributes);
-
- switch (message) {
-
- case dragTrackingEnterHandler:
- // We get called with this message the first time that a drag enters ANY
- // window in our application.
- gDropcanAcceptItems = true;
-
- // Check to see if all of the drag items contain
- // TEXT. We only accept a drag if all of the items in the drag can be accepted.
- CountDragItems(theDrag, &count);
-
- for (index = 1; index <= count; index++) {
- GetDragItemReferenceNumber(theDrag, index, &theItem);
-
- result = GetFlavorFlags(theDrag, theItem, 'TEXT', &flavorFlags);
-
- if (result != noErr) {
- gDropcanAcceptItems = false;
- break;
- }
- }
- break;
-
- case dragTrackingEnterWindow:
- // We receive an EnterWindow message each time a drag enters one of our
- // application's windows. We initialize our global variables for tracking
- // the drag through the window.
-
- // Assume this window can accept the drag
- gDropDestCanAcceptItems = true;
-
- // If it is not a connection window, it cannot accept a drop.
- if (((WindowPeek)theWindow)->windowKind != WIN_CNXN) {
- gDropDestCanAcceptItems = false;
- break;
- }
-
- // Initially no blue box.
- gDropcursorInContent = false;
- break;
-
- case dragTrackingInWindow:
- GetPort(&savePort);
- SetPort(theWindow);
-
- // We receive InWindow messages as long as the mouse is in one of our windows
- // during a drag. We draw the window highlighting when we get these messages.
- GetDragMouse(theDrag, &theMouse, 0L);
-
- // If we are still in the sender window, check to see if we should draw a blue box.
- // inOriginalSelection is true if the mouse is still within the confines of the
- // selected text's original location. This allows the user to cancel a drop by
- // dropping the text somewhere inside of the original selection.
- if (attributes & dragInsideSenderWindow) {
- localMouse = theMouse;
- GlobalToLocal(&localMouse);
-
- selectionRgn = RSGetTextSelRgn(WindowPtr2WindRecPtr(theWindow)->vs);
- inOriginalSelection = PtInRgn(localMouse, selectionRgn);
- DisposeRgn(selectionRgn);
- }
- else {
- inOriginalSelection = false;
- }
-
- // Show or hide the window highlighting when the mouse enters or leaves the
- // text area in our window (we don't want to show the highlighting when
- // the mouse is over the scroll bars).
- dragRect = (*(((WindowPeek)theWindow)->contRgn))->rgnBBox;
-
- // Subtract out the scrollbars.
- dragRect.right -= kScrollbarSize;
- dragRect.bottom -= kScrollbarSize;
-
- // If the mouse is in the text area and not in the original selection,
- // draw the blue box.
- if (PtInRect(theMouse, &dragRect) && !inOriginalSelection) {
- if (!gDropcursorInContent) {
-
- // Set up the blue box region.
- GlobalToLocal(&topLeft(dragRect));
- GlobalToLocal(&botRight(dragRect));
- RectRgn(theRgn = NewRgn(), &dragRect);
-
- ShowDragHilite(theDrag, theRgn, true);
-
- DisposeRgn(theRgn);
- }
-
- // Remember that we are in a valid drop location.
- gDropcursorInContent = true;
-
- }
- else {
- // We have moved out of a valid drop region.
-
- if (gDropcursorInContent) { // Hide the box if it was drawn.
- HideDragHilite(theDrag);
- }
-
- // Remember that we are outside of a valid drop region.
- gDropcursorInContent = false;
-
- }
-
- SetPort(savePort);
- break;
-
- case dragTrackingLeaveWindow:
- HideDragHilite(theDrag);
- break;
-
- case dragTrackingLeaveHandler:
- break;
-
- }
-
- return(noErr);
- }
-
- OSErr DragText(EventRecord *ev, Point where, short w, Boolean *dragged)
- {
- DragReference dragRef;
- OSErr err = noErr;
- Boolean haveDragRef = false;
- RgnHandle dragRgn = nil;
- Handle textH = nil;
- long size;
-
- *dragged = false;
- if (!gHaveDragMgr) {
- return noErr;
- }
-
- dragRgn = RSGetTextSelRgn(w);
- if (dragRgn == nil) {
- return noErr;
- }
- if (!PtInRgn(where, dragRgn)) {
- DisposeRgn(dragRgn);
- return noErr;
- }
- if (!WaitMouseMoved(ev->where)) return noErr;
- *dragged = true;
-
- textH = RSGetTextSel(w, 0);
-
- if ((textH == (char **)-1L) || (textH == nil)) {
- textH = nil;
- goto exit;
- }
-
- HLock(textH);
- size = GetHandleSize(textH);
-
- err = NewDrag(&dragRef);
- if (err != noErr) goto exit;
- haveDragRef = true;
-
- err = AddDragItemFlavor(dragRef, 1, 'TEXT', *textH, size, 0);
- if (err != noErr) goto exit;
-
- LocalToGlobalRgn(dragRgn);
- OutlineRegion(dragRgn);
-
- err = TrackDrag(dragRef, ev, dragRgn);
- if (err != noErr && err != userCanceledErr) goto exit;
-
- DisposeRgn(dragRgn);
- DisposeDrag(dragRef);
- DisposeHandle(textH);
- return noErr;
-
- exit:
-
- if (haveDragRef) DisposeDrag(dragRef);
- if (dragRgn != nil) DisposeRgn(dragRgn);
- if (textH != nil) DisposeHandle(textH);
- return err;
- }
-
- static void LocalToGlobalRgn (RgnHandle rgn)
- {
- Point where;
-
- SetPt(&where, 0, 0);
- LocalToGlobal(&where);
- OffsetRgn(rgn, where.h, where.v);
- }
-
- static void OutlineRegion (RgnHandle theRgn)
- {
- RgnHandle tempRgn;
-
- tempRgn = NewRgn();
- CopyRgn(theRgn, tempRgn);
- InsetRgn(tempRgn, 1, 1);
- DiffRgn(theRgn, tempRgn, theRgn);
- DisposeRgn(tempRgn);
- }
-