From 530d6fc55ac1fe955b31fe09e93b0f4a11985403 Mon Sep 17 00:00:00 2001 From: KATO Takenori Date: Tue, 9 Dec 1997 11:58:02 +0000 Subject: [PATCH] Sync with sys/i386/isa/mse.c and syscons.c revisions 1.36 and 1.242, respectively. --- sys/pc98/pc98/mse.c | 228 +++++++++++++++++-- sys/pc98/pc98/syscons.c | 484 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 643 insertions(+), 69 deletions(-) diff --git a/sys/pc98/pc98/mse.c b/sys/pc98/pc98/mse.c index 19f7b800db11..740c6466be1d 100644 --- a/sys/pc98/pc98/mse.c +++ b/sys/pc98/pc98/mse.c @@ -11,7 +11,7 @@ * this software for any purpose. It is provided "as is" * without express or implied warranty. * - * $Id: mse.c,v 1.12 1997/09/14 16:27:31 kato Exp $ + * $Id: mse.c,v 1.13 1997/11/19 11:35:52 kato Exp $ */ /* * Driver for the Logitech and ATI Inport Bus mice for use with 386bsd and @@ -58,10 +58,14 @@ #endif /*DEVFS*/ #include +#include #include #include +/* driver configuration flags (config) */ +#define MSE_CONFIG_ACCEL 0x00f0 /* acceleration factor */ +#define MSE_CONFIG_FLAGS (MSE_CONFIG_ACCEL) static int mseprobe(struct isa_device *); static int mseattach(struct isa_device *); @@ -74,12 +78,13 @@ struct isa_driver msedriver = { static d_open_t mseopen; static d_close_t mseclose; static d_read_t mseread; +static d_ioctl_t mseioctl; static d_poll_t msepoll; #define CDEV_MAJOR 27 static struct cdevsw mse_cdevsw = { mseopen, mseclose, mseread, nowrite, /*27*/ - noioc, nostop, nullreset, nodevtotty,/* mse */ + mseioctl, nostop, nullreset, nodevtotty,/* mse */ msepoll, nommap, NULL, "mse", NULL, -1 }; @@ -87,7 +92,6 @@ static struct cdevsw mse_cdevsw = * Software control structure for mouse. The sc_enablemouse(), * sc_disablemouse() and sc_getmouse() routines must be called spl'd(). */ -#define PROTOBYTES 5 static struct mse_softc { int sc_flags; int sc_mousetype; @@ -101,7 +105,10 @@ static struct mse_softc { int sc_obuttons; int sc_buttons; int sc_bytesread; - u_char sc_bytes[PROTOBYTES]; + u_char sc_bytes[MOUSE_SYS_PACKETSIZE]; + mousehw_t hw; + mousemode_t mode; + mousestatus_t status; #ifdef DEVFS void *devfs_token; void *n_devfs_token; @@ -244,12 +251,24 @@ static struct mse_types { /* Disable interrupts routine */ void (*m_get) __P((u_int port, int *dx, int *dy, int *but)); /* and get mouse status */ +#ifndef PC98 + mousehw_t m_hw; /* buttons iftype type model hwid */ + mousemode_t m_mode; /* proto rate res accel level size mask */ +#endif } mse_types[] = { #ifdef PC98 { MSE_98BUSMOUSE, mse_probe98m, mse_enable98m, mse_disable98m, mse_get98m }, #else - { MSE_ATIINPORT, mse_probeati, mse_enableati, mse_disableati, mse_getati }, - { MSE_LOGITECH, mse_probelogi, mse_enablelogi, mse_disablelogi, mse_getlogi }, + { MSE_ATIINPORT, + mse_probeati, mse_enableati, mse_disableati, mse_getati, + { 2, MOUSE_IF_INPORT, MOUSE_MOUSE, MOUSE_MODEL_GENERIC, 0, }, + { MOUSE_PROTO_INPORT, -1, -1, 0, 0, MOUSE_MSC_PACKETSIZE, + { MOUSE_MSC_SYNCMASK, MOUSE_MSC_SYNC, }, }, }, + { MSE_LOGITECH, + mse_probelogi, mse_enablelogi, mse_disablelogi, mse_getlogi, + { 2, MOUSE_IF_BUS, MOUSE_MOUSE, MOUSE_MODEL_GENERIC, 0, }, + { MOUSE_PROTO_BUS, -1, -1, 0, 0, MOUSE_MSC_PACKETSIZE, + { MOUSE_MSC_SYNCMASK, MOUSE_MSC_SYNC, }, }, }, #endif { 0, }, }; @@ -271,6 +290,10 @@ mseprobe(idp) sc->sc_enablemouse = mse_types[i].m_enable; sc->sc_disablemouse = mse_types[i].m_disable; sc->sc_getmouse = mse_types[i].m_get; +#ifndef PC98 + sc->hw = mse_types[i].m_hw; + sc->mode = mse_types[i].m_mode; +#endif return (1); } i++; @@ -298,6 +321,7 @@ mseattach(idp) #endif sc->sc_port = idp->id_iobase; + sc->mode.accelfactor = (idp->id_flags & MSE_CONFIG_ACCEL) >> 4; #ifdef DEVFS sc->devfs_token = devfs_add_devswf(&mse_cdevsw, unit << 1, DV_CHR, 0, 0, @@ -330,9 +354,13 @@ mseopen(dev, flags, fmt, p) if (sc->sc_flags & MSESC_OPEN) return (EBUSY); sc->sc_flags |= MSESC_OPEN; - sc->sc_obuttons = sc->sc_buttons = 0x7; + sc->sc_obuttons = sc->sc_buttons = MOUSE_MSC_BUTTONS; sc->sc_deltax = sc->sc_deltay = 0; - sc->sc_bytesread = PROTOBYTES; + sc->sc_bytesread = sc->mode.packetsize = MOUSE_MSC_PACKETSIZE; + sc->mode.level = 0; + sc->status.flags = 0; + sc->status.button = sc->status.obutton = 0; + sc->status.dx = sc->status.dy = sc->status.dz = 0; /* * Initialize mouse interface and enable interrupts. @@ -382,7 +410,7 @@ mseread(dev, uio, ioflag) * packet. */ s = spltty(); /* XXX Should be its own spl, but where is imlXX() */ - if (sc->sc_bytesread >= PROTOBYTES) { + if (sc->sc_bytesread >= sc->mode.packetsize) { while (sc->sc_deltax == 0 && sc->sc_deltay == 0 && (sc->sc_obuttons ^ sc->sc_buttons) == 0) { if (MSE_NBLOCKIO(dev)) { @@ -402,7 +430,8 @@ mseread(dev, uio, ioflag) * For some reason X386 expects 5 bytes but never uses * the fourth or fifth? */ - sc->sc_bytes[0] = 0x80 | (sc->sc_buttons & ~0xf8); + sc->sc_bytes[0] = sc->mode.syncmask[1] + | (sc->sc_buttons & ~sc->mode.syncmask[0]); if (sc->sc_deltax > 127) sc->sc_deltax = 127; if (sc->sc_deltax < -127) @@ -415,18 +444,137 @@ mseread(dev, uio, ioflag) sc->sc_bytes[1] = sc->sc_deltax; sc->sc_bytes[2] = sc->sc_deltay; sc->sc_bytes[3] = sc->sc_bytes[4] = 0; + sc->sc_bytes[5] = sc->sc_bytes[6] = 0; + sc->sc_bytes[7] = MOUSE_SYS_EXTBUTTONS; sc->sc_obuttons = sc->sc_buttons; sc->sc_deltax = sc->sc_deltay = 0; sc->sc_bytesread = 0; } splx(s); - xfer = min(uio->uio_resid, PROTOBYTES - sc->sc_bytesread); + xfer = min(uio->uio_resid, sc->mode.packetsize - sc->sc_bytesread); if (error = uiomove(&sc->sc_bytes[sc->sc_bytesread], xfer, uio)) return (error); sc->sc_bytesread += xfer; return(0); } +/* + * mseioctl: process ioctl commands. + */ +static int +mseioctl(dev, cmd, addr, flag, p) + dev_t dev; + int cmd; + caddr_t addr; + int flag; + struct proc *p; +{ + register struct mse_softc *sc = &mse_sc[MSE_UNIT(dev)]; + mousestatus_t status; + int err = 0; + int s; + + switch (cmd) { + + case MOUSE_GETHWINFO: + s = spltty(); + *(mousehw_t *)addr = sc->hw; + if (sc->mode.level == 0) + ((mousehw_t *)addr)->model = MOUSE_MODEL_GENERIC; + splx(s); + break; + + case MOUSE_GETMODE: + s = spltty(); + *(mousemode_t *)addr = sc->mode; + switch (sc->mode.level) { + case 0: + break; + case 1: + ((mousemode_t *)addr)->protocol = MOUSE_PROTO_SYSMOUSE; + ((mousemode_t *)addr)->syncmask[0] = MOUSE_SYS_SYNCMASK; + ((mousemode_t *)addr)->syncmask[1] = MOUSE_SYS_SYNC; + break; + } + splx(s); + break; + + case MOUSE_SETMODE: + switch (((mousemode_t *)addr)->level) { + case 0: + case 1: + break; + default: + return (EINVAL); + } + if (((mousemode_t *)addr)->accelfactor < -1) + return (EINVAL); + else if (((mousemode_t *)addr)->accelfactor >= 0) + sc->mode.accelfactor = + ((mousemode_t *)addr)->accelfactor; + sc->mode.level = ((mousemode_t *)addr)->level; + switch (sc->mode.level) { + case 0: + sc->sc_bytesread = sc->mode.packetsize + = MOUSE_MSC_PACKETSIZE; + break; + case 1: + sc->sc_bytesread = sc->mode.packetsize + = MOUSE_SYS_PACKETSIZE; + break; + } + break; + + case MOUSE_GETLEVEL: + *(int *)addr = sc->mode.level; + break; + + case MOUSE_SETLEVEL: + switch (*(int *)addr) { + case 0: + sc->mode.level = *(int *)addr; + sc->sc_bytesread = sc->mode.packetsize + = MOUSE_MSC_PACKETSIZE; + break; + case 1: + sc->mode.level = *(int *)addr; + sc->sc_bytesread = sc->mode.packetsize + = MOUSE_SYS_PACKETSIZE; + break; + default: + return (EINVAL); + } + break; + + case MOUSE_GETSTATUS: + s = spltty(); + status = sc->status; + sc->status.flags = 0; + sc->status.obutton = sc->status.button; + sc->status.button = 0; + sc->status.dx = 0; + sc->status.dy = 0; + sc->status.dz = 0; + splx(s); + *(mousestatus_t *)addr = status; + break; + + case MOUSE_READSTATE: + case MOUSE_READDATA: + return (ENODEV); + +#if (defined(MOUSE_GETVARS)) + case MOUSE_GETVARS: + case MOUSE_SETVARS: + return (ENODEV); +#endif + + default: + return (ENOTTY); + } + return (err); +} + /* * msepoll: check for mouse input to be processed. */ @@ -442,8 +590,8 @@ msepoll(dev, events, p) s = spltty(); if (events & (POLLIN | POLLRDNORM)) - if (sc->sc_bytesread != PROTOBYTES || sc->sc_deltax != 0 || - sc->sc_deltay != 0 || + if (sc->sc_bytesread != sc->mode.packetsize || + sc->sc_deltax != 0 || sc->sc_deltay != 0 || (sc->sc_obuttons ^ sc->sc_buttons) != 0) revents |= events & (POLLIN | POLLRDNORM); else { @@ -465,7 +613,23 @@ void mseintr(unit) int unit; { + /* + * the table to turn MouseSystem button bits (MOUSE_MSC_BUTTON?UP) + * into `mousestatus' button bits (MOUSE_BUTTON?DOWN). + */ + static int butmap[8] = { + 0, + MOUSE_BUTTON3DOWN, + MOUSE_BUTTON2DOWN, + MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN, + MOUSE_BUTTON1DOWN, + MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN, + MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN, + MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN + }; register struct mse_softc *sc = &mse_sc[unit]; + int dx, dy, but; + int sign; #ifdef DEBUG static int mse_intrcnt = 0; @@ -475,7 +639,31 @@ mseintr(unit) if ((sc->sc_flags & MSESC_OPEN) == 0) return; - (*sc->sc_getmouse)(sc->sc_port, &sc->sc_deltax, &sc->sc_deltay, &sc->sc_buttons); + (*sc->sc_getmouse)(sc->sc_port, &dx, &dy, &but); + if (sc->mode.accelfactor > 0) { + sign = (dx < 0); + dx = dx * dx / sc->mode.accelfactor; + if (dx == 0) + dx = 1; + if (sign) + dx = -dx; + sign = (dy < 0); + dy = dy * dy / sc->mode.accelfactor; + if (dy == 0) + dy = 1; + if (sign) + dy = -dy; + } + sc->sc_deltax += dx; + sc->sc_deltay += dy; + sc->sc_buttons = but; + + but = butmap[~but & MOUSE_MSC_BUTTONS]; + sc->status.dx += dx; + sc->status.dy += dy; + sc->status.flags |= ((dx || dy) ? MOUSE_POSCHANGED : 0) + | (sc->status.button ^ but); + sc->status.button = but; /* * If mouse state has changed, wake up anyone wanting to know. @@ -560,7 +748,7 @@ mse_getlogi(port, dx, dy, but) outb(port + MSE_PORTC, MSE_HOLD | MSE_RXLOW); x = inb(port + MSE_PORTA); - *but = (x >> 5) & 0x7; + *but = (x >> 5) & MOUSE_MSC_BUTTONS; x &= 0xf; outb(port + MSE_PORTC, MSE_HOLD | MSE_RXHIGH); x |= (inb(port + MSE_PORTA) << 4); @@ -568,8 +756,8 @@ mse_getlogi(port, dx, dy, but) y = (inb(port + MSE_PORTA) & 0xf); outb(port + MSE_PORTC, MSE_HOLD | MSE_RYHIGH); y |= (inb(port + MSE_PORTA) << 4); - *dx += x; - *dy += y; + *dx = x; + *dy = y; outb(port + MSE_PORTC, MSE_INTREN); } @@ -632,13 +820,13 @@ mse_getati(port, dx, dy, but) outb(port + MSE_PORTA, MSE_INPORT_MODE); outb(port + MSE_PORTB, MSE_INPORT_HOLD); outb(port + MSE_PORTA, MSE_INPORT_STATUS); - *but = ~(inb(port + MSE_PORTB) & 0x7); + *but = ~inb(port + MSE_PORTB) & MOUSE_MSC_BUTTONS; outb(port + MSE_PORTA, MSE_INPORT_DX); byte = inb(port + MSE_PORTB); - *dx += byte; + *dx = byte; outb(port + MSE_PORTA, MSE_INPORT_DY); byte = inb(port + MSE_PORTB); - *dy += byte; + *dy = byte; outb(port + MSE_PORTA, MSE_INPORT_MODE); outb(port + MSE_PORTB, MSE_INPORT_INTREN); } diff --git a/sys/pc98/pc98/syscons.c b/sys/pc98/pc98/syscons.c index bb0eec493667..984bd781bc02 100644 --- a/sys/pc98/pc98/syscons.c +++ b/sys/pc98/pc98/syscons.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: syscons.c,v 1.64 1997/11/27 10:14:11 kato Exp $ + * $Id: syscons.c,v 1.65 1997/12/06 13:25:01 bde Exp $ */ #include "sc.h" @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -181,6 +182,8 @@ static char vgaregs[MODE_PARAM_SIZE]; static char vgaregs2[MODE_PARAM_SIZE]; static int rows_offset = 1; static char *cut_buffer; +static int mouse_level = 0; /* sysmouse protocol level */ +static mousestatus_t mouse_status = { 0, 0, 0, 0, 0, 0 }; static u_short mouse_and_mask[16] = { 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80, @@ -290,8 +293,14 @@ static void set_font_mode(u_char *buf); static void set_normal_mode(u_char *buf); static void set_destructive_cursor(scr_stat *scp); static void set_mouse_pos(scr_stat *scp); +static int skip_spc_right(scr_stat *scp, u_short *p); +static int skip_spc_left(scr_stat *scp, u_short *p); +static void mouse_cut(scr_stat *scp); static void mouse_cut_start(scr_stat *scp); static void mouse_cut_end(scr_stat *scp); +static void mouse_cut_word(scr_stat *scp); +static void mouse_cut_line(scr_stat *scp); +static void mouse_cut_extend(scr_stat *scp); static void mouse_paste(scr_stat *scp); static void draw_mouse_image(scr_stat *scp); static void remove_mouse_image(scr_stat *scp); @@ -918,6 +927,8 @@ scopen(dev_t dev, int flag, int mode, struct proc *p) scparam(tp, &tp->t_termios); ttsetwater(tp); (*linesw[tp->t_line].l_modem)(tp, 1); + if (minor(dev) == SC_MOUSE) + mouse_level = 0; /* XXX */ } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) @@ -1063,7 +1074,7 @@ int scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) { int error; - u_int i = 0; + u_int i; struct tty *tp; scr_stat *scp; u_short *usp; @@ -1071,6 +1082,7 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) u_short *atr_usp; #endif char *mp; + int s; tp = scdevtotty(dev); if (!tp) @@ -1209,10 +1221,22 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) case CONS_MOUSECTL: /* control mouse arrow */ { + /* MOUSE_BUTTON?DOWN -> MOUSE_MSC_BUTTON?UP */ + static butmap[8] = { + MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP + | MOUSE_MSC_BUTTON3UP, + MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP, + MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON3UP, + MOUSE_MSC_BUTTON3UP, + MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP, + MOUSE_MSC_BUTTON2UP, + MOUSE_MSC_BUTTON1UP, + 0, + }; mouse_info_t *mouse = (mouse_info_t*)data; if (!crtc_vga) - return ENXIO; + return ENODEV; switch (mouse->operation) { case MOUSE_MODE: @@ -1262,26 +1286,55 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) case MOUSE_GETINFO: mouse->u.data.x = scp->mouse_xpos; mouse->u.data.y = scp->mouse_ypos; + mouse->u.data.z = 0; mouse->u.data.buttons = scp->mouse_buttons; break; case MOUSE_ACTION: + case MOUSE_MOTION_EVENT: /* this should maybe only be settable from /dev/consolectl SOS */ /* send out mouse event on /dev/sysmouse */ + + mouse_status.dx += mouse->u.data.x; + mouse_status.dy += mouse->u.data.y; + mouse_status.dz += mouse->u.data.z; + if (mouse->operation == MOUSE_ACTION) + mouse_status.button = mouse->u.data.buttons; + mouse_status.flags |= + ((mouse->u.data.x || mouse->u.data.y || mouse->u.data.z) ? + MOUSE_POSCHANGED : 0) + | (mouse_status.obutton ^ mouse_status.button); + if (cur_console->status & MOUSE_ENABLED) cur_console->status |= MOUSE_VISIBLE; + if ((MOUSE_TTY)->t_state & TS_ISOPEN) { - u_char buf[5]; + u_char buf[MOUSE_SYS_PACKETSIZE]; int j; - buf[0] = 0x80 | ((~mouse->u.data.buttons) & 0x07); - buf[1] = (mouse->u.data.x & 0x1fe >> 1); - buf[3] = (mouse->u.data.x & 0x1ff) - buf[1]; - buf[2] = -(mouse->u.data.y & 0x1fe >> 1); - buf[4] = -(mouse->u.data.y & 0x1ff) - buf[2]; - for (j=0; j<5; j++) + /* the first five bytes are compatible with MouseSystems' */ + buf[0] = MOUSE_MSC_SYNC + | butmap[mouse_status.button & MOUSE_STDBUTTONS]; + j = imax(imin(mouse->u.data.x, 255), -256); + buf[1] = j >> 1; + buf[3] = j - buf[1]; + j = -imax(imin(mouse->u.data.y, 255), -256); + buf[2] = j >> 1; + buf[4] = j - buf[2]; + for (j = 0; j < MOUSE_MSC_PACKETSIZE; j++) (*linesw[(MOUSE_TTY)->t_line].l_rint)(buf[j],MOUSE_TTY); + if (mouse_level >= 1) { /* extended part */ + j = imax(imin(mouse->u.data.z, 127), -128); + buf[5] = (j >> 1) & 0x7f; + buf[6] = (j - (j >> 1)) & 0x7f; + /* buttons 4-10 */ + buf[7] = (~mouse_status.button >> 3) & 0x7f; + for (j = MOUSE_MSC_PACKETSIZE; + j < MOUSE_SYS_PACKETSIZE; j++) + (*linesw[(MOUSE_TTY)->t_line].l_rint)(buf[j],MOUSE_TTY); + } } + if (cur_console->mouse_signal) { cur_console->mouse_buttons = mouse->u.data.buttons; /* has controlling process died? */ @@ -1294,26 +1347,117 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) else psignal(cur_console->mouse_proc, cur_console->mouse_signal); } - else { + else if (mouse->operation == MOUSE_ACTION) { /* process button presses */ - if (cur_console->mouse_buttons != mouse->u.data.buttons) { + if ((cur_console->mouse_buttons ^ mouse->u.data.buttons) && + !(cur_console->status & UNKNOWN_MODE)) { cur_console->mouse_buttons = mouse->u.data.buttons; - if (!(cur_console->status & UNKNOWN_MODE)) { - if (cur_console->mouse_buttons & LEFT_BUTTON) - mouse_cut_start(cur_console); - else - mouse_cut_end(cur_console); - if (cur_console->mouse_buttons & RIGHT_BUTTON || - cur_console->mouse_buttons & MIDDLE_BUTTON) - mouse_paste(cur_console); - } + if (cur_console->mouse_buttons & MOUSE_BUTTON1DOWN) + mouse_cut_start(cur_console); + else + mouse_cut_end(cur_console); + if (cur_console->mouse_buttons & MOUSE_BUTTON2DOWN || + cur_console->mouse_buttons & MOUSE_BUTTON3DOWN) + mouse_paste(cur_console); } } + if (mouse->u.data.x != 0 || mouse->u.data.y != 0) { - cur_console->mouse_xpos += mouse->u.data.x; - cur_console->mouse_ypos += mouse->u.data.y; + cur_console->mouse_xpos += mouse->u.data.x; + cur_console->mouse_ypos += mouse->u.data.y; set_mouse_pos(cur_console); } + + break; + + case MOUSE_BUTTON_EVENT: + if ((mouse->u.event.id & MOUSE_BUTTONS) == 0) + return EINVAL; + if (mouse->u.event.value < 0) + return EINVAL; + + if (mouse->u.event.value > 0) { + cur_console->mouse_buttons |= mouse->u.event.id; + mouse_status.button |= mouse->u.event.id; + } else { + cur_console->mouse_buttons &= ~mouse->u.event.id; + mouse_status.button &= ~mouse->u.event.id; + } + mouse_status.flags |= + ((mouse->u.data.x || mouse->u.data.y || mouse->u.data.z) ? + MOUSE_POSCHANGED : 0) + | (mouse_status.obutton ^ mouse_status.button); + + if (cur_console->status & MOUSE_ENABLED) + cur_console->status |= MOUSE_VISIBLE; + + if ((MOUSE_TTY)->t_state & TS_ISOPEN) { + u_char buf[8]; + int i; + + buf[0] = MOUSE_MSC_SYNC + | butmap[mouse_status.button & MOUSE_STDBUTTONS]; + buf[7] = (~mouse_status.button >> 3) & 0x7f; + buf[1] = buf[2] = buf[3] = buf[4] = buf[5] = buf[6] = 0; + for (i = 0; + i < ((mouse_level >= 1) ? MOUSE_SYS_PACKETSIZE + : MOUSE_MSC_PACKETSIZE); i++) + (*linesw[(MOUSE_TTY)->t_line].l_rint)(buf[i],MOUSE_TTY); + } + + if (cur_console->mouse_signal) { + if (cur_console->mouse_proc && + (cur_console->mouse_proc != pfind(cur_console->mouse_pid))){ + cur_console->mouse_signal = 0; + cur_console->mouse_proc = NULL; + cur_console->mouse_pid = 0; + } + else + psignal(cur_console->mouse_proc, cur_console->mouse_signal); + break; + } + + if (cur_console->status & UNKNOWN_MODE) + break; + + switch (mouse->u.event.id) { + case MOUSE_BUTTON1DOWN: + switch (mouse->u.event.value % 4) { + case 0: /* up */ + mouse_cut_end(cur_console); + break; + case 1: + mouse_cut_start(cur_console); + break; + case 2: + mouse_cut_word(cur_console); + break; + case 3: + mouse_cut_line(cur_console); + break; + } + break; + case MOUSE_BUTTON2DOWN: + switch (mouse->u.event.value) { + case 0: /* up */ + break; + default: + mouse_paste(cur_console); + break; + } + break; + case MOUSE_BUTTON3DOWN: + switch (mouse->u.event.value) { + case 0: /* up */ + if (!(cur_console->mouse_buttons & MOUSE_BUTTON1DOWN)) + mouse_cut_end(cur_console); + break; + default: + mouse_cut_extend(cur_console); + break; + } + break; + } break; default: @@ -1324,6 +1468,107 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) return 0; } + /* MOUSE_XXX: /dev/sysmouse ioctls */ + case MOUSE_GETHWINFO: /* get device information */ + { + mousehw_t *hw = (mousehw_t *)data; + + if (tp != MOUSE_TTY) + return ENOTTY; + hw->buttons = 10; /* XXX unknown */ + hw->iftype = MOUSE_IF_SYSMOUSE; + hw->type = MOUSE_MOUSE; + hw->model = MOUSE_MODEL_GENERIC; + hw->hwid = 0; + return 0; + } + + case MOUSE_GETMODE: /* get protocol/mode */ + { + mousemode_t *mode = (mousemode_t *)data; + + if (tp != MOUSE_TTY) + return ENOTTY; + mode->level = mouse_level; + switch (mode->level) { + case 0: + /* at this level, sysmouse emulates MouseSystems protocol */ + mode->protocol = MOUSE_PROTO_MSC; + mode->rate = -1; /* unknown */ + mode->resolution = -1; /* unknown */ + mode->accelfactor = 0; /* disabled */ + mode->packetsize = MOUSE_MSC_PACKETSIZE; + mode->syncmask[0] = MOUSE_MSC_SYNCMASK; + mode->syncmask[1] = MOUSE_MSC_SYNC; + break; + + case 1: + /* at this level, sysmouse uses its own protocol */ + mode->protocol = MOUSE_PROTO_SYSMOUSE; + mode->rate = -1; + mode->resolution = -1; + mode->accelfactor = 0; + mode->packetsize = MOUSE_SYS_PACKETSIZE; + mode->syncmask[0] = MOUSE_SYS_SYNCMASK; + mode->syncmask[1] = MOUSE_SYS_SYNC; + break; + } + return 0; + } + + case MOUSE_SETMODE: /* set protocol/mode */ + { + mousemode_t *mode = (mousemode_t *)data; + + if (tp != MOUSE_TTY) + return ENOTTY; + if ((mode->level < 0) || (mode->level > 1)) + return EINVAL; + mouse_level = mode->level; + return 0; + } + + case MOUSE_GETLEVEL: /* get operation level */ + if (tp != MOUSE_TTY) + return ENOTTY; + *(int *)data = mouse_level; + return 0; + + case MOUSE_SETLEVEL: /* set operation level */ + if (tp != MOUSE_TTY) + return ENOTTY; + if ((*(int *)data < 0) || (*(int *)data > 1)) + return EINVAL; + mouse_level = *(int *)data; + return 0; + + case MOUSE_GETSTATUS: /* get accumulated mouse events */ + if (tp != MOUSE_TTY) + return ENOTTY; + s = spltty(); + *(mousestatus_t *)data = mouse_status; + mouse_status.flags = 0; + mouse_status.obutton = mouse_status.button; + mouse_status.dx = 0; + mouse_status.dy = 0; + mouse_status.dz = 0; + splx(s); + return 0; + +#if notyet + case MOUSE_GETVARS: /* get internal mouse variables */ + case MOUSE_SETVARS: /* set internal mouse variables */ + if (tp != MOUSE_TTY) + return ENOTTY; + return ENODEV; +#endif + + case MOUSE_READSTATE: /* read status from the device */ + case MOUSE_READDATA: /* read data from the device */ + if (tp != MOUSE_TTY) + return ENOTTY; + return ENODEV; + case CONS_GETINFO: /* get current (virtual) console info */ { vid_info_t *ptr = (vid_info_t*)data; @@ -1446,6 +1691,8 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) if (scp->history != NULL) i = imax(scp->history_size / scp->xsize - imax(SC_HISTORY_SIZE, scp->ysize), 0); + else + i = 0; switch (cmd & 0xff) { case M_VGA_C80x60: case M_VGA_M80x60: if (!(fonts_loaded & FONT_8)) @@ -5120,28 +5367,86 @@ set_mouse_pos(scr_stat *scp) scp->mouse_pos = scp->scr_buf + ((scp->mouse_ypos/scp->font_size)*scp->xsize + scp->mouse_xpos/8); - if ((scp->status & MOUSE_VISIBLE) && (scp->status & MOUSE_CUTTING)) { - u_short *ptr; - int i = 0; - - mark_for_update(scp, scp->mouse_cut_start - scp->scr_buf); - mark_for_update(scp, scp->mouse_cut_end - scp->scr_buf); - scp->mouse_cut_end = scp->mouse_pos; - for (ptr = (scp->mouse_cut_start > scp->mouse_cut_end - ? scp->mouse_cut_end : scp->mouse_cut_start); - ptr <= (scp->mouse_cut_start > scp->mouse_cut_end - ? scp->mouse_cut_start : scp->mouse_cut_end); - ptr++) { - cut_buffer[i++] = *ptr & 0xff; - if (((ptr - scp->scr_buf) % scp->xsize) == (scp->xsize - 1)) { - cut_buffer[i++] = '\n'; - } - } - cut_buffer[i] = 0x00; - } + if ((scp->status & MOUSE_VISIBLE) && (scp->status & MOUSE_CUTTING)) + mouse_cut(scp); } } +#define isspace(c) (((c) & 0xff) == ' ') + +static int +skip_spc_right(scr_stat *scp, u_short *p) +{ + int i; + + for (i = (p - scp->scr_buf) % scp->xsize; i < scp->xsize; ++i) { + if (!isspace(*p)) + break; + ++p; + } + return i; +} + +static int +skip_spc_left(scr_stat *scp, u_short *p) +{ + int i; + + for (i = (p-- - scp->scr_buf) % scp->xsize - 1; i >= 0; --i) { + if (!isspace(*p)) + break; + --p; + } + return i; +} + +static void +mouse_cut(scr_stat *scp) +{ + u_short *end; + u_short *p; + int i = 0; + int j = 0; + + scp->mouse_cut_end = (scp->mouse_pos >= scp->mouse_cut_start) ? + scp->mouse_pos + 1 : scp->mouse_pos; + end = (scp->mouse_cut_start > scp->mouse_cut_end) ? + scp->mouse_cut_start : scp->mouse_cut_end; + for (p = (scp->mouse_cut_start > scp->mouse_cut_end) ? + scp->mouse_cut_end : scp->mouse_cut_start; p < end; ++p) { + cut_buffer[i] = *p & 0xff; + /* remember the position of the last non-space char */ + if (!isspace(cut_buffer[i++])) + j = i; + /* trim trailing blank when crossing lines */ + if (((p - scp->scr_buf) % scp->xsize) == (scp->xsize - 1)) { + cut_buffer[j++] = '\n'; + i = j; + } + } + cut_buffer[i] = '\0'; + + /* scan towards the end of the last line */ + --p; + for (i = (p - scp->scr_buf) % scp->xsize; i < scp->xsize; ++i) { + if (!isspace(*p)) + break; + ++p; + } + /* if there is nothing but blank chars, trim them, but mark towards eol */ + if (i >= scp->xsize) { + if (scp->mouse_cut_start > scp->mouse_cut_end) + scp->mouse_cut_start = p; + else + scp->mouse_cut_end = p; + cut_buffer[j++] = '\n'; + cut_buffer[j] = '\0'; + } + + mark_for_update(scp, scp->mouse_cut_start - scp->scr_buf); + mark_for_update(scp, scp->mouse_cut_end - scp->scr_buf); +} + static void mouse_cut_start(scr_stat *scp) { @@ -5149,14 +5454,24 @@ mouse_cut_start(scr_stat *scp) if (scp->status & MOUSE_VISIBLE) { if (scp->mouse_pos == scp->mouse_cut_start && - scp->mouse_cut_start == scp->mouse_cut_end) { - cut_buffer[0] = 0x00; + scp->mouse_cut_start == scp->mouse_cut_end - 1) { + cut_buffer[0] = '\0'; remove_cutmarking(scp); - } - else { - scp->mouse_cut_start = scp->mouse_cut_end = scp->mouse_pos; + } else if (skip_spc_right(scp, scp->mouse_pos) >= scp->xsize) { + /* if the pointer is on trailing blank chars, mark towards eol */ + i = skip_spc_left(scp, scp->mouse_pos) + 1; + scp->mouse_cut_start = scp->scr_buf + + ((scp->mouse_pos - scp->scr_buf) / scp->xsize) * scp->xsize + i; + scp->mouse_cut_end = scp->scr_buf + + ((scp->mouse_pos - scp->scr_buf) / scp->xsize + 1) * scp->xsize; + cut_buffer[0] = '\n'; + cut_buffer[1] = '\0'; + scp->status |= MOUSE_CUTTING; + } else { + scp->mouse_cut_start = scp->mouse_pos; + scp->mouse_cut_end = scp->mouse_cut_start + 1; cut_buffer[0] = *scp->mouse_cut_start & 0xff; - cut_buffer[1] = 0x00; + cut_buffer[1] = '\0'; scp->status |= MOUSE_CUTTING; } mark_all(scp); @@ -5177,6 +5492,77 @@ mouse_cut_end(scr_stat *scp) } } +static void +mouse_cut_word(scr_stat *scp) +{ + u_short *p; + u_short *sol; + u_short *eol; + int i; + + /* + * Because we don't have locale information in the kernel, + * we only distinguish space char and non-space chars. Punctuation + * chars, symbols and other regular chars are all treated alike. + */ + if (scp->status & MOUSE_VISIBLE) { + sol = scp->scr_buf + + ((scp->mouse_pos - scp->scr_buf) / scp->xsize) * scp->xsize; + eol = sol + scp->xsize; + if (isspace(*scp->mouse_pos)) { + for (p = scp->mouse_pos; p >= sol; --p) + if (!isspace(*p)) + break; + scp->mouse_cut_start = ++p; + for (p = scp->mouse_pos; p < eol; ++p) + if (!isspace(*p)) + break; + scp->mouse_cut_end = p; + } else { + for (p = scp->mouse_pos; p >= sol; --p) + if (isspace(*p)) + break; + scp->mouse_cut_start = ++p; + for (p = scp->mouse_pos; p < eol; ++p) + if (isspace(*p)) + break; + scp->mouse_cut_end = p; + } + for (i = 0, p = scp->mouse_cut_start; p < scp->mouse_cut_end; ++p) + cut_buffer[i++] = *p & 0xff; + cut_buffer[i] = '\0'; + scp->status |= MOUSE_CUTTING; + } +} + +static void +mouse_cut_line(scr_stat *scp) +{ + u_short *p; + int i; + + if (scp->status & MOUSE_VISIBLE) { + scp->mouse_cut_start = scp->scr_buf + + ((scp->mouse_pos - scp->scr_buf) / scp->xsize) * scp->xsize; + scp->mouse_cut_end = scp->mouse_cut_start + scp->xsize; + for (i = 0, p = scp->mouse_cut_start; p < scp->mouse_cut_end; ++p) + cut_buffer[i++] = *p & 0xff; + cut_buffer[i++] = '\n'; + cut_buffer[i] = '\0'; + scp->status |= MOUSE_CUTTING; + } +} + +static void +mouse_cut_extend(scr_stat *scp) +{ + if ((scp->status & MOUSE_VISIBLE) && !(scp->status & MOUSE_CUTTING) + && (scp->mouse_cut_start != NULL)) { + mouse_cut(scp); + scp->status |= MOUSE_CUTTING; + } +} + static void mouse_paste(scr_stat *scp) { @@ -5307,7 +5693,7 @@ draw_cutmarking(scr_stat *scp) /* are we outside the selected area ? */ if ( ptr < (scp->mouse_cut_start > scp->mouse_cut_end ? scp->mouse_cut_end : scp->mouse_cut_start) || - ptr > (scp->mouse_cut_start > scp->mouse_cut_end ? + ptr >= (scp->mouse_cut_start > scp->mouse_cut_end ? scp->mouse_cut_start : scp->mouse_cut_end)) { #ifdef PC98 if (ptr != scp->mouse_pos)