Exemple #1
0
/*
 * Action: mouse button down on browser
 */
static void
project_bpress(
    Widget widget, 
    XEvent *event, 
    String *params, 
    int num_params
)
{
    XButtonEvent        *bevent;

    if (event->type == ButtonPress)
    {
        bevent = (XButtonEvent*)event;

        if (bevent->state == 0 && bevent->button == 1)/* RUBBERBAND SELECT */
        {
            if (ui_initiate_rubberband(widget, True, 
			project_rband, (XtPointer)NULL) == ERROR)
            {
                if (util_get_verbosity() > 0)
                    fprintf(stderr,"project organizer: couldn't begin rubberbanding\n");
            }
	    else
		mselect_adjust = False;
	}
        else if (bevent->button == 2 || /* RUBBERBAND ADJUST SELECT */
                 (bevent->button == 1 && (bevent->state & ShiftMask)))
	{
            if (ui_initiate_rubberband(widget, True, 
			project_rband, (XtPointer)NULL) == ERROR)
            {
                if (util_get_verbosity() > 0)
                    fprintf(stderr,"project organizer: couldn't begin rubberbanding\n");
            }
	    else
		mselect_adjust = True;
        }
    }
}
Exemple #2
0
/*************************************************************************
**                                                                      **
**       Function Definitions                                           **
**                                                                      **
**************************************************************************/
void
ui_win_front(
    Widget widget
)
{
    Widget p_shell;

    if (widget == NULL)
	return;

    p_shell = ui_get_ancestor_shell(widget);

    if (XtIsRealized(p_shell))
        XRaiseWindow(XtDisplay(p_shell),XtWindow(p_shell));
    else
	if (util_get_verbosity() > 0)
	    fprintf(stderr,"ui_win_front: widget not realized\n");

}
Exemple #3
0
/*
 * Action: Show the module when double-clicked on.
 */
static void
show_module(
    Widget widget, 
    XEvent *event, 
    String *params, 
    int num_params
)
{
    Vwr         v = NULL;
    VNode       selected_node;
    VMethods    m;
    ABObj       obj;
    ABObj       winobj;
    AB_TRAVERSAL trav;
 
    XtVaGetValues(widget, XmNuserData, &v, NULL);

    if (!v)
        return;

    selected_node = vwr_locate_node(v,
                        event->xbutton.x, event->xbutton.y);

    if (selected_node)
    {
        VNode   *selected_nodes = NULL;
        int     num_selected = 0;
 
        if (!(m = v->methods))
            return;

        /* USE METHODS !! */
        obj = (ABObj) selected_node->obj_data;
 
        if (!obj)
            return;

        /*
         * Set busy cursor before this potentially
         * lengthy operation
         */
        ab_set_busy_cursor(TRUE);

        /* If the module is already showing, then
         * make all of its windows come to the fore-
         * ground.
         */
        if (obj_has_flag(obj, MappedFlag))
        {
            for (trav_open(&trav, obj, AB_TRAV_WINDOWS);
                (winobj = trav_next(&trav)) != NULL; )
            {
                if (obj_has_flag(winobj, MappedFlag))
                    ui_win_front(objxm_get_widget(winobj));
            }
            trav_close(&trav);
            proj_set_cur_module(obj);
        }    
        else if( abobj_show_tree(obj, TRUE) == -1 )
        {
           if (util_get_verbosity() > 0)
             fprintf(stderr,"show_module: error in abobj_show_tree\n");
	}
        else 
        {
            proj_set_cur_module(obj);
        }

        vwr_get_cond(v->current_tree, &selected_nodes,
                        &num_selected, select_fn);

        if (selected_nodes)                        
            free((char *)selected_nodes);
 
        update_menu_items(0, num_selected);

        /*
         * Unset busy cursor
         */
        ab_set_busy_cursor(FALSE);

    }
}
Exemple #4
0
/*
 * Function for undoing RESIZE
 */
static void
undo_resize(
    ABUndoRec	undo_rec
)
{

    Position	x,
		y;
    int		width, 
    		height,
		i;
    ABObj       obj;

    if (!undo_rec)
	return;

    /*
     * Set undo to undo this resize (undo of undo)
     */
    (void)abobj_set_undo(undo_rec->list, undo_rec->count, 
		undo_resize, AB_UNDO_RESIZE);

    /*
     * For each object that was resized
     */
    for (i = 0; i < undo_rec->count; ++i)
    {
	BOOL	w_resizable, h_resizable;
	/*
	 * If undo record is not the right type, something is WRONG !!
	 */
	if (undo_rec->info_list[i].type != AB_UNDO_RESIZE)
	    continue;

        obj = undo_rec->list[i];
	w_resizable = abobj_width_resizable(obj);
	h_resizable = abobj_height_resizable(obj);

	/*
	 * Get current x,y position
	 */
	if (obj->ui_handle)
	{
            XtVaGetValues(objxm_get_widget(obj),
			XmNx,      &x,
			XmNy,      &y,
			NULL);
	}
	else
	{
	    x = (Position)obj_get_x(obj);
	    y = (Position)obj_get_y(obj);
	}

	/*
	 * Get previous width/height
	 */
        width = undo_rec->info_list[i].info.resize.width;
        height = undo_rec->info_list[i].info.resize.height;

        /* 
         * Resize the object !
         */
	resize_in_pixels(obj, (int)width, (int)height, border_w);
        abobj_set_xy(obj, (int)x, (int)y);

        if (xy_obj->attachments)
            abobj_calculate_new_layout(xy_obj, (int)x, (int)y,
                    width, height);

        abobj_instantiate_changes(obj);

        /* WORKAROUND for Motif XmForm bug (it ignores child resize request 
         * if x,y have not also changed). So, we have to force it.
         */
        abobj_force_dang_form_resize(xy_obj);

        if (util_get_verbosity() > 3)
            objxm_dump_widget_geometry(xy_widget);
    }
}
Exemple #5
0
/*
 *    Resize object according to info in last resize rubberbanding    
 */
int
abobj_resize(
    ABObj     obj, 
    XEvent     *event
)
{
    Widget       parent;
    Display      *dpy;
    XRectangle   p_rect;
    XRectangle	 adj_rect;
    Window       rootwin;
    int          orig_x, orig_y;
    int          trans_x, trans_y;
    ABObj	 moveobj;
    ABObj	 pobj;

    if (!first_move) /* resize occurred */
    {
        Window     win;

	if (obj_is_item(obj))
	    obj = obj_get_parent(obj);

	obj     = obj_get_root(obj);
        parent  = XtParent(xy_widget);
        dpy     = XtDisplay(xy_widget);

        orig_x = (int)resize_rect.x;
        orig_y = (int)resize_rect.y;

        first_move = TRUE;

        x_get_widget_rect(parent, &p_rect);

        rootwin = RootWindowOfScreen(XtScreen(xy_widget));

        /* erase last rect outline 
         */
        x_fullscreen_box(xy_widget, rootwin, 
        	resize_rect.x, resize_rect.y,
                rect_right(&resize_rect), 
                rect_bottom(&resize_rect));

        /* translate from root coordinates to parent's 
         */
        XTranslateCoordinates(dpy, rootwin, XtWindow(parent),
                        orig_x , orig_y, &trans_x, &trans_y, &win);

	resize_rect.width++;
	resize_rect.height++;

        /* Ensure new geometry fits within parent
         */
        if (trans_x < 0)
        {
            resize_rect.x = 0;
            resize_rect.width += trans_x;

	    if (obj_is_pane(obj) || obj_is_separator(obj)) /* If a pane, attach to parent's edge */
		obj_set_attachment(xy_obj, AB_CP_WEST, AB_ATTACH_OBJ, obj_get_parent(xy_obj), 0);
        }
        else    
	{
            resize_rect.x = trans_x;

            /* Break edge-attachment */
            if ((obj_is_pane(obj) || obj_is_separator(obj)) &&
                 (obj_get_attach_type(xy_obj, AB_CP_WEST) == AB_ATTACH_OBJ &&
                  obj_get_attach_value(xy_obj, AB_CP_WEST) == (void*)obj_get_parent(xy_obj)))
                obj_set_attachment(xy_obj, AB_CP_WEST, AB_ATTACH_POINT, (void*)0, trans_x);
        }

        if (trans_y < 0)
        {
            resize_rect.y = 0;
            resize_rect.height += trans_y;

            if (obj_is_pane(obj) || obj_is_separator(obj)) /* If a pane, attach to parent's edge */
                obj_set_attachment(xy_obj, AB_CP_NORTH, AB_ATTACH_OBJ, obj_get_parent(xy_obj), 0);
        }
        else
	{
            resize_rect.y = trans_y;

	    /* Break edge-attachment */
            if ((obj_is_pane(obj) || obj_is_separator(obj)) &&
		 (obj_get_attach_type(xy_obj, AB_CP_NORTH) == AB_ATTACH_OBJ &&
		  obj_get_attach_value(xy_obj, AB_CP_NORTH) == (void*)obj_get_parent(xy_obj))) 
                obj_set_attachment(xy_obj, AB_CP_NORTH, AB_ATTACH_POINT, (void*)0, trans_y);
	}

        if (resize_rect.x + (short)resize_rect.width >= (short)p_rect.width)
        {
            resize_rect.width = (short)p_rect.width - resize_rect.x - 1;

	    if (obj_is_pane(obj) || obj_is_separator(obj)) /* If a pane, attach to parent's edge */ 
		obj_set_attachment(xy_obj, AB_CP_EAST, AB_ATTACH_OBJ, obj_get_parent(xy_obj), 0);
	}
	else
	{
            /* Break edge-attachment */ 
	    if ((obj_is_pane(obj) || obj_is_separator(obj)) &&
                 (obj_get_attach_type(xy_obj, AB_CP_EAST) == AB_ATTACH_OBJ &&
                  obj_get_attach_value(xy_obj, AB_CP_EAST) == (void*)obj_get_parent(xy_obj))) 
                obj_set_attachment(xy_obj, AB_CP_EAST, AB_ATTACH_NONE, (void*)0, 0); 
        } 

        if (resize_rect.y + (short)resize_rect.height > (short)p_rect.height)
	{
            resize_rect.height = (short)p_rect.height - resize_rect.y - 1;

            if (obj_is_pane(obj) || obj_is_separator(obj)) /* If a pane, attach to parent's edge */
                obj_set_attachment(xy_obj, AB_CP_SOUTH, AB_ATTACH_OBJ, obj_get_parent(xy_obj), 0); 
	}
        else 
        {
            /* Break edge-attachment */ 
            if ((obj_is_pane(obj) || obj_is_separator(obj)) && 
                 (obj_get_attach_type(xy_obj, AB_CP_SOUTH) == AB_ATTACH_OBJ && 
                  obj_get_attach_value(xy_obj, AB_CP_SOUTH) == (void*)obj_get_parent(xy_obj)))  
                obj_set_attachment(xy_obj, AB_CP_SOUTH, AB_ATTACH_NONE, (void*)0, 0);  
        } 

	(void)abobj_set_undo(&obj, 1, undo_resize, AB_UNDO_RESIZE);

	pobj = obj_get_parent(obj);
 	if (obj_is_layers(pobj))
	    moveobj = pobj;
	else
	    moveobj = obj;

	adj_rect = resize_rect;
	if (abobj_has_attached_label(obj))
	    subtract_attached_label(obj, &adj_rect);

        if (obj_is_drawing_area(obj) && obj_has_scrollbar(obj))
        {
            int new_d_w = -1;
            int new_d_h = -1;
            int d_w = obj_get_drawarea_width(obj);
            int d_h = obj_get_drawarea_height(obj);
 
            /* If the overall DrawArea dimension is now larger than the internal
             * canvas dimension, resize the canvas dimension to be at least as large
             * as the overall DrawArea.
             */
            if ((int)resize_rect.width != obj_get_width(obj) &&
                (int)resize_rect.width > d_w)
                new_d_w = (int)resize_rect.width;
 
            if ((int)resize_rect.height != obj_get_height(obj) &&
                (int)resize_rect.height > d_h)
                new_d_h = (int)resize_rect.height;
 
            if (new_d_w != -1 || new_d_h != -1)
                abobj_set_drawarea_size(obj,
                        new_d_w != -1? new_d_w : d_w, new_d_h != -1? new_d_h : d_h);
        }

        /* 
 	 * Resize the object !
         */
	if (obj_is_layers(pobj))
	    abobj_layer_set_size(pobj, resize_rect.width, resize_rect.height);

        else if ((obj_is_text(obj) || obj_is_term_pane(obj)) &&
		  obj_get_num_columns(obj) != -1)
	    /* TextPane, TermPane, TextField with Character-based Sizing */
	    abobj_set_text_size(obj, (int)adj_rect.width, (int)adj_rect.height);

	else if (obj_is_list(obj) && obj_get_num_rows(obj) != -1)
	{
	    /* List with Character-based height */
	    abobj_set_text_size(obj, (int)adj_rect.width, (int)adj_rect.height);
	    abobj_set_pixel_width(obj, (int)adj_rect.width, border_w);
	}
	else /* else size is Pixel-based...*/
	    resize_in_pixels(obj, (int)adj_rect.width, (int)adj_rect.height, border_w);

        abobj_set_xy(moveobj, resize_rect.x, resize_rect.y);

	if (xy_obj->attachments)
	    abobj_calculate_new_layout(xy_obj, resize_rect.x, resize_rect.y,
		resize_rect.width, resize_rect.height);

	/* Change obj size BEFORE changing attachments...*/
	abobj_instantiate_changes(obj);
	abobj_tree_instantiate_changes(moveobj);

	/* WORKAROUND for Motif XmForm bug (it ignores child resize request 
	 * if x,y have not also changed). So, we have to force it.
	 */
	abobj_force_dang_form_resize(xy_obj);

	if (util_get_verbosity() > 3)
	    objxm_dump_widget_geometry(xy_widget);

        return OK;
    }
    return ERROR;

}
Exemple #6
0
/*
 *    Draw rubberbanding outline for resizing action    
 */
int
abobjP_resize_object_outline(
    ABObj        obj,
    XEvent       *event,
    RESIZE_DIR   dir
)
{
    ABObj	       s_obj;
    static Widget      parent;
    static Window      rootwin;
    static Display     *dpy;
    static XRectangle  orig_r, r;
    static int         last_x, last_y;
    int                x,y;
    char               buf[80];

    if (event->type == MotionNotify)
    {
    	x = ((XMotionEvent*)event)->x_root;
    	y = ((XMotionEvent*)event)->y_root;
    }
    else if (event->type == ButtonPress)
    {
        x = ((XButtonEvent*)event)->x_root;
        y = ((XButtonEvent*)event)->y_root;
    } 
    else
	return -1;

    if (first_move)
    {
        Window     win;
        int    orig_x, orig_y;
        int    trans_x, trans_y;

	if (obj_is_item(obj))
	    obj = obj_get_parent(obj);

	obj  = obj_get_root(obj);
	xy_obj = objxm_comp_get_subobj(obj, AB_CFG_POSITION_OBJ);
	xy_widget = (Widget)xy_obj->ui_handle;
 
        if (xy_widget == NULL)
        {
            if (util_get_verbosity() > 0)
                fprintf(stderr,"abobjP_resize_object_outline: %s :no SIZE widget\n",
			util_strsafe(obj_get_name(obj)));
            return ERROR;
        }
 
        parent  = XtParent(xy_widget);
        dpy     = XtDisplay(xy_widget);
        rootwin = RootWindowOfScreen(XtScreen(xy_widget));

        x_get_widget_rect(xy_widget, &orig_r);
	if (obj_has_border_frame(obj)) /* We have a border-frame to deal with */
	{
	    XRectangle pane_r;

            s_obj = objxm_comp_get_subobj(obj, AB_CFG_SIZE_OBJ);

	    /* Determine width of border */
	    x_get_widget_rect(objxm_get_widget(s_obj), &pane_r);
	    border_w = ((int)(orig_r.width - pane_r.width))/2;
	}
	else
	    border_w = 0;

	orig_r.width--;
	orig_r.height--;

        r = orig_r;

        orig_x = (int)orig_r.x;
        orig_y = (int)orig_r.y;

        XTranslateCoordinates(dpy, XtWindow(parent),
            rootwin, orig_x , orig_y, &trans_x, &trans_y,
            &win);

        r.x = (short)trans_x;
        r.y = (short)trans_y;

        first_move = FALSE;
    }
    else     /* erase previous outline */    
    {
        make_rect(&resize_rect, &r, last_x, last_y, dir);
        x_fullscreen_box(xy_widget, rootwin, 
                resize_rect.x, resize_rect.y,
                rect_right(&resize_rect), 
                rect_bottom(&resize_rect));

    }

    make_rect(&resize_rect, &r, x, y, dir);
    x_fullscreen_box(xy_widget, rootwin, 
                resize_rect.x, resize_rect.y,
                                rect_right(&resize_rect), 
                rect_bottom(&resize_rect));

    sprintf(buf, "%3.3dx%3.3d", resize_rect.width,
                                resize_rect.height);

    /* REMIND: aim, update status region on ab palette win */

    last_x = x;
    last_y = y;

    return OK;

}
Exemple #7
0
/*
 * Given a new x,y,width,height, calculate appropriate layout info
 */
int
abobj_calculate_new_layout(
    ABObj	obj,
    int		new_x,
    int		new_y,
    Dimension	new_width,
    Dimension	new_height
)
{
    ABObj	parent;
    ABAttachListPtr attachments;
    Position    x, y;
    Dimension   width, height;
    Dimension   p_width, p_height;
    long	gridpos;

    if ((attachments = obj->attachments) == NULL)
        return -1;

    if (obj->ui_handle == NULL)
    {
	if (util_get_verbosity() > 0)
	    fprintf(stderr,"abobj_calculate_new_layout: %s: NULL widget\n", obj_get_name(obj));
	return -1;
    }

    XtVaGetValues((Widget)obj->ui_handle,
			XmNx,		&x,
			XmNy,		&y,
                        XmNwidth,       &width,
                        XmNheight,      &height,
			NULL);

    parent = obj_get_parent(obj);
    XtVaGetValues((Widget)parent->ui_handle,
                        XmNwidth,       &p_width,
                        XmNheight,      &p_height,
                        NULL);

    switch(attachments->west.type)
    {
	case AB_ATTACH_POINT:
	   attachments->west.offset = new_x;
	   break;
	case AB_ATTACH_GRIDLINE:
	   gridpos = (100 * new_x)/(int)p_width;
	   attachments->west.value = (void*)gridpos;
	   break;
	case AB_ATTACH_CENTER_GRIDLINE:
           gridpos = (100 * (new_x + (int)new_width/2))/(int)p_width;
	   attachments->west.value = (void*)gridpos;
	   break;
	case AB_ATTACH_OBJ:
	case AB_ATTACH_ALIGN_OBJ_EDGE:
	   attachments->west.offset += (new_x - x);
	   if (new_x == 0 && attachments->west.offset < 0)
		attachments->west.offset = 0;
	   break;
    }

    switch(attachments->east.type) 
    { 
        case AB_ATTACH_POINT: 
           attachments->east.offset = p_width - (new_x + new_width);
           break;
        case AB_ATTACH_GRIDLINE:
           gridpos = (100 * (new_x + (int)new_width))/(int)p_width;
           attachments->east.value = (void*)gridpos;
           break;
	case AB_ATTACH_CENTER_GRIDLINE:
           gridpos = (100 * (new_x + (int)new_width/2))/(int)p_width;
           attachments->east.value = (void*)gridpos;
           break;
	case AB_ATTACH_OBJ:
	   attachments->east.offset = p_width - (new_x + new_width + 1);
	   break;
	case AB_ATTACH_ALIGN_OBJ_EDGE:
	   attachments->east.offset += (x + width - new_x - new_width);
	   break;
    }

    switch(attachments->north.type)
    {
        case AB_ATTACH_POINT:
           attachments->north.offset = new_y;
           break;
        case AB_ATTACH_GRIDLINE:
           gridpos = (100 * new_y)/(int)p_height;
           attachments->north.value = (void*)gridpos;
           break;
	case AB_ATTACH_CENTER_GRIDLINE:
           gridpos = (100 * (new_y + (int)new_height/2))/(int)p_height;
           attachments->north.value = (void*)gridpos;
           break;
        case AB_ATTACH_OBJ: 
        case AB_ATTACH_ALIGN_OBJ_EDGE: 
           attachments->north.offset += (new_y - y); 
           if (new_y == 0 && attachments->north.offset < 0) 
        	attachments->north.offset = 0; 
           break; 
    }

    switch(attachments->south.type)
    {
        case AB_ATTACH_POINT:
           attachments->south.offset = p_height - (new_y + new_height);
           break;
        case AB_ATTACH_GRIDLINE:
           gridpos = (100 * (new_y + (int)new_height))/(int)p_height;
           attachments->south.value = (void*)gridpos;
           break;
	case AB_ATTACH_CENTER_GRIDLINE:
           gridpos = (100 * (new_y + (int)new_height/2))/(int)p_height;
           attachments->south.value = (void*)gridpos;
           break;
        case AB_ATTACH_OBJ:
           attachments->south.offset = p_height - (new_y + new_height + 1);
	   break;
        case AB_ATTACH_ALIGN_OBJ_EDGE: 
           attachments->south.offset += (y + height - new_y - new_height); 
           break; 
    }

    objxm_obj_set_attachment_args(obj, OBJXM_CONFIG_BUILD);

    return 0;

}
Exemple #8
0
/*************************************************************************
**                                                                      **
**       Function Definitions                                           **
**                                                                      **
**************************************************************************/
int
abobjP_move_object_outline(
    ABObj         	obj, 
    XMotionEvent        *mevent
)
{
    static XRectangle parent_rect;
    static XRectangle last_rect;
    static int        x_offset, y_offset;
    static Dimension  border_w;
    static Display    *dpy;
    XRectangle	      widget_rect;
    int               trans_x, trans_y;

    /* First time: set up initial move variables */
    if (first_move)
    {
	if (obj_is_item(obj))
	    obj = obj_get_parent(obj);

	obj    = obj_get_root(obj);
	
        /* Multiple objects might be selected...*/ 
        if (obj_is_control(obj) || 
	    obj_is_group(obj) ||
	    obj_is_pane(obj)) 
        { 
            abobj_get_selected(obj_get_root(obj_get_parent(obj)), False, False, &sel);
        } 
        else
	{
            sel.count = 1; 
	    sel.list = (ABObj*)util_malloc(sizeof(ABObj));
	    sel.list[0] = obj;
	}

	xy_obj = objxm_comp_get_subobj(obj, AB_CFG_POSITION_OBJ);
        xy_widget = (Widget)xy_obj->ui_handle;

        if (xy_widget == NULL)
        {
            if (util_get_verbosity() > 2)
                fprintf(stderr,"abobjP_move_object_outline: %s :no POSITION widget\n",
			util_strsafe(obj_get_name(obj)));
            return ERROR;
        }

        dpy    = XtDisplay(xy_widget);
        parent = XtParent(xy_widget);

	x_get_widget_rect(xy_widget, &widget_rect);
        x_get_widget_rect(parent, &parent_rect);

	if (sel.count > 1)
	{
            abobj_get_rect_for_objects(sel.list, sel.count, &orig_rect);
	} 
	else
	{
	    orig_rect = widget_rect;
	    XtVaGetValues(xy_widget, XtNborderWidth, &border_w, NULL);
	    orig_rect.width  += (2*border_w);
	    orig_rect.height += (2*border_w);
	    orig_rect.width--;
	    orig_rect.height--;
	}
	move_rect = orig_rect;

        drag_init_rect.x     = mevent->x - AB_drag_threshold;
        drag_init_rect.y     = mevent->y - AB_drag_threshold;
        drag_init_rect.width = drag_init_rect.height = 2 * AB_drag_threshold;

	x_offset = widget_rect.x - orig_rect.x + mevent->x;
	y_offset = widget_rect.y - orig_rect.y + mevent->y;

        first_move  = False;

        rect_zero_out(&last_rect);
    }
    /* Don't begin rendering move outline until pointer is out of
     * the drag_init bounding box
     */
    else if (!rect_includespoint(&drag_init_rect, mevent->x, mevent->y))
    {    
        Window win;

        /* event coords are relative to widget-must translate to parent */
        XTranslateCoordinates(dpy, XtWindow(xy_widget), XtWindow(parent),
            mevent->x, mevent->y, &trans_x, &trans_y, &win);

        move_rect.x = trans_x - x_offset;
        move_rect.y = trans_y - y_offset;

        /* Ensure move outline is within the parent's rect */
        if (move_rect.x < 0)
            move_rect.x = 0;
        else if ((move_rect.x + (short)move_rect.width + 1) >= (short)parent_rect.width)
            move_rect.x = parent_rect.width - (move_rect.width + 1);

        if (move_rect.y < 0)
            move_rect.y = 0;
        else if ((move_rect.y + (short)move_rect.height + 1) >= (short)parent_rect.height)
            move_rect.y = parent_rect.height - (move_rect.height + 1);

        /* If cursor has moved since last event, erase previous outline
         * and render new one (using XOR function)
         */
        if (!rect_equal(&move_rect, &last_rect))
        {
            if (!rect_isnull(&last_rect))
                x_box_r(parent, &last_rect);
            x_box_r(parent, &move_rect);
            last_rect = move_rect;
        }
    }
    return OK;
}