#include #include #include "regions.h" struct region { int id; int x, y, w, h; bool enabled; void (*mouse_in)( int ); void (*mouse_out)( int ); void (*mouse_click)( int, unsigned int ); struct region *next; }; struct regioned_window { Window win; struct region *first_reg; struct regioned_window *next; }; static struct regioned_window *regioned_windows=NULL; static Display *dpy=NULL; static struct region *region_locate( Window win, int x, int y ); static struct region *region_find( Window win, int id ); static struct regioned_window *region_get_win( Window win ); void region_init( Display *_dpy ) { dpy = _dpy; } void region_add( Window win, int id, int x, int y, int w, int h, void (*mouse_in)(int), void (*mouse_out)(int), void (*mouse_click)(int, unsigned int) ) { /* cerate the region and set its fields */ struct region *reg = new region; reg->id = id; reg->x = x; reg->y = y; reg->w = w; reg->h = h; reg->enabled = true; reg->mouse_in = mouse_in; reg->mouse_out = mouse_out; reg->mouse_click = mouse_click; /* find the regioned_win and insert the new region into its list of regions */ struct regioned_window *reg_win = region_get_win(win); reg->next = reg_win->first_reg; reg_win->first_reg = reg; } void region_enable( Window win, int id ) { struct region *reg = region_find( win, id ); if( reg != NULL ) reg->enabled = true; } void region_disable( Window win, int id ) { struct region *reg = region_find( win, id ); if( reg != NULL ) reg->enabled = false; } bool region_in( Window win, int x, int y ) { return (region_locate(win,x,y) != NULL); } void region_mouse_motion( Window win, int x, int y ) { struct region *reg; static struct region *last_active_reg=NULL; reg = region_locate( win, x, y ); if( reg == last_active_reg ) return; if( last_active_reg != NULL ) { last_active_reg->mouse_out( last_active_reg->id ); XUngrabPointer( dpy, CurrentTime ); } if( reg != NULL ) { reg->mouse_in( reg->id) ; XGrabPointer( dpy, win, true, PointerMotionMask|ButtonPress, GrabModeAsync, GrabModeAsync, None, None, CurrentTime ); } last_active_reg = reg; } void region_mouse_click( Window win, int x, int y, unsigned int button ) { struct region *reg; region_mouse_motion( win, x, y ); if( (reg=region_locate(win,x,y)) != NULL ) reg->mouse_click(reg->id, button); } static struct region *region_locate( Window win, int x, int y ) { struct region *reg = region_get_win(win)->first_reg; while( reg != NULL ) { if( (x >= reg->x) && (x <= reg->x+reg->w) && (y >= reg->y) && (y <= reg->y+reg->h ) && reg->enabled ) return reg; reg = reg->next; } return NULL; } static struct region *region_find( Window win, int id ) { struct region *reg = region_get_win(win)->first_reg; while( reg != NULL ) { if( reg->id == id ) return reg; reg = reg->next; } return NULL; } static struct regioned_window *region_get_win( Window win ) { struct regioned_window *reg_win = regioned_windows; while( reg_win != NULL ) { if( reg_win->win == win ) return reg_win; reg_win = reg_win->next; } reg_win = new regioned_window; reg_win->win = win; reg_win->first_reg = NULL; reg_win->next = regioned_windows; regioned_windows = reg_win; return reg_win; }