154 lines
3.2 KiB
C++
154 lines
3.2 KiB
C++
#include <string.h>
|
|
#include <X11/Xlib.h>
|
|
#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;
|
|
}
|