home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
001-099
/
ff022.lzh
/
Pemacs
/
mouse.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-05-10
|
8KB
|
342 lines
/*
* This file implements memacs support for the Amiga mouse.
* Author: Andy Poggio
*/
#include <exec/types.h>
#include <exec/exec.h>
#include <intuition/intuition.h>
#include <devices/console.h>
#include <stdio.h>
#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( "0{"); /* get mouse button and menu events */
ttflush();
}