static int gtextfield_timer(GGadget *g, GEvent *event) {
    GTextField *gt = (GTextField *) g;

    if ( !g->takes_input || (g->state!=gs_enabled && g->state!=gs_active && g->state!=gs_focused ))
return(false);
    if ( gt->cursor == event->u.timer.timer ) {
	if ( gt->cursor_on ) {
	    gt_draw_cursor(g->base, gt);
	    gt->cursor_on = false;
	} else {
	    gt->cursor_on = true;
	    gt_draw_cursor(g->base, gt);
	}
return( true );
    }
    if ( gt->numeric_scroll == event->u.timer.timer ) {
	GTextFieldIncrement(gt,gt->incr_down?-1:1);
return( true );
    }
    if ( gt->pressed == event->u.timer.timer ) {
	GEvent e;
	GDrawSetFont(g->base,gt->font);
	GDrawGetPointerPosition(g->base,&e);
	if ( (e.u.mouse.x<g->r.x && gt->xoff_left>0 ) ||
		(gt->multi_line && e.u.mouse.y<g->r.y && gt->loff_top>0 ) ||
		( e.u.mouse.x >= g->r.x + g->r.width &&
			gt->xmax-gt->xoff_left>g->inner.width ) ||
		( e.u.mouse.y >= g->r.y + g->r.height &&
			gt->lcnt-gt->loff_top > g->inner.height/gt->fh )) {
	    int l = gt->loff_top + (e.u.mouse.y-g->inner.y)/gt->fh;
	    int xpos; unichar_t *end;

	    if ( e.u.mouse.y<g->r.y && gt->loff_top>0 )
		l = --gt->loff_top;
	    else if ( e.u.mouse.y >= g->r.y + g->r.height &&
			    gt->lcnt-gt->loff_top > g->inner.height/gt->fh ) {
		++gt->loff_top;
		l = gt->loff_top + g->inner.width/gt->fh;
	    } else if ( l<gt->loff_top )
		l = gt->loff_top; 
	    else if ( l>=gt->loff_top + g->inner.height/gt->fh ) 
		l = gt->loff_top + g->inner.height/gt->fh-1;
	    if ( l>=gt->lcnt ) l = gt->lcnt-1;

	    xpos = e.u.mouse.x+gt->xoff_left;
	    if ( e.u.mouse.x<g->r.x && gt->xoff_left>0 ) {
		gt->xoff_left -= gt->nw;
		xpos = g->inner.x + gt->xoff_left;
	    } else if ( e.u.mouse.x >= g->r.x + g->r.width &&
			    gt->xmax-gt->xoff_left>g->inner.width ) {
		gt->xoff_left += gt->nw;
		xpos = g->inner.x + gt->xoff_left + g->inner.width;
	    }

	    end = GTextFieldGetPtFromPos(gt,l,xpos);
	    if ( end-gt->text > gt->sel_base ) {
		gt->sel_start = gt->sel_base;
		gt->sel_end = end-gt->text;
	    } else {
		gt->sel_start = end-gt->text;
		gt->sel_end = gt->sel_base;
	    }
	    _ggadget_redraw(g);
	    if ( gt->vsb!=NULL )
		GScrollBarSetPos(&gt->vsb->g,gt->loff_top);
	    if ( gt->hsb!=NULL )
		GScrollBarSetPos(&gt->hsb->g,gt->xoff_left);
	}
return( true );
    }
return( false );
}
static int gtextfield_timer(GGadget *g, GEvent *event) {
    GTextField *gt = (GTextField *) g;

    if ( !g->takes_input || (g->state!=gs_enabled && g->state!=gs_active && g->state!=gs_focused ))
return(false);
    if ( gt->cursor == event->u.timer.timer ) {
	if ( gt->cursor_on ) {
	    gt_draw_cursor(g->base, gt);
	    gt->cursor_on = false;
	} else {
	    gt->cursor_on = true;
	    gt_draw_cursor(g->base, gt);
	}
return( true );
    }
    if ( gt->numeric_scroll == event->u.timer.timer ) {
	GTextFieldIncrement(gt,gt->incr_down?-1:1);
return( true );
    }
    if ( gt->pressed == event->u.timer.timer ) {
	GEvent e;
	GDrawSetFont(g->base,gt->font);
	GDrawGetPointerPosition(g->base,&e);
	if ( (e.u.mouse.x<g->r.x && gt->xoff_left>0 ) ||
		(gt->multi_line && e.u.mouse.y<g->r.y && gt->loff_top>0 ) ||
		( e.u.mouse.x >= g->r.x + g->r.width &&
			gt->xmax-gt->xoff_left>g->inner.width ) ||
		( e.u.mouse.y >= g->r.y + g->r.height &&
			gt->lcnt-gt->loff_top > g->inner.height/gt->fh )) {
	    int l = gt->loff_top + (e.u.mouse.y-g->inner.y)/gt->fh;
	    int xpos; unichar_t *end;

	    if ( e.u.mouse.y<g->r.y && gt->loff_top>0 )
		l = --gt->loff_top;
	    else if ( e.u.mouse.y >= g->r.y + g->r.height &&
			    gt->lcnt-gt->loff_top > g->inner.height/gt->fh ) {
		++gt->loff_top;
		l = gt->loff_top + g->inner.width/gt->fh;
	    } else if ( l<gt->loff_top )
		l = gt->loff_top; 
	    else if ( l>=gt->loff_top + g->inner.height/gt->fh ) 
		l = gt->loff_top + g->inner.height/gt->fh-1;
	    if ( l>=gt->lcnt ) l = gt->lcnt-1;

	    xpos = e.u.mouse.x+gt->xoff_left;
	    if ( e.u.mouse.x<g->r.x && gt->xoff_left>0 ) {
		gt->xoff_left -= gt->nw;
		xpos = g->inner.x + gt->xoff_left;
	    } else if ( e.u.mouse.x >= g->r.x + g->r.width &&
			    gt->xmax-gt->xoff_left>g->inner.width ) {
		gt->xoff_left += gt->nw;
		xpos = g->inner.x + gt->xoff_left + g->inner.width;
	    }

	    end = GTextFieldGetPtFromPos(gt,l,xpos);
	    if ( end-gt->text > gt->sel_base ) {
		gt->sel_start = gt->sel_base;
		gt->sel_end = end-gt->text;
	    } else {
		gt->sel_start = end-gt->text;
		gt->sel_end = gt->sel_base;
	    }
	    _ggadget_redraw(g);
	    if ( gt->vsb!=NULL )
		GScrollBarSetPos(&gt->vsb->g,gt->loff_top);
	    if ( gt->hsb!=NULL )
		GScrollBarSetPos(&gt->hsb->g,gt->xoff_left);
	}
return( true );
    }
return( false );
}