rearranged includes, seperate redraw request areas.

svn path=/trunk/netsurf/; revision=12359
This commit is contained in:
Ole Loots 2011-05-09 22:10:02 +00:00
parent 2f40a85b67
commit 3276ce5db9
10 changed files with 262 additions and 186 deletions

View File

@ -87,7 +87,7 @@ struct s_browser * browser_create( struct gui_window * gw,
bw->scale = clone->scale;
else
bw->scale = 1;
bnew->redraw.areas_used = 0;
bnew->compwin = mt_WindCreate( &app, VSLIDE|HSLIDE, 1, 1, app.w, app.h);
bnew->compwin->w_u = 1;
bnew->compwin->h_u = 1;
@ -181,21 +181,10 @@ bool browser_attach_frame( struct gui_window * container, struct gui_window * fr
container->browser->compwin->w_max = 0;
container->browser->comp->flex = 0;
container->browser->comp->size = 300;
//container->browser->comp->bounds.max_height = 0;
//container->browser->comp->bounds.min_height = 0;
//WindClose( container->browser->compwin );
container->browser->comp->type = lt;
mt_CompAttach( &app, container->browser->comp, frame->browser->comp );
//win_comp_attach(&app, container->browser->compwin, frame->browser->comp);
browser_update_rects( container );
frame->browser->attached = true;
//container->browser->attached = true;
/*browser_update_rects( frame );
LGRECT brect;
browser_get_rect( frame, BR_CONTENT, &brect );
*/
frame->browser->attached = true;
}
/* find the root of an frame ( or just return gw if is already the root) */
@ -806,20 +795,17 @@ bool browser_redraw_required( struct gui_window * gw)
}
}
}
ret = ( (b->redraw.required && frames == 0) ||
b->scroll.required ||
b->caret.redraw );
ret = ( ((b->redraw.areas_used > 0) && frames == 0)
|| b->scroll.required
|| b->caret.redraw );
return( ret );
}
/* schedule a redraw of content */
/* coords are relative to the framebuffer */
/* the box is modified to fit the current viewport if it doesn't fit in */
void browser_schedule_redraw_rect(struct gui_window * gw, short x, short y, short w, short h)
{
int diff;
if( x < 0 ){
w += x;
x = 0;
@ -832,17 +818,32 @@ void browser_schedule_redraw_rect(struct gui_window * gw, short x, short y, shor
browser_schedule_redraw( gw, x, y, x+w, y+h );
}
/* schedule a redraw of content */
/* coords are relative to the framebuffer */
static inline bool bbox_intersect(BBOX * box1, BBOX * box2)
{
if (box2->x1 < box1->x0)
return false;
if (box2->y1 < box1->y0)
return false;
if (box2->x0 > box1->x1)
return false;
if (box2->y0 > box1->y1)
return false;
return true;
}
/*
schedule a redraw of content, coords are relative to the framebuffer
*/
void browser_schedule_redraw(struct gui_window * gw, short x0, short y0, short x1, short y1)
{
assert( gw != NULL );
CMP_BROWSER b = gw->browser;
int i;
LGRECT work;
/* TODO: add rectangle to list, instead of summarizing the rect.? */
/* otherwise it can result in large areas, altough it isnt needed. ( like 1 px in the upper left,
and 1px in bottom right corner )
*/
if( y1 < 0 || x1 < 0 )
return;
@ -853,53 +854,65 @@ void browser_schedule_redraw(struct gui_window * gw, short x0, short y0, short x
if( y0 > work.g_h )
return;
/* special handling of initial call: */
if( b->redraw.required == false ) {
b->redraw.required = true;
b->redraw.area.x0 = x0;
b->redraw.area.y0 = y0;
b->redraw.area.x1 = x1;
b->redraw.area.y1 = y1;
} else {
b->redraw.area.x0 = MIN(b->redraw.area.x0, x0);
b->redraw.area.y0 = MIN(b->redraw.area.y0, y0);
b->redraw.area.x1 = MAX(b->redraw.area.x1, x1);
b->redraw.area.y1 = MAX(b->redraw.area.y1, y1);
for( i=0; i<b->redraw.areas_used; i++) {
if( b->redraw.areas[i].x0 <= x0
&& b->redraw.areas[i].x1 >= x1
&& b->redraw.areas[i].y0 <= y0
&& b->redraw.areas[i].y1 >= y1 ){
/* the area is already queued for redraw */
return;
} else {
BBOX area;
area.x0 = x0;
area.y0 = y0;
area.x1 = x1;
area.y1 = y1;
if( bbox_intersect(&b->redraw.areas[i], &area ) ){
b->redraw.areas[i].x0 = MIN(b->redraw.areas[i].x0, x0);
b->redraw.areas[i].y0 = MIN(b->redraw.areas[i].y0, y0);
b->redraw.areas[i].x1 = MAX(b->redraw.areas[i].x1, x1);
b->redraw.areas[i].y1 = MAX(b->redraw.areas[i].y1, y1);
return;
}
}
}
if( b->redraw.areas_used < MAX_REDRW_SLOTS ) {
b->redraw.areas[b->redraw.areas_used].x0 = x0;
b->redraw.areas[b->redraw.areas_used].x1 = x1;
b->redraw.areas[b->redraw.areas_used].y0 = y0;
b->redraw.areas[b->redraw.areas_used].y1 = y1;
b->redraw.areas_used++;
} else {
/*
we are out of available slots, merge box with last slot
this is dumb... but also a very rare case.
*/
b->redraw.areas[MAX_REDRW_SLOTS-1].x0 = MIN(b->redraw.areas[i].x0, x0);
b->redraw.areas[MAX_REDRW_SLOTS-1].y0 = MIN(b->redraw.areas[i].y0, y0);
b->redraw.areas[MAX_REDRW_SLOTS-1].x1 = MAX(b->redraw.areas[i].x1, x1);
b->redraw.areas[MAX_REDRW_SLOTS-1].y1 = MAX(b->redraw.areas[i].y1, y1);
}
done:
return;
}
static void browser_redraw_content( struct gui_window * gw, int xoff, int yoff )
{
LGRECT work;
CMP_BROWSER b = gw->browser;
GRECT area;
struct rect clip;
LOG(("%s : %d,%d - %d,%d\n", b->bw->name, b->redraw.area.x0,
b->redraw.area.y0, b->redraw.area.x1, b->redraw.area.y1
));
area.g_x = b->redraw.area.x0;
area.g_y = b->redraw.area.y0;
area.g_w = b->redraw.area.x1 - b->redraw.area.x0;
area.g_h = b->redraw.area.y1 - b->redraw.area.y0;
current_redraw_browser = b->bw;
clip.x0 = b->redraw.area.x0;
clip.y0 = b->redraw.area.y0;
clip.x1 = b->redraw.area.x1;
clip.y1 = b->redraw.area.y1;
browser_window_redraw( b->bw, -b->scroll.current.x,
-b->scroll.current.y, &clip );
-b->scroll.current.y, &b->redraw.area );
current_redraw_browser = NULL;
/* reset redraw area */
b->redraw.area.x0 = INT_MAX;
b->redraw.area.y0 = INT_MAX;
b->redraw.area.x1 = INT_MIN;
b->redraw.area.y1 = INT_MIN;
}
@ -961,41 +974,55 @@ void browser_redraw( struct gui_window * gw )
b->scroll.required = false;
}
if (b->redraw.required == true && b->bw->current_content != NULL ) {
if ((b->redraw.areas_used > 0) && b->bw->current_content != NULL ) {
if( (plotter->flags & PLOT_FLAG_OFFSCREEN) == 0 ) {
int i;
GRECT area;
GRECT fbwork;
BBOX cliporg;
todo[0] = bwrect.g_x;
todo[1] = bwrect.g_y;
todo[2] = todo[0] + bwrect.g_w-1;
todo[3] = todo[1] + bwrect.g_h-1;
vs_clip(plotter->vdi_handle, 1, (short*)&todo[0]);
area.g_x = b->redraw.area.x0;
area.g_y = b->redraw.area.y0;
area.g_w = b->redraw.area.x1 - b->redraw.area.x0;
area.g_h = b->redraw.area.y1 - b->redraw.area.y0;
if( wind_get(gw->root->handle->handle, WF_FIRSTXYWH,
&todo[0], &todo[1], &todo[2], &todo[3] )!=0 ) {
while (todo[2] && todo[3]) {
/* convert screen to framebuffer coords: */
todo[0] -= bwrect.g_x;
todo[1] -= bwrect.g_y;
if( todo[0] < 0 ){
todo[2] = todo[2] + todo[0];
todo[0] = 0;
fbwork.g_x = todo[0] - bwrect.g_x;
fbwork.g_y = todo[1] - bwrect.g_y;
if( fbwork.g_x < 0 ){
fbwork.g_w = todo[2] + todo[0];
fbwork.g_x = 0;
} else {
fbwork.g_w = todo[2];
}
if( todo[1] < 0 ){
todo[3] = todo[3] + todo[1];
todo[1] = 0;
if( fbwork.g_y < 0 ){
fbwork.g_h = todo[3] + todo[1];
fbwork.g_y = 0;
} else {
fbwork.g_h = todo[3];
}
if (rc_intersect((GRECT *)&area,(GRECT *)&todo)) {
b->redraw.area.x0 = todo[0];
b->redraw.area.y0 = todo[1];
b->redraw.area.x1 = b->redraw.area.x0 + todo[2];
b->redraw.area.y1 = b->redraw.area.y0 + todo[3];
browser_redraw_content( gw, 0, 0 );
/* walk the redraw requests: */
for( i=0; i<b->redraw.areas_used; i++ ){
area.g_x = b->redraw.areas[i].x0;
area.g_y = b->redraw.areas[i].y0;
area.g_w = b->redraw.areas[i].x1 - b->redraw.areas[i].x0;
area.g_h = b->redraw.areas[i].y1 - b->redraw.areas[i].y0;
if (rc_intersect((GRECT *)&fbwork,(GRECT *)&area)) {
b->redraw.area.x0 = area.g_x; //todo[0];
b->redraw.area.y0 = area.g_y; //todo[1];
b->redraw.area.x1 = area.g_x + area.g_w; //todo[0] + todo[2];
b->redraw.area.y1 = area.g_y + area.g_h; //todo[1] + todo[3];
browser_redraw_content( gw, 0, 0 );
} else {
/*
the area should be kept scheduled for later redraw, but because this
is onscreen plotter, it doesn't make much sense anyway...
*/
}
}
if (wind_get(gw->root->handle->handle, WF_NEXTXYWH,
&todo[0], &todo[1], &todo[2], &todo[3])==0) {
@ -1007,7 +1034,7 @@ void browser_redraw( struct gui_window * gw )
} else {
/* its save to do a complete redraw :) */
}
b->redraw.required = false;
b->redraw.areas_used = 0;
}
if( b->caret.redraw == true && b->bw->current_content != NULL ) {
GRECT area;

View File

@ -24,7 +24,19 @@
which cosnist mainly of an WinDom COMPONENT.
*/
#define BROWSER_SCROLL_SVAL 64 /* The small scroll inc. value */
/*
BROWSER_SCROLL_SVAL
The small scroll inc. value (used by scroll-wheel, arrow click):
*/
#define BROWSER_SCROLL_SVAL 64
/*
MAX_REDRW_SLOTS
This is the number of redraw requests that an browser window can queue.
If a redraw is scheduled and all slots are used, the rectangle will
be merged to one of the existing slots.
*/
#define MAX_REDRW_SLOTS 32
enum browser_type
{
@ -42,6 +54,56 @@ enum browser_rect
BR_VSLIDER = 4
};
/*
This struct contains info of current browser viewport scroll
and the scroll which is requested. If a scroll is requested,
the field required is set to true.
*/
struct s_scroll_info
{
POINT requested;
POINT current;
bool required;
};
/*
This struct holds information of the cursor within the browser
viewport.
*/
struct s_caret
{
GRECT requested;
GRECT current;
bool redraw;
};
/*
This struct holds scheduled redraw requests.
*/
struct s_browser_redrw_info
{
BBOX areas[MAX_REDRW_SLOTS];
short areas_used;
BBOX area; /* used for clipping of content redraw */
};
/*
This is the actual browser widget, containings GUI elements and
the current state of the browser widget.
*/
struct s_browser
{
int type;
COMPONENT * comp;
WINDOW * compwin;
struct browser_window * bw;
struct s_scroll_info scroll;
struct s_browser_redrw_info redraw;
struct s_caret caret;
bool attached;
};
struct s_browser * browser_create( struct gui_window * gw, struct browser_window * clone, struct browser_window *bw, enum browser_type, int lt, int w, int flex );
bool browser_destroy( struct s_browser * b );
void browser_get_rect( struct gui_window * gw, enum browser_rect type, LGRECT * out);
@ -53,6 +115,18 @@ bool browser_attach_frame( struct gui_window * container, struct gui_window * fr
struct gui_window * browser_find_root( struct gui_window * gw );
static void browser_process_scroll( struct gui_window * gw, LGRECT bwrect );
bool browser_redraw_required( struct gui_window * gw);
/*
This queues an redraw to one of the slots.
The following strategy is used:
1. It checks if the rectangle to be scheduled is within one of the
already queued bboxes. If yes, it will return.
2. It checks for an intersection, and it will merge the rectangle to
already queued rectangle where it fits best.
3. it tries to put the rectangle into one available slot.
4. if no slot is available, it will search for the nearest rectangle
and summarize it within that slot.
*/
void browser_redraw_caret( struct gui_window * gw, GRECT * area );
static void browser_redraw_content( struct gui_window * gw, int xoff, int yoff );

View File

@ -68,28 +68,6 @@ struct s_gem_cursors {
MFORM_EX arrow;
} gem_cursors;
/* maybe its better to have an linked
list of redraw areas, so that there
is no such an overhead when 2 (or more)
SMALL rectangles far away from each other
need an redraw!
Currently these rects get summarized into
one big redraw area!
*/
struct s_browser_redrw_info
{
BBOX area; /* this is an box which describes the area to redraw */
/* from netsurfs point of view */
bool required;
};
struct s_scroll_info
{
POINT requested;
POINT current;
bool required;
};
enum focus_element_type {
WIDGET_NONE=0,
URL_WIDGET,
@ -113,101 +91,28 @@ struct s_gui_input_state {
} prev_inp_state;
*/
#define TB_BUTTON_WIDTH 32
#define TB_BUTTON_HEIGHT 21 /* includes 1px 3d effect */
#define TOOLBAR_HEIGHT 25
#define URLBOX_HEIGHT 21
#define STATUSBAR_HEIGHT 16
#define STATUSBAR_MAX_SLEN 255
#define MOVER_WH 16
#define THROBBER_WIDTH 32
/* defines for data attached to components: */
#define CDT_OBJECT 0x004f424aUL
#define CDT_OWNER 0x03UL
#define CDT_ICON 0x04UL
#define CDT_ICON_TYPE 0x05UL
/*
URL Widget Block size: size of memory block to allocated
when input takes more memory than currently allocated:
*/
#define URL_WIDGET_BSIZE 64
#define URL_WIDGET_MAX_MEM 60000
struct s_url_widget
{
short selection_len; /* len & direction of selection */
short caret_pos; /* cursor pos */
short char_size; /* size of one character (width & hight) */
short scrollx; /* current scroll position */
bool redraw; /* widget is only redrawn when this flag is set */
char * text; /* dynamicall allocated URL string*/
unsigned short allocated;
unsigned short used; /* memory used by URL (strlen + 1) */
COMPONENT * comp;
};
struct s_throbber_widget
{
COMPONENT * comp;
short index;
short max_index;
bool running;
};
struct gui_window;
struct s_tb_button
{
short rsc_id;
void (*cb_click)(struct gui_window * gw);
COMPONENT * comp;
};
struct s_toolbar
{
COMPONENT * comp;
struct gui_window * owner;
struct s_url_widget url;
struct s_throbber_widget throbber;
GRECT btdim; /* size & location of buttons */
struct s_tb_button * buttons;
int btcnt;
/* buttons are defined in toolbar.c */
};
struct s_statusbar
{
COMPONENT * comp;
char text[STATUSBAR_MAX_SLEN+1];
size_t textlen;
bool attached;
};
struct s_caret
{
GRECT requested;
GRECT current;
bool redraw;
};
struct s_browser
{
int type;
COMPONENT * comp;
WINDOW * compwin;
struct browser_window * bw;
struct s_scroll_info scroll;
struct s_browser_redrw_info redraw;
struct s_caret caret;
bool attached;
};
struct s_browser;
struct s_statusbar;
struct s_toolbar;
typedef struct s_toolbar * CMP_TOOLBAR;
typedef struct s_statusbar * CMP_STATUSBAR;
typedef struct s_browser * CMP_BROWSER;
/*
This is the "main" window. It can consist of several components
and also holds information shared by several frames within
the window. Each frame, no matter how deep nested,
knows about it's root (GEM window).
*/
struct s_gui_win_root
{
WINDOW * handle;
@ -222,6 +127,13 @@ struct s_gui_win_root
GRECT loc; /* current size of window on screen */
};
/*
This is the part of the gui which is known by netsurf core.
You must implement it. Altough, you are free how to do it.
Each of the browser "viewports" managed by netsurf are bound
to this structure. gui_window does not mean that it is an
comple window - also frames own an gui_window.
*/
struct gui_window {
struct s_gui_win_root * root;
CMP_BROWSER browser;
@ -233,5 +145,4 @@ extern struct gui_window *window_list;
#define MOUSE_IS_DRAGGING() (mouse_hold_start[0] || mouse_hold_start[1])
#endif

View File

@ -33,6 +33,7 @@
#include "content/fetch.h"
#include "atari/gui.h"
#include "atari/toolbar.h"
#include "atari/browser.h"
#include "atari/misc.h"
extern void * h_gem_rsrc;

View File

@ -116,8 +116,6 @@ char * gemdos_realpath(const char * path, char * rpath)
char * work_ptr;
size_t l;
printf("gdos rpath in: %s\n", path);
if( rpath == NULL ){
return( NULL );
}
@ -125,6 +123,7 @@ char * gemdos_realpath(const char * path, char * rpath)
return( realpath(path, rpath) );
}
LOG(("gdos rpath in: %s\n", path));
memset( rpath, 0, PATH_MAX );
/* first, absolutize relative path: */
@ -186,7 +185,7 @@ char * gemdos_realpath(const char * path, char * rpath)
strcpy( rpath, work_ptr );
}
l = strlen( rpath );
printf("gdos rpath out: %s\n", rpath);
LOG(("gdos rpath out: %s\n", rpath));
return( rpath );
}

View File

@ -14,6 +14,7 @@
#include "utils/messages.h"
#include "atari/gui.h"
#include "atari/misc.h"
#include "atari/browser.h"
#include "atari/search.h"
#include "atari/res/netsurf.rsh"

View File

@ -58,7 +58,6 @@ void __CDECL evnt_sb_redraw( COMPONENT *c, long buff[8] )
if( sb == NULL )
return;
assert( sb->attached != false );
if( sb->attached == false )
return;

View File

@ -19,6 +19,19 @@
#ifndef NS_ATARI_STATUSBAR
#define NS_ATARI_STATUSBAR
#define STATUSBAR_HEIGHT 16
#define STATUSBAR_MAX_SLEN 255
#define MOVER_WH 16
struct s_statusbar
{
COMPONENT * comp;
char text[STATUSBAR_MAX_SLEN+1];
size_t textlen;
bool attached;
};
CMP_STATUSBAR sb_create( struct gui_window * gw );
void sb_destroy( CMP_STATUSBAR s );
void sb_set_text( CMP_STATUSBAR sb , char * text );

View File

@ -40,6 +40,7 @@
#include "atari/gui.h"
#include "atari/toolbar.h"
#include "atari/browser_win.h"
#include "atari/browser.h"
#include "atari/clipboard.h"
#include "atari/misc.h"
#include "atari/global_evnt.h"

View File

@ -19,10 +19,60 @@
#ifndef NS_ATARI_TOOLBAR_H
#define NS_ATARI_TOOLBAR_H
#define TB_BUTTON_WIDTH 32
#define TB_BUTTON_HEIGHT 21 /* includes 1px 3d effect */
#define TOOLBAR_HEIGHT 25
#define THROBBER_WIDTH 32
#define THROBBER_MIN_INDEX 1
#define THROBBER_MAX_INDEX 12
#define THROBBER_INACTIVE_INDEX 13
#define URLBOX_HEIGHT 21
/*
URL Widget Block size: size of memory block to allocated
when input takes more memory than currently allocated:
*/
#define URL_WIDGET_BSIZE 64
#define URL_WIDGET_MAX_MEM 60000
struct s_tb_button
{
short rsc_id;
void (*cb_click)(struct gui_window * gw);
COMPONENT * comp;
};
struct s_url_widget
{
short selection_len; /* len & direction of selection */
short caret_pos; /* cursor pos */
short char_size; /* size of one character (width & hight) */
short scrollx; /* current scroll position */
bool redraw; /* widget is only redrawn when this flag is set */
char * text; /* dynamicall allocated URL string */
unsigned short allocated;
unsigned short used; /* memory used by URL (strlen + 1) */
COMPONENT * comp;
};
struct s_throbber_widget
{
COMPONENT * comp;
short index;
short max_index;
bool running;
};
struct s_toolbar
{
COMPONENT * comp;
struct gui_window * owner;
struct s_url_widget url;
struct s_throbber_widget throbber;
GRECT btdim; /* size & location of buttons */
struct s_tb_button * buttons;
int btcnt;
};
CMP_TOOLBAR tb_create( struct gui_window * gw );
void tb_destroy( CMP_TOOLBAR tb );