/* * This file implements memacs support for the Amiga mouse. * Author: Andy Poggio */ #include #include #include #include #include #include "ed.h" #define NL 0 extern struct Window *Window; /* Font sizes */ #define FONT_X 8 #define FONT_Y 8 /* Button Codes */ #define LEFT_BUTTON 1 #define RIGHT_BUTTON 2 /* Menu Definitions */ #define NUM_MENUS 1 /* Copies of this structure will get "stamped" into many more */ /* Allocated later */ struct IntuiText generic = { 0, 1, /* Bluepen, Whitepen */ JAM2, 5, /* mode, LeftEdge */ 0, NL, /* Top (to be filled later), Font */ NL, /* Name (to be filled later) */ NL /* Next one */ }; /* Menu numbers */ #define COM_MENU 0 /* Menu Widths */ #define COM_WIDTH 72 int item_widths[ NUM_MENUS ] = { 112 }; /* All items in these menus have the following flags set */ #define BLACK_FILL ITEMTEXT | ITEMENABLED | HIGHCOMP /** FILE MENU ITEMS **/ #define NUM_COM_ITEMS 9 #define COPY_ITEM 0 #define KILL_ITEM 1 #define UNKILL_ITEM 2 #define TWO_ITEM 3 #define ONE_ITEM 4 #define QUERY_ITEM 5 #define NEW_ITEM 6 #define QUIT_ITEM 7 #define NOOP_ITEM 8 struct MenuItem com_items[NUM_COM_ITEMS]; struct IntuiText com_names[NUM_COM_ITEMS]; char *commenu_names[] = { "Copy Region", "Kill Region", "Un-Kill", "Split Window", "One Window", "Query Replace", "New CLI", "Quit", "No Operaton" }; struct Menu cmenu = { NL, /* Pointer to next menu */ 0, 0, COM_WIDTH, 10, /* LeftEdge, TopEdge, Width, Height */ MENUENABLED, /* FLAGS */ "Commands", /* Menu name */ com_items /* First item structure */ }; mouse_setup_menu() { mouse_newmenu( &cmenu, commenu_names, com_items, com_names, NUM_COM_ITEMS, item_widths[0], BLACK_FILL); SetMenuStrip(Window, &cmenu); /* Set up the menu here */ } mouse_clear_menu() { ClearMenuStrip(Window, &cmenu); } static do_menu( m, f, n) /* execute a menu command */ { int menu, item, sub; menu = MENUNUM( m); item = ITEMNUM( m); sub = SUBNUM( m); switch( menu) { case COM_MENU: switch( item) { case COPY_ITEM: copyregion( f, n); break; case KILL_ITEM: killregion( f, n); break; case UNKILL_ITEM: yank( f, n); break; case TWO_ITEM: splitwind( f, n); break; case ONE_ITEM: onlywind( f, n); break; case QUERY_ITEM: qreplace( f, n); break; case NEW_ITEM: spawncli( f, n); break; case QUIT_ITEM: quickexit( f, n); break; case NOOP_ITEM: break; } break; } } mouse_handle_event( execute, f, n) { register char *s; char instr[ 81]; /* 8 nine digit numbers with separators + 1 */ int result, c, class, subclass, keycode, qualifiers, x, y, secs, musecs; static int netx, nety; static int button_now = 0, button_ever = 0; for( s = instr; (*s++ = ttgetc()) != '|';); *s = 0; /* terminate the str */ if( ! execute) return; sscanf( instr, "%d;%d;%d;%d;%d;%d;%d;%d|", &class, &subclass, &keycode, &qualifiers, &x, &y, &secs, &musecs); switch( class) { case 2: /* mouse button--only get this for left button */ if( keycode & 0x80) { /* key up */ keycode &= ~0x80; /* clear the up bit */ button_now &= ~ LEFT_BUTTON; } else { /* key down */ netx = Window->MouseX - Window->BorderLeft; /* save coords */ nety = Window->MouseY - Window->BorderTop; button_now |= LEFT_BUTTON; button_ever |= LEFT_BUTTON; } break; case 10: /* menu selection -- right button up only */ if( keycode == MENUNULL) { netx = Window->MouseX - Window->BorderLeft; /* save coords */ nety = Window->MouseY - Window->BorderTop; button_ever |= RIGHT_BUTTON; } else { /* made a menu selection */ button_ever = 0; /* ignore other buttons */ do_menu( keycode, f, n); } break; } if(( ! button_now) && button_ever) { /* buttons were pushed: interpret */ switch( button_ever) { case LEFT_BUTTON: mouse_to_xy( netx, nety); break; case RIGHT_BUTTON: mouse_set_mark( netx, nety); break; case LEFT_BUTTON | RIGHT_BUTTON: backdel( f, n); break; } button_ever = 0; } } mouse_newmenu( menu, item_names, menu_items, menu_text, num_items, Mwidth, flag) struct Menu *menu; /* Menu structure */ char *item_names[]; /* Pointer to array of item names */ struct MenuItem menu_items[]; /* pointer to array of structures */ struct IntuiText menu_text[]; /* Pointer to array of text structures */ int num_items; /* Number of items */ int Mwidth; /* Menu Width */ int flag; /* Special Item flag for ALL items */ { int i; int height = 0; for (i=0; i< num_items; i++) { menu_text[i] = generic; /* stamp generic template */ menu_text[i].IText = (UBYTE *) item_names[i]; /* mv string ptrs */ menu_items[i].NextItem = &menu_items[i+1]; /* Lnk to nxt item */ menu_items[i].TopEdge = 10 * i; /* Top rect of item */ menu_items[i].LeftEdge = 0; menu_items[i].Height = 8; menu_items[i].ItemFill = (APTR)&menu_text[i]; menu_items[i].Flags = flag; menu_items[i].Width = Mwidth; menu_items[i].MutualExclude = 0x0000; menu_items[i].Command = 0; menu_items[i].SubItem = NL; menu_items[i].NextSelect = NL; height += 10; } menu_items[num_items-1].NextItem = NULL; menu->Height = height; } static winddist( w, row, col) /* calc distance of window from this row, col */ WINDOW *w; { int d; if( row < w->w_toprow) /* above window */ return( w->w_toprow - row); else if( row < (w->w_toprow + w->w_ntrows)) /* within window */ return( 0); else /* below window */ return( row - (w->w_toprow + w->w_ntrows)); } WINDOW * mouse_find_wind( row, col) /* find window containing this row, col */ { WINDOW *w, *result_w; int distance, result_distance; result_distance = HUGE; /* greater than any real distance */ for( w = wheadp; w != NULL; w = w->w_wndp) { distance = winddist( w, row, col); if( distance < result_distance) { result_w = w; result_distance = distance; } } return( result_w); } static get_wintop( this_w) /* return row for top of this window */ WINDOW *this_w; { register WINDOW *w; register int row; row = 0; for( w = wheadp; w != this_w; w = w->w_wndp) { row += w->w_ntrows +1; } return( row); } mouse_to_xy( x, y) /* move point to position at coords x,y */ { register LINE *dlp; register int row, col; WINDOW *w; row = y / FONT_Y; /* convert coords to row and col */ col = x / FONT_X; w = mouse_find_wind( row, col); /* find the window and make it current */ curwp = w; curbp = curwp->w_bufp; row -= get_wintop( curwp); /* adjust to row in window */ if( row >= curwp->w_ntrows) row = curwp->w_ntrows -1; dlp = curwp->w_linep; while (row-- && dlp!=curbp->b_linep) { dlp = lforw(dlp); } curwp->w_dotp = dlp; curgoal = col; /* aim for this col */ curwp->w_doto = getgoal(dlp); } mouse_set_mark( x, y) /* set mark at mouse cursor */ { WINDOW *wp; LINE *dlp; int offset; /* save current position */ wp = curwp; dlp = curwp->w_dotp; offset = curwp->w_doto; /* go to cursor position, set mark, and announce */ mouse_to_xy( x, y); update(); setmark( FALSE, 1); update(); /* return to former position */ curwp = wp; curbp = curwp->w_bufp; curwp->w_dotp = dlp; curwp->w_doto = offset; } mouse_enable() /* this must be last to keep ctags happy */ { ttputs( "[2;10{"); /* get mouse button and menu events */ ttflush(); }