home *** CD-ROM | disk | FTP | other *** search
- #include "jam.h"
- #ifdef WINDOWED /* whole file */
-
- /*
- * Mouse support routines. Some code taken from original Amigamouse
- * code in Mg2a and enhanced/modified almost beyond recognition. This
- * code supports
- *
- * set mark
- * set dot
- * select region and copy/kill it
- * resize window(s)
- * scroll window(s)
- *
- * via string commands stuffed into the input stream from the
- * window level code. It ain't pretty, but it gets the job done.
- *
- */
- #include "def.h"
- #include "stdio.h"
- #include "keyname.h"
- #include "macro.h"
- #include "kbd.h"
-
- /* string-to-verb matching for mousecmd subcommands
- */
- #define LEFTDOWN 0
- #define RIGHTDOWN 1
- #define LEFTUP 2
- #define MOVE 3
- #define DBLCLICK 4
- #define LEFTDOWNSHIFT 5
- #define M_ABORT 6
- #define M_TIMER 7
-
- static BOOL rn_(setmousepos,(int row, int col, BOOL left));
- static void rn_(movedot,(int row, int col));
- static int rn_(subcommand,(char *s));
-
- static int downrow = -1, downcol = -1; /* initial down during move.. */
- static int oldrow = -1, oldcol = -1; /* last mouse click */
- static int newrow, newcol; /* next mouse click */
- static BOOL inmodeline = FALSE;
- static BOOL bottommodeline = FALSE;
- static BOOL mouseDown = FALSE;
- static BOOL mouseMoving = FALSE;
- static EWINDOW *touchedWp;
- static BOOL mshift = FALSE;
- static BOOL didsetmark = FALSE;
- static EWINDOW *mwp, *mwp1; /* window(s) mouse is in */
- static int mdoto, mdoto1, mcol1; /* line offset of mouse */
- static LINE *mdotp, *mdotp1; /* the real line the mouse is on */
-
- static char *cancel = "Cancelled!";
- static char *diffw = "Different window.";
- static char *shiftm = "Shift key will reverse scroll direction.";
- static char *movecopy = "Mark set; move cursor (dot) to define region to %s.";
- static char *mv = "move";
- static char *cp = "copy";
-
- /* relative-command - return if last click was in modeline
- */
- BOOL minmodeline()
- {
- return (inmodeline);
- }
- /*
- * Utility routine to move dot to where the user clicked.
- * Optional 'move' flag to make move permanent vs just
- * locating new dot.
- */
- int dottomouse(inrow, incol, move)
- int inrow;
- int incol;
- BOOL move;
- {
- register EWINDOW *wp;
- register int dot;
- register int col;
- register int c, nlines;
-
- inmodeline = FALSE; /* always reset */
- bottommodeline = FALSE;
- newrow = inrow;
- newcol = incol;
-
- if (macrodef)
- {
- ewprintf(notinmacro);
- return (FALSE);
- }
-
- /* Find out which window was clicked in
- */
- for (wp = wheadp; wp != NULL; wp = wp->w_wndp)
- if (newrow == (wp->w_toprow + wp->w_ntrows))
- {
- touchedWp = wp;
- inmodeline = TRUE;
- if (!wp->w_wndp) /* no next window? */
- bottommodeline = TRUE;
- }
- else if ((newrow >= wp->w_toprow) &&
- (newrow <= (wp->w_toprow + wp->w_ntrows)))
- break;
-
- /* Impossible?
- */
- if (wp == NULL)
- return (ABORT);
-
- else /* Compute the new location; optionally move there */
- {
- EWINDOW *savewp = curwp;
- BUFFER *savebp = curbp;
- LINE *savedotp = curwp->w_dotp;
- int savedoto = curwp->w_doto;
-
- /* Move to selected window, move dot to top left
- * then advance as possible to mouse point.
- */
- curwp = wp;
- curbp = wp->w_bufp;
- curwp->w_dotp = wp->w_linep;
- curwp->w_doto = 0;
-
- /* Go forward the correct # of lines
- */
- nlines = newrow - curwp->w_toprow;
- for (; nlines > 0; nlines--)
- {
- /* Wrap around? Don't insert blank lines in file
- */
- if (lforw(curwp->w_dotp) == curbp->b_linep)
- break;
- forwline(FFRAND, 1);
- }
-
- /* Go forward the correct # of characters
- * need to count them out because of tabs
- */
- col = dot = 0;
- while ((col < newcol) && (dot < llength(curwp->w_dotp)))
- {
- c = lgetc(curwp->w_dotp, dot++);
- if (c == CCHR('I'))
- col |= TABROUND;
- else if (ISCTRL(c) != FALSE)
- ++col;
- ++col;
- }
- if (col > newcol)
- dot--; /* back up to tab/ctrl char */
- forwchar(FFRAND, dot);
-
- /* not supposed to move? reset but remember where it
- * would have been
- */
- mwp = curwp;
- mdoto = curwp->w_doto;
- mdotp = curwp->w_dotp;
-
- if (!move)
- {
- curwp = savewp;
- curbp = savebp;
- curwp->w_dotp = savedotp;
- curwp->w_doto = savedoto;
- }
- }
-
- return (TRUE);
- }
- /* Handle mouse generated things
- */
- int mousecmd(f, n)
- int f, n;
- {
- char buf[256];
- int subcmd;
- static int row, col;
- BOOL killit = FALSE;
- static BOOL drawn = FALSE;
- #define IsAbort ((subcmd == M_ABORT) || killit)
- #define SetAbort() killit = TRUE
-
- /* Read the subcommand which is waiting in input stream.
- */
- getcmdinput(buf);
- if (buf[0])
- {
- subcmd = subcommand(buf); /* Convert subcommand to verb */
- switch(subcmd)
- {
- case M_ABORT:
- ewprintf(cancel);
- ttbeep();
- /* FALLTHRU */
- case LEFTUP:
- {
- BOOL copy = FALSE;
- BOOL kill = FALSE;
- EWINDOW *savewp = curwp;
- BUFFER *savebp = curbp;
- LINE *savedotp = curwp->w_dotp;
- int savedoto = curwp->w_doto;
-
- /* make window cursor normal, then find
- * position UP occurred
- */
- WindowNormalCursor();
- if (drawn) /* erase old */
- {
- movedot(row, col);
- drawn = FALSE;
- }
- if (!IsAbort) /* abort has no params */
- {
- getcmdinput(buf);
- sscanf(buf, posFormat, &row, &col);
- }
-
- if (!mouseDown) /* up after abort? */
- return (TRUE); /* no other bell */
-
- if (inmacro)
- {
- ewprintf(notinmacro);
- return FALSE; /* can't record mouse actions */
- }
-
- if (didsetmark) /* didn't do this for modeline move */
- {
- if (IsCaretCreated())
- SetCaretVis(FALSE); /* make sure no display weirdness */
-
- if (mwp1 != mwp)
- {
- ewprintf(diffw); /* operation can't span windows */
- SetAbort();
- }
- curwp = savewp;
- curbp = savebp;
- curwp->w_dotp = savedotp;
- curwp->w_doto = savedoto;
-
- /* Set dot at up point. If real motion occurred,
- * set appropriate verb (copy/kill).
- */
- if (!IsAbort)
- {
- dottomouse(row, col, TRUE);
- if ((mwp1 == mwp) && (mdotp != mdotp1) ||
- (mdoto != mdoto1))
- {
- if (mshift)
- kill = TRUE;
- else
- copy = TRUE;
- }
- } /* end !IsAbort */
- } /* end didsetmark */
-
- /* if an action triggered, do it now
- */
- if (copy)
- {
- kdelete();
- copyregion(0, 1);
- }
- else if (kill)
- killregion(0, 1);
-
- /* verboseness... remind that something can be pasted
- */
- if (copy || kill)
- ewprintf(pastemsg);
- mshift = FALSE;
- mouseMoving = mouseDown = FALSE;
- didsetmark = FALSE;
- }
- break;
-
- case LEFTDOWN:
- case LEFTDOWNSHIFT:
- mshift = (subcmd == LEFTDOWNSHIFT? TRUE: FALSE);
- getcmdinput(buf);
-
- if (inmacro)
- {
- ewprintf(notinmacro);
- return FALSE; /* can't record mouse actions */
- }
-
- sscanf(buf, posFormat, &row, &col);
- return(setmousepos(row, col, TRUE));
-
- case DBLCLICK:
- if (inmacro)
- {
- ewprintf(notinmacro);
- return FALSE; /* can't record mouse actions */
- }
-
- /* mouse-dblclick really should be the end result of
- * of clicking the mouse, then users could map that action
- * just like any keyboard key. But I don't feel like doing
- * that, and in reality NO ui should directly do anything but
- * insert pseudo keystrokes for mapping... in a perfect world.
- */
- if (!inmodeline && (curbp->b_modes[0] == name_mode(DiredStr)))
- return(d_findfile(0, 1));
- else if (!inmodeline && (curbp->b_modes[0] == name_mode(BlistStr)))
- return(seebuffer(0, 1));
- else
- {
- ewprintf("Mouse setting mark...");
- return(setmark(0, 1));
- }
-
- case RIGHTDOWN:
- {
- int s;
-
- getcmdinput(buf);
-
- if (inmacro)
- {
- ewprintf(notinmacro);
- return FALSE; /* can't record mouse actions */
- }
-
- sscanf(buf, posFormat, &row, &col);
- s = setmousepos(row, col, FALSE);
- if (s)
- yank(0, 1);
- return (s);
- }
-
- case M_TIMER:
- {
- int shifted;
-
- if (drawn)
- {
- movedot(row, col); /* erase old */
- drawn = FALSE;
- }
- ewprintf(shiftm);
- getcmdinput(buf);
- sscanf(buf, "%d", &shifted);
- if (shifted)
- ExtendedFunction(function_name(back1page));
- else
- ExtendedFunction(function_name(forw1page));
- break;
- }
-
- case MOVE:
- {
- EWINDOW *save;
- int delta;
- int row_ = row; /* last move row, col */
- int col_ = col;
-
- getcmdinput(buf);
-
- if (!mouseDown) /* abort occurred? */
- return (TRUE); /* leave quietly */
-
- if (inmacro)
- {
- ewprintf(notinmacro);
- return FALSE; /* can't record mouse actions */
- }
- sscanf(buf, posFormat, &row, &col);
-
- /* button down hit mode line?
- */
- if (inmodeline && !mouseMoving) /* moving for selection? */
- {
- if (bottommodeline)
- ewprintf(Impossible);
- else
- {
- WindowSizeCursor();
- save = curwp;
- curwp = touchedWp;
- oldrow = touchedWp->w_toprow + touchedWp->w_ntrows - 1;
- delta = abs(row - oldrow);
- if (row < oldrow)
- shrinkwind(0, delta);
- else
- enlargewind(0, delta);
- curwp = save;
- oldrow = row;
- }
- }
-
- /* button down hit source window?
- */
- else
- {
- if (!mouseMoving)
- {
- setmark(0, 1);
- movedot(row, col);
- }
- else if ((row_ != row) || (col_ != col))
- {
- if (drawn)
- movedot(row_, col_); /* erase old */
- movedot(row, col); /* draw new */
- }
-
- if (!drawn)
- ewprintf(movecopy, mshift ? mv : cp);
- drawn = TRUE;
- WindowDragCursor();
- mouseMoving = TRUE;
- }
- }
-
- default:
- break; /* nothing of interest */
- }
- }
-
- /* gobbledy-goop
- */
- return TRUE;
- }
-
- /* set dot to row/col, conditionally sets static state
- * variables concerning down position
- */
- static BOOL setmousepos(row, col, left)
- int row;
- int col;
- BOOL left;
- {
- if (!dottomouse(row, col, TRUE)) /* sets newrow, newcol */
- return (FALSE);
- if (!left)
- return (TRUE);
-
- downrow = oldrow = newrow; /* save state */
- downcol = oldcol = newcol;
- mouseDown = TRUE;
- mouseMoving = FALSE;
- mwp1 = mwp; /* save across move */
- mdotp1 = mdotp;
- mdoto1 = mdoto;
- mcol1 = getcolpos() - 1; /* evaluated location */
-
- /* get globals to the right place...draw a marker
- */
- WindowArrowCursor(); /* kinda limbo cursor.. */
- ewprintf("Cntrl-left is scroll; drag for region select.");
- if (!inmodeline)
- if (g_hasFocus)
- {
- update();
- didsetmark = TRUE;
- }
- return (TRUE);
- }
- /* visible region-selection drawing...
- */
- static void movedot(row, col)
- int row, col;
- {
- dottomouse(row, col, TRUE);
- update();
- DrawMarker();
- ttflush(FALSE);
- }
- /* parse a subcommand string to a integer verb
- */
- static int subcommand(s)
- char *s;
- {
- /* this just moves the strcmp's out of direct sight!
- */
- if (strcmp(s, LeftUp) == 0)
- return(LEFTUP);
- else if (strcmp(s, RightDwn) == 0)
- return(RIGHTDOWN);
- else if (strcmp(s, LeftDwn) == 0)
- return(LEFTDOWN);
- else if (strcmp(s, LeftDwnShift) == 0)
- return(LEFTDOWNSHIFT);
- else if (strcmp(s, DoubleClick) == 0)
- return(DBLCLICK);
- else if (strcmp(s, MoveStr) == 0)
- return(MOVE);
- else if (strcmp(s, MouseAbort) == 0)
- return(M_ABORT);
- else if (strcmp(s, MouseTimer) == 0)
- return(M_TIMER);
-
- /* unknown */
- else
- return (-1);
- }
- #endif /* WHOLE FILE */
-
-