=================================================================== ChangeSet@xxxx, 2004-08-10 00:53:10-05:00, dtor_core@xxxxxxxxxxxxx Remove global "state" structure, code cleanups. gpm.c | 229 ++++++++++++++++++++++++++++++++++-------------------------------- 1 files changed, 119 insertions(+), 110 deletions(-) =================================================================== diff -Nru a/src/gpm.c b/src/gpm.c --- a/src/gpm.c 2004-08-10 01:17:59 -05:00 +++ b/src/gpm.c 2004-08-10 01:17:59 -05:00 @@ -3,7 +3,7 @@ * * Copyright (C) 1993 Andreq Haylett <ajh@xxxxxxxxxxxxx> * Copyright (C) 1994-1999 Alessandro Rubini <rubini@xxxxxxxx> - * Copyright (C) 1998 Ian Zimmerman <itz@xxxxxxxxx> + * Copyright (C) 1998 Ian Zimmerman <itz@xxxxxxxxx> * Copyright (c) 2001,2002 Nico Schottelius <nico-gpm@xxxxxxxxxxxxxxx> * * This program is free software; you can redistribute it and/or modify @@ -56,12 +56,6 @@ static int console_resized; /* not really an option */ -static struct { - int x, y; - int buttons; - int clicks; -} state; - /*-------------------------------------------------------------------*/ static void gpm_killed(int signo) { @@ -88,7 +82,7 @@ /*....................................... read and identify one byte */ if (read(fd, data, type->howmany) != type->howmany) { if (option.test) exit(0); - gpm_report(GPM_PR_ERR,GPM_MESS_READ_FIRST, strerror(errno)); + gpm_report(GPM_PR_ERR, GPM_MESS_READ_FIRST, strerror(errno)); return NULL; } @@ -127,7 +121,7 @@ gpm_report(GPM_PR_ERR, GPM_MESS_READ_REST, strerror(errno)); return NULL; } - + if ((data[1] & type->proto[2]) != type->proto[3]) { gpm_report(GPM_PR_INFO, GPM_MESS_SKIP_DATA); return NULL; @@ -137,7 +131,7 @@ } /*-------------------------------------------------------------------*/ -void handle_console_resize(Gpm_Event *ePtr) +void handle_console_resize(Gpm_Event *event) { int old_x, old_y; struct micetab *mouse; @@ -145,11 +139,11 @@ old_x = console.max_x; old_y = console.max_y; refresh_console_size(); if (!old_x) { /* first invocation, place the pointer in the middle */ - state.x = ePtr->x = console.max_x / 2; - state.y = ePtr->y = console.max_y / 2; + event->x = console.max_x / 2; + event->y = console.max_y / 2; } else { /* keep the pointer in the same position where it was */ - state.x = ePtr->x = ePtr->x * console.max_x / old_x; - state.y = ePtr->y = ePtr->y * console.max_y / old_y; + event->x = event->x * console.max_x / old_x; + event->y = event->y * console.max_y / old_y; } for (mouse = micelist; mouse; mouse = mouse->next) { @@ -158,7 +152,7 @@ * has square cells. (An author-centric observation ;-) */ mouse->options.scaley = mouse->options.scalex * 50 * console.max_x / 80 / console.max_y; - gpm_report(GPM_PR_DEBUG, GPM_MESS_X_Y_VAL, + gpm_report(GPM_PR_DEBUG, GPM_MESS_X_Y_VAL, mouse->options.scalex, mouse->options.scaley); } } @@ -171,8 +165,7 @@ if (absolute_dev) { /* prepare the values from a absolute device for repeater mode */ gettimeofday(&now, (struct timezone *)NULL); - if (((now.tv_sec - last.tv_sec) * 1000 + - (now.tv_usec - last.tv_usec) / 1000) > 250) { + if (DIF_TIME(last, now) > 250) { event->dx = 0; event->dy = 0; } @@ -185,32 +178,109 @@ repeater.type->repeat_fun(event, repeater.fd); } +static void calculate_clicks(Gpm_Event *event, int click_tmo) +{ + static struct timeval release; + struct timeval now; + + switch(event->type) { /* now provide the cooked bits */ + case GPM_DOWN: + GET_TIME(now); + if (release.tv_sec && (DIF_TIME(release, now) < click_tmo)) /* check first click */ + event->clicks++, event->clicks %= 3; /* 0, 1 or 2 */ + else + event->clicks = 0; + event->type |= GPM_SINGLE << event->clicks; + break; + + case GPM_UP: + GET_TIME(release); + event->type |= GPM_SINGLE << event->clicks; + break; + + case GPM_DRAG: + event->type |= GPM_SINGLE << event->clicks; + break; + + case GPM_MOVE: + event->clicks = 0; + break; + + default: + break; + } +} + +static void snap_to_screen_limits(Gpm_Event *event) +{ + int extent; + + /* The current policy is to force the following behaviour: + * - At buttons down cursor position must be inside the screen, + * though flags are set. + * - At button up allow going outside by one single step + * + * We are using 1-baeed coordinates, like the original "selection". + * Only one margin will be reported, Y takes priority over X. + */ + + extent = (event->type & (GPM_DRAG|GPM_UP)) ? 1 : 0; + + event->margin = 0; + + if (event->y > console.max_y) { + event->y = console.max_y + extent; + extent = 0; + event->margin = GPM_BOT; + } else if (event->y <= 0) { + event->y = 1 - extent; + extent = 0; + event->margin = GPM_TOP; + } + + if (event->x > console.max_x) { + event->x = console.max_x + extent; + if (!event->margin) event->margin = GPM_RGT; + } else if (event->x <= 0) { + event->x = 1 - extent; + if (!event->margin) event->margin = GPM_LFT; + } +} + +static int more_data_waiting(int fd) +{ + static struct timeval timeout = {0, 0}; + fd_set fdSet; + + FD_ZERO(&fdSet); + FD_SET(fd, &fdSet); + select(fd + 1, &fdSet, NULL_SET, NULL_SET, &timeout/* zero */); + + return FD_ISSET(fd, &fdSet); +} + /*------------------------------------------------------------------- - * call getMouseData to get hardware device data, call mouse device's fun() + * call getMouseData to get hardware device data, call mouse device's fun() * to retrieve the hardware independent event data, then optionally repeat * the data via repeat_fun() to the repeater device *-------------------------------------------------------------------*/ static enum mouse_rslt processMouse(struct micetab *mouse, int attempt, Gpm_Event *event, int text_mode) { - char *data; - unsigned char shift_state; static int last_active; static int fine_dx, fine_dy; - int i; + static int oldB; + static Gpm_Event nEvent; - struct timeval now; - static struct timeval button_release; /* tv1==0: first click is single */ - static struct timeval timeout = {0, 0}; - fd_set fdSet; struct Gpm_Type *type = mouse->type; struct miceopt *opt = &mouse->options; - static int oldB; /* old buttons and Type to chain events */ - int oldT = event->type; enum mouse_rslt rslt = MOUSE_DATA_OK; + unsigned char shift_state; + char *data; + int i; - if (attempt > 1) { - if (opt->absolute) { /* a pen or other absolute device */ + if (attempt > 1) { /* continue interrupted cluster loop */ + if (opt->absolute) { event->x = nEvent.x; event->y = nEvent.y; } @@ -221,7 +291,6 @@ event->dx = event->dy = 0; event->wdx = event->wdy = 0; nEvent.modifiers = 0; /* some mice set them */ - FD_ZERO(&fdSet); FD_SET(mouse->dev.fd, &fdSet); i = 0; do { /* cluster loop */ @@ -235,7 +304,7 @@ /* propagate buttons */ nEvent.buttons = (opt->sequence[nEvent.buttons & 7] & 7) | - (nEvent.buttons & ~7); /* change the order */ + (nEvent.buttons & ~7); /* change the order */ if (!i) event->buttons = nEvent.buttons; if (oldB != nEvent.buttons) { @@ -261,9 +330,7 @@ event->wdx += nEvent.wdx; event->wdy += nEvent.wdy; - select(mouse->dev.fd + 1, &fdSet, NULL_SET, NULL_SET, &timeout/* zero */); - - } while (i++ < opt->cluster && FD_ISSET(mouse->dev.fd, &fdSet)); + } while (i++ < opt->cluster && more_data_waiting(mouse->dev.fd)); } /* if(eventFlag) */ /*....................................... update the button number */ @@ -306,7 +373,6 @@ /*....................................... fill missing fields */ event->x += event->dx; event->y += event->dy; - state.buttons = event->buttons; event->vc = get_console_state(&shift_state); if (event->vc != last_active) { @@ -316,85 +382,28 @@ event->modifiers |= shift_state; if (oldB == event->buttons) - event->type = (event->buttons ? GPM_DRAG : GPM_MOVE); - else - event->type = (event->buttons > oldB ? GPM_DOWN : GPM_UP); - - switch(event->type) { /* now provide the cooked bits */ - case GPM_DOWN: - GET_TIME(now); - if (button_release.tv_sec && (DIF_TIME(button_release, now) < opt->time)) /* check first click */ - state.clicks++, state.clicks %= 3; /* 0, 1 or 2 */ - else - state.clicks = 0; - event->type |= GPM_SINGLE << state.clicks; - break; - - case GPM_UP: - GET_TIME(button_release); + event->type = (event->buttons ? (GPM_DRAG | GPM_MFLAG) : GPM_MOVE); + else { + if (event->buttons > oldB) + event->type = GPM_DOWN; + else { + event->type &= GPM_MFLAG; + event->type |= GPM_UP; event->buttons ^= oldB; /* for button-up, tell which one */ - event->type |= oldT & GPM_MFLAG; - event->type |= GPM_SINGLE << state.clicks; - break; - - case GPM_DRAG: - event->type |= GPM_MFLAG; - event->type |= GPM_SINGLE << state.clicks; - break; - - case GPM_MOVE: - state.clicks = 0; - - default: - break; - } - event->clicks = state.clicks; - -/* UGLY - FIXME! */ -/* The current policy is to force the following behaviour: - * - At buttons up, must fit inside the screen, though flags are set. - * - At button down, allow going outside by one single step - */ - - - /* selection used 1-based coordinates, so do I */ - - /* - * 1.05: only one margin is current. Y takes priority over X. - * The i variable is how much margin is allowed. "m" is which one is there. - */ - - i = (event->type & (GPM_DRAG|GPM_UP)) != 0; /* i is boolean */ - - if (event->y > console.max_y) { - event->y = console.max_y + 1 - !i; - i = 0; - event->margin = GPM_BOT; - } else if (event->y <= 0) { - event->y = 1 - i; - i = 0; - event->margin = GPM_TOP; - } - - if (event->x > console.max_x) { - event->x = console.max_x + 1 - !i; - if (!event->margin) event->margin = GPM_RGT; - } else if (event->x <= 0) { - event->x = 1 - i; - if (!event->margin) event->margin = GPM_LFT; + } } + calculate_clicks(event, opt->time); + snap_to_screen_limits(event); gpm_report(GPM_PR_DEBUG,"M: %3i %3i (%3i %3i) - butt=%i vc=%i cl=%i", event->dx, event->dy, event->x, event->y, event->buttons, event->vc, event->clicks); - /* update the global state */ - state.x = event->x; state.y = event->y; oldB = nEvent.buttons; if (opt_special && (event->type & GPM_DOWN) && !processSpecial(event)) rslt = MOUSE_NO_DATA; - + return rslt; } @@ -519,9 +528,9 @@ pending--; if ((ci = accept_client_connection(ctlfd))) { if (ci->data.eventMask & GPM_MOVE) { - Gpm_Event event = { 0, 0, ci->data.vc, 0, 0, - state.x, state.y, GPM_MOVE, 0, 0 }; - do_client(ci, &event); + Gpm_Event e = { 0, 0, ci->data.vc, 0, 0, + event.x, event.y, GPM_MOVE, 0, 0 }; + do_client(ci, &e); } FD_SET(ci->fd, &connSet); FD_SET(ci->fd, &readySet); @@ -536,8 +545,8 @@ if (FD_ISSET(ci->fd, &selSet)) { FD_CLR(ci->fd, &selSet); pending--; - if (!process_client_request(ci, i, state.x, state.y, state.clicks, - state.buttons, micelist->options.three_button)) { + if (!process_client_request(ci, i, event.x, event.y, event.clicks, + event.buttons, micelist->options.three_button)) { FD_CLR(ci->fd, &connSet); FD_CLR(ci->fd, &readySet); remove_client(ci, i); @@ -552,10 +561,10 @@ if (FD_ISSET(i, &selSet)) { FD_CLR(i, &selSet); pending--; - gpm_report(GPM_PR_WARN, GPM_MESS_STRANGE_DATA,i); + gpm_report(GPM_PR_WARN, GPM_MESS_STRANGE_DATA, i); } } - + /*................... all done. */ if (pending) gpm_report(GPM_PR_OOPS, GPM_MESS_SELECT_PROB); } /* while(1) */ _______________________________________________ gpm mailing list gpm@xxxxxxxxxxxxxx http://lists.linux.it/listinfo/gpm