From 999410adc818e9bc9e566580b38954720d7dad55 Mon Sep 17 00:00:00 2001 From: Ole Loots Date: Mon, 28 Nov 2011 23:23:28 +0000 Subject: I'm actually trying to simplify the frontend code, changes: - Optimized browser window caret, uses back-buffer now. ( So no content redraw is scheduled by the frontend just for a caret move ) - Fixed a double redraw issue when the browser reformat is pending and the AES also sends an redraw request because of the resize. - Started to use netsurfs textarea instead of a custom implementation ( to reduce code size ). svn path=/trunk/netsurf/; revision=13191 --- atari/Makefile.target | 1 + atari/browser.c | 467 +++++++++++++++++---------------------- atari/browser.h | 51 ++--- atari/browser_win.c | 99 +++++---- atari/browser_win.h | 19 -- atari/ctxmenu.c | 18 +- atari/encoding.c | 50 +++++ atari/encoding.h | 19 ++ atari/font.c | 60 +---- atari/font.h | 12 +- atari/gui.c | 60 +++-- atari/history.c | 1 + atari/plot.h | 3 +- atari/redrawslots.c | 79 +++++++ atari/redrawslots.h | 27 +++ atari/toolbar.c | 594 +++++++++++++++++++++----------------------------- atari/toolbar.h | 50 +++-- atari/treeview.c | 8 +- 18 files changed, 779 insertions(+), 839 deletions(-) create mode 100644 atari/encoding.c create mode 100644 atari/encoding.h create mode 100644 atari/redrawslots.c create mode 100644 atari/redrawslots.h (limited to 'atari') diff --git a/atari/Makefile.target b/atari/Makefile.target index a4f672f8f..019febd4f 100644 --- a/atari/Makefile.target +++ b/atari/Makefile.target @@ -38,6 +38,7 @@ S_ATARI := gui.c findfile.c filetype.c misc.c bitmap.c schedule.c \ search.c font.c \ plot.c plot/plotter.c plot/plotter_vdi.c plot/eddi.s \ plot/font_vdi.c plot/font_freetype.c plot/font_internal.c \ + redrawslots.c encoding.c \ browser_win.c toolbar.c statusbar.c browser.c \ global_evnt.c osspec.c dragdrop.c system_colour.c \ ctxmenu.c diff --git a/atari/browser.c b/atari/browser.c index 46acac108..9ed5aa3d1 100755 --- a/atari/browser.c +++ b/atari/browser.c @@ -49,12 +49,13 @@ #include "atari/browser_win.h" #include "atari/misc.h" #include "atari/global_evnt.h" -#include "atari/res/netsurf.rsh" +#include "atari/res/netsurf.rsh" +#include "atari/redrawslots.h" #include "atari/browser.h" #include "atari/plot/plotter.h" #include "atari/plot.h" -#include "atari/font.h" -#include "atari/ctxmenu.h" +#include "atari/encoding.h" +#include "atari/ctxmenu.h" #include "cflib.h" extern browser_mouse_state bmstate; @@ -63,13 +64,20 @@ extern int mouse_hold_start[3]; extern GEM_PLOTTER plotter; extern struct gui_window *input_window; extern short last_drag_x; -extern short last_drag_y; - - - -static void __CDECL browser_evnt_wdestroy( WINDOW * c, short buff[8], void * data); -COMPONENT *comp_widget_create( APPvar *app, WINDOW *win, int size, int flex ); +extern short last_drag_y; +static void browser_process_scroll( struct gui_window * gw, LGRECT bwrect ); +static void browser_redraw_content( struct gui_window * gw, int xoff, int yoff, + struct rect * area ); +static void __CDECL browser_evnt_resize( COMPONENT * c, long buff[8], + void * data); +static void __CDECL browser_evnt_destroy( COMPONENT * c, long buff[8], + void * data); +static void __CDECL browser_evnt_redraw( COMPONENT * c, long buff[8], + void * data); +static void __CDECL browser_evnt_mbutton( COMPONENT * c, long buff[8], + void * data); + /* Create an browser component. @@ -97,8 +105,8 @@ struct s_browser * browser_create if(clone) bw->scale = clone->scale; else - bw->scale = 1; - bnew->redraw.areas_used = 0; + bw->scale = 1; + redraw_slots_init( &bnew->redraw, MAX_REDRW_SLOTS ); bnew->comp = (COMPONENT*)mt_CompCreate(&app, CLT_HORIZONTAL, 100, 1); if( bnew->comp == NULL ) { free(bnew); @@ -114,6 +122,9 @@ struct s_browser * browser_create ); mt_CompEvntDataAttach( &app, bnew->comp, WM_DESTROY, browser_evnt_destroy, (void*)bnew + ); + mt_CompEvntDataAttach( &app, bnew->comp, WM_SIZED, + browser_evnt_resize, (void*)gw ); /* Set the gui_window owner. */ @@ -124,6 +135,7 @@ struct s_browser * browser_create bnew->scroll.requested.x = 0; bnew->scroll.current.x = 0; bnew->scroll.current.y = 0; + bnew->reformat_pending = false; } return( bnew ); @@ -170,12 +182,12 @@ void browser_get_rect( struct gui_window * gw, enum browser_rect type, LGRECT * void browser_update_rects(struct gui_window * gw ) { short buff[8]; - LGRECT cmprect; + LGRECT cmprect; mt_WindGetGrect( &app, gw->root->handle, WF_CURRXYWH, (GRECT*)&buff[4]); buff[0] = CM_REFLOW; buff[1] = _AESapid; buff[2] = 0; - EvntExec(gw->root->handle, buff); + EvntExec(gw->root->handle, buff); } void browser_set_content_size(struct gui_window * gw, int w, int h) @@ -194,6 +206,13 @@ void browser_set_content_size(struct gui_window * gw, int w, int h) /* force update of scrollbars: */ b->scroll.required = true; } +} + +static void __CDECL browser_evnt_resize( COMPONENT * c, long buff[8], void * data) +{ + /* Just a dummy to prevent second redraw (already handled within browser_win)*/ + printf("browser evnt resize"); + return; } static void __CDECL browser_evnt_destroy( COMPONENT * c, long buff[8], void * data) @@ -419,7 +438,7 @@ static void browser_process_scroll( struct gui_window * gw, LGRECT bwrect ) dst.g_h = src.g_h; plotter->copy_rect( plotter, src, dst ); b->scroll.current.y += b->scroll.requested.y; - browser_schedule_redraw( gw, 0, 0, bwrect.g_w, h ) ; + browser_schedule_redraw( gw, 0, 0, bwrect.g_w, h ); } if( b->scroll.requested.y > 0 ) { @@ -467,7 +486,10 @@ static void browser_process_scroll( struct gui_window * gw, LGRECT bwrect ) browser_schedule_redraw( gw, bwrect.g_w - w, 0, bwrect.g_w, bwrect.g_h ); } b->scroll.requested.y = 0; - b->scroll.requested.x = 0; + b->scroll.requested.x = 0; + if( b->caret.requested.g_w > 0 ){ + b->caret.redraw = true; + } gw->root->handle->xpos = b->scroll.current.x; gw->root->handle->ypos = b->scroll.current.y; @@ -477,7 +499,7 @@ static void browser_process_scroll( struct gui_window * gw, LGRECT bwrect ) /* Report keypress to browser component. - The browser component doesn't list for keyinput by itself. + The browser component doesn't listen for keyinput by itself. parameter: - gui_window ( compocnent owner ). - unsigned short nkc ( CFLIB normalised key code ) @@ -487,154 +509,58 @@ bool browser_input( struct gui_window * gw, unsigned short nkc ) LGRECT work; bool r = false; unsigned char ascii = (nkc & 0xFF); - nkc = (nkc & (NKF_CTRL|NKF_SHIFT|0xFF)); - browser_get_rect(gw, BR_CONTENT, &work); - - if( (nkc & NKF_CTRL) != 0 ) { - switch ( ascii ) { - case 'A': - r = browser_window_key_press(gw->browser->bw, KEY_SELECT_ALL); - break; - - case 'C': - r = browser_window_key_press(gw->browser->bw, KEY_COPY_SELECTION); - break; - - case 'X': - r = browser_window_key_press(gw->browser->bw, KEY_CUT_SELECTION); - break; - - case 'V': - r = browser_window_key_press(gw->browser->bw, KEY_PASTE); - break; - - default: - break; - } - } - if( (nkc & NKF_SHIFT) != 0 ) { - switch( ascii ) { - - case NK_TAB: - r = browser_window_key_press(gw->browser->bw, KEY_SHIFT_TAB); - break; - - case NK_LEFT: - if( browser_window_key_press(gw->browser->bw, KEY_LINE_START) == false) { - browser_scroll( gw, WA_LFPAGE, work.g_w, false ); - r = true; - } - break; - - case NK_RIGHT: - if( browser_window_key_press(gw->browser->bw, KEY_LINE_END) == false) { - browser_scroll( gw, WA_RTPAGE, work.g_w, false ); - r = true; - } - break; - - case NK_UP: - if ( browser_window_key_press(gw->browser->bw, KEY_PAGE_UP) ==false ){ - browser_scroll( gw, WA_UPPAGE, work.g_h, false ); - r = true; - } - break; - - case NK_DOWN: - if (browser_window_key_press(gw->browser->bw, KEY_PAGE_DOWN) == false) { - browser_scroll( gw, WA_DNPAGE, work.g_h, false ); - r = true; - } - break; - - default: - break; - } - } - if( (nkc & (NKF_SHIFT|NKF_CTRL) ) == 0 ) { - switch( ascii ) { - case NK_BS: - r = browser_window_key_press(gw->browser->bw, KEY_DELETE_LEFT); - break; - - case NK_DEL: - r = browser_window_key_press(gw->browser->bw, KEY_DELETE_RIGHT); - break; - - case NK_TAB: - r = browser_window_key_press(gw->browser->bw, KEY_TAB); - break; - - - case NK_ENTER: - r = browser_window_key_press(gw->browser->bw, KEY_NL); - break; - - case NK_RET: - r = browser_window_key_press(gw->browser->bw, KEY_CR); - break; - - case NK_ESC: - r = browser_window_key_press(gw->browser->bw, KEY_ESCAPE); - break; - - case NK_CLRHOME: - r = browser_window_key_press(gw->browser->bw, KEY_TEXT_START); - break; - - case NK_RIGHT: - if (browser_window_key_press(gw->browser->bw, KEY_RIGHT) == false){ - browser_scroll( gw, WA_RTLINE, 16, false ); - r = true; - } - break; - - case NK_LEFT: - if (browser_window_key_press(gw->browser->bw, KEY_LEFT) == false) { - browser_scroll( gw, WA_LFLINE, 16, false ); - r = true; - } - break; - - case NK_UP: - if (browser_window_key_press(gw->browser->bw, KEY_UP) == false) { - browser_scroll( gw, WA_UPLINE, 16, false); - r = true; - } - break; - - case NK_DOWN: - if (browser_window_key_press(gw->browser->bw, KEY_DOWN) == false) { - browser_scroll( gw, WA_DNLINE, 16, false); - r = true; - } - break; - - case NK_M_PGUP: - if ( browser_window_key_press(gw->browser->bw, KEY_PAGE_UP) ==false ) { - browser_scroll( gw, WA_UPPAGE, work.g_h, false ); - r = true; - } - break; - - case NK_M_PGDOWN: - if (browser_window_key_press(gw->browser->bw, KEY_PAGE_DOWN) == false) { - browser_scroll( gw, WA_DNPAGE, work.g_h, false ); - r = true; - } - break; - - default: - break; - } - } - - if( r == false && ( (nkc & NKF_CTRL)==0) ) { + long ucs4; + long ik = nkc_to_input_key( nkc, &ucs4 ); + + // pass event to specific control? + + if( ik == 0 ){ if (ascii >= 9 ) { - int ucs4 = atari_to_ucs4(ascii); r = browser_window_key_press(gw->browser->bw, ucs4 ); - } - } + } + } else { + r = browser_window_key_press(gw->browser->bw, ik ); + if( r == false ){ + browser_get_rect(gw, BR_CONTENT, &work); + switch( ik ){ + case KEY_LINE_START: + browser_scroll( gw, WA_LFPAGE, work.g_w, false ); + break; + + case KEY_LINE_END: + browser_scroll( gw, WA_RTPAGE, work.g_w, false ); + break; + + case KEY_PAGE_UP: + browser_scroll( gw, WA_UPPAGE, work.g_h, false ); + break; + + case KEY_PAGE_DOWN: + browser_scroll( gw, WA_DNPAGE, work.g_h, false ); + break; + + case KEY_RIGHT: + browser_scroll( gw, WA_RTLINE, 16, false ); + break; + + case KEY_LEFT: + browser_scroll( gw, WA_LFLINE, 16, false ); + break; + + case KEY_UP: + browser_scroll( gw, WA_UPLINE, 16, false); + break; + + case KEY_DOWN: + browser_scroll( gw, WA_DNLINE, 16, false); + break; + + default: + break; + } + } + } + return( r ); } @@ -645,11 +571,15 @@ bool browser_redraw_required( struct gui_window * gw) CMP_BROWSER b = gw->browser; if( b->bw->current_content == NULL ) - return ( false ); + return ( false ); + + /* disable redraws when the browser awaits WM_REDRAW caused by resize */ + if( b->reformat_pending ) + return( false ); ret = ( ((b->redraw.areas_used > 0) ) || b->scroll.required - || b->caret.redraw ); + || b->caret.redraw); return( ret ); } @@ -670,22 +600,6 @@ void browser_schedule_redraw_rect(struct gui_window * gw, short x, short y, shor browser_schedule_redraw( gw, x, y, x+w, y+h ); } -static inline bool rect_intersect( struct rect * box1, struct rect * 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 @@ -707,50 +621,13 @@ void browser_schedule_redraw(struct gui_window * gw, short x0, short y0, short x if( y0 > work.g_h ) return; - area.x0 = x0; - area.y0 = y0; - area.x1 = x1; - area.y1 = y1; - - for( i=0; iredraw.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 { - if( rect_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; - } - } - } + redraw_slot_schedule( &b->redraw, x0, y0, x1, y1 ); - 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 ) +static void browser_redraw_content( struct gui_window * gw, int xoff, int yoff, + struct rect * area ) { LGRECT work; CMP_BROWSER b = gw->browser; @@ -760,44 +637,104 @@ static void browser_redraw_content( struct gui_window * gw, int xoff, int yoff ) .plot = &atari_plotters }; - 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 + LOG(("%s : %d,%d - %d,%d\n", b->bw->name, area->x0, + area->y0, area->x1, area->y1 )); browser_window_redraw( b->bw, -b->scroll.current.x, - -b->scroll.current.y, &b->redraw.area, &ctx ); + -b->scroll.current.y, area, &ctx ); } - - -void browser_redraw_caret( struct gui_window * gw, GRECT * area ) + +/* + area: the browser canvas +*/ +void browser_restore_caret_background( struct gui_window * gw, LGRECT * area) +{ + CMP_BROWSER b = gw->browser; + LGRECT rect; + if( area == NULL ){ + browser_get_rect( gw, BR_CONTENT, &rect ); + area = ▭ + } + /* This call restores the background and releases the memory: */ + // TODO: only release memory/clear flag when the caret is not clipped. + // TODO: apply clipping. + w_put_bkgr( &app, + area->g_x-b->scroll.current.x+b->caret.current.g_x, + area->g_y-b->scroll.current.y+b->caret.current.g_y, + gw->browser->caret.current.g_w, + gw->browser->caret.current.g_h, + &gw->browser->caret.background + ); + gw->browser->caret.background.fd_addr = NULL; +} + +/* + area: the browser canvas +*/ +void browser_redraw_caret( struct gui_window * gw, LGRECT * area ) { - GRECT caret; - struct s_browser * b = gw->browser; - if( b->caret.redraw == true ){ + // TODO: only redraw caret when window is topped. + if( gw->browser->caret.redraw && gw->browser->caret.requested.g_w > 0 ){ + LGRECT caret; + struct s_browser * b = gw->browser; struct rect old_clip; - struct rect clip; + struct rect clip; + + if( b->caret.current.g_w > 0 && b->caret.background.fd_addr != NULL ){ + browser_restore_caret_background( gw, area ); + } caret = b->caret.requested; - caret.g_x -= gw->browser->scroll.current.x; - caret.g_y -= gw->browser->scroll.current.y; - clip.x0 = caret.g_x - 1; - clip.y0 = caret.g_y - 1; - clip.x1 = caret.g_x + caret.g_w + 1; - clip.y1 = caret.g_y + caret.g_h + 1; + caret.g_x -= b->scroll.current.x - area->g_x; + caret.g_y -= b->scroll.current.y - area->g_y; + + if( !rc_lintersect( area, &caret ) ) { + return; + } + + MFDB screen; + short pxy[8]; + + /* save background: */ + //assert( b->caret.background.fd_addr == NULL ); + init_mfdb( app.nplanes, caret.g_w, caret.g_h, 0, + &b->caret.background ); + init_mfdb( 0, caret.g_w, caret.g_h, 0, &screen ); + pxy[0] = caret.g_x; + pxy[1] = caret.g_y; + pxy[2] = caret.g_x + caret.g_w - 1; + pxy[3] = caret.g_y + caret.g_h - 1; + pxy[4] = 0; + pxy[5] = 0; + pxy[6] = caret.g_w - 1; + pxy[7] = caret.g_h - 1; + /* hide the mouse */ + v_hide_c ( app.graf.handle); + /* copy screen image */ + vro_cpyfm ( app.graf.handle, S_ONLY, pxy, &screen, &b->caret.background); + /* restore the mouse */ + v_show_c ( app.graf.handle, 1); + /* draw caret: */ + caret.g_x -= area->g_x; + caret.g_y -= area->g_y; + clip.x0 = caret.g_x; + clip.y0 = caret.g_y; + clip.x1 = caret.g_x + caret.g_w-1; + clip.y1 = caret.g_y + caret.g_h-1; /* store old clip before adjusting it: */ plot_get_clip( &old_clip ); /* clip to cursor: */ - plot_clip( &clip ); - plot_rectangle( caret.g_x, caret.g_y, - caret.g_x+caret.g_w, caret.g_y+caret.g_h, - plot_style_caret ); + plot_clip( &clip ); + plot_line( caret.g_x, caret.g_y, caret.g_x, caret.g_y + caret.g_h, + plot_style_caret ); /* restore old clip area: */ plot_clip( &old_clip ); b->caret.current.g_x = caret.g_x + gw->browser->scroll.current.x; b->caret.current.g_y = caret.g_y + gw->browser->scroll.current.y; - b->caret.current.g_w = caret.g_w; + b->caret.current.g_w = caret.g_w; b->caret.current.g_h = caret.g_h; } } @@ -807,13 +744,15 @@ void browser_redraw( struct gui_window * gw ) LGRECT bwrect; struct s_browser * b = gw->browser; short todo[4]; - struct rect clip; + struct rect clip; + /* used for clipping of content redraw: */ + struct rect redraw_area; if( b->attached == false || b->bw->current_content == NULL ) { return; } - browser_get_rect(gw, BR_CONTENT, &bwrect); + browser_get_rect(gw, BR_CONTENT, &bwrect); plotter->resize(plotter, bwrect.g_w, bwrect.g_h); plotter->move(plotter, bwrect.g_x, bwrect.g_y ); @@ -864,11 +803,11 @@ void browser_redraw( struct gui_window * gw ) 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; - b->redraw.area.y0 = area.g_y; - b->redraw.area.x1 = area.g_x + area.g_w; - b->redraw.area.y1 = area.g_y + area.g_h; - browser_redraw_content( gw, 0, 0 ); + redraw_area.x0 = area.g_x; + redraw_area.y0 = area.g_y; + redraw_area.x1 = area.g_x + area.g_w; + redraw_area.y1 = area.g_y + area.g_h; + browser_redraw_content( gw, 0, 0, &redraw_area ); } else { /* the area should be kept scheduled for later redraw, but because this @@ -889,8 +828,8 @@ void browser_redraw( struct gui_window * gw ) } b->redraw.areas_used = 0; } - if( b->caret.redraw == true && b->bw->current_content != NULL ) { - GRECT area; + if( b->caret.redraw == true && b->bw->current_content != NULL ) { + LGRECT area; todo[0] = bwrect.g_x; todo[1] = bwrect.g_y; todo[2] = todo[0] + bwrect.g_w; @@ -913,15 +852,8 @@ static void __CDECL browser_evnt_redraw( COMPONENT * c, long buff[8], void * dat short pxy[8]; struct gui_window * gw = (struct gui_window *) data; CMP_BROWSER b = gw->browser; - LGRECT work, lclip, rwork; - - // TODO: maybe implement something like validate_gw() - // to fetch spurious redraw events? the function should - // traverse all gui_windows and see if gw exists in the list + LGRECT work, lclip; - int xoff,yoff,width,heigth; - short cw, ch, cellw, cellh; - /* use that instead of browser_find_root() ? */ browser_get_rect( gw, BR_CONTENT, &work ); lclip = work; if ( !rc_lintersect( (LGRECT*)&buff[4], &lclip ) ) return; @@ -953,12 +885,23 @@ static void __CDECL browser_evnt_redraw( COMPONENT * c, long buff[8], void * dat lclip.g_h = work.g_h + lclip.g_y; lclip.g_y = 0; } - if( lclip.g_h > 0 && lclip.g_w > 0 ) { - browser_schedule_redraw( gw, lclip.g_x, lclip.g_y, - lclip.g_x + lclip.g_w, lclip.g_y + lclip.g_h - ); + + if( gw->browser->reformat_pending == true ){ + LGRECT newsize; + gw->browser->reformat_pending = false; + browser_get_rect(gw, BR_CONTENT, &newsize); + /* this call will also schedule an redraw for the complete */ + /* area. */ + /* Resize must be handled here, because otherwise */ + /* a redraw is scheduled twice (1. by the frontend, 2. by AES) */ + browser_window_reformat(b->bw, false, newsize.g_w, newsize.g_h ); + } else { + browser_schedule_redraw( gw, lclip.g_x, lclip.g_y, + lclip.g_x + lclip.g_w, lclip.g_y + lclip.g_h + ); + } } return; diff --git a/atari/browser.h b/atari/browser.h index 32c0fec72..3eb94374f 100755 --- a/atari/browser.h +++ b/atari/browser.h @@ -17,7 +17,9 @@ */ #ifndef NS_ATARI_BROWSER_H -#define NS_ATARI_BROWSER_H +#define NS_ATARI_BROWSER_H + +#include "atari/redrawslots.h" /* Each browser_window in the Atari Port is represented by an struct s_browser, @@ -30,13 +32,6 @@ */ #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_rect { @@ -65,21 +60,10 @@ struct s_scroll_info */ struct s_caret { - GRECT requested; - GRECT current; - bool redraw; -}; - -/* - This struct holds scheduled redraw requests. -*/ -struct rect; -struct s_browser_redrw_info -{ - struct rect areas[MAX_REDRW_SLOTS]; - short areas_used; - /* used for clipping of content redraw: */ - struct rect area; + LGRECT requested; + LGRECT current; + bool redraw; + MFDB background; }; /* @@ -99,9 +83,10 @@ struct s_browser COMPONENT * comp; struct browser_window * bw; struct s_scroll_info scroll; - struct s_browser_redrw_info redraw; + struct s_redrw_slots redraw; struct s_caret caret; - bool attached; + bool attached; + bool reformat_pending; }; struct s_browser * browser_create( struct gui_window * gw, struct browser_window * clone, struct browser_window *bw, int lt, int w, int flex ); @@ -113,8 +98,10 @@ void browser_set_content_size(struct gui_window * gw, int w, int h); void browser_scroll( struct gui_window * gw, short MODE, int value, bool abs ); struct gui_window * browser_find_root( struct gui_window * gw ); bool browser_redraw_required( struct gui_window * gw); -static void browser_process_scroll( struct gui_window * gw, LGRECT bwrect ); - +void browser_redraw_caret( struct gui_window * gw, LGRECT * area); +void browser_restore_caret_background(struct gui_window * gw, LGRECT * area); +/* update loc / size of the browser widgets: */ +void browser_update_rects(struct gui_window * gw ); /* This queues an redraw to one of the slots. The following strategy is used: @@ -126,17 +113,7 @@ static void browser_process_scroll( struct gui_window * gw, LGRECT bwrect ); 4. if no slot is available, it will simply merge the new rectangle with the last available slot. */ -void browser_redraw_caret( struct gui_window * gw, GRECT * area ); -static void browser_redraw_content( struct gui_window * gw, int xoff, int yoff ); - -/* update loc / size of the browser widgets: */ -void browser_update_rects(struct gui_window * gw ); void browser_schedule_redraw_rect(struct gui_window * gw, short x, short y, short w, short h); void browser_schedule_redraw(struct gui_window * gw, short x, short y, short w, short h ); -static void __CDECL browser_evnt_resize( COMPONENT * c, long buff[8], void * data); -static void __CDECL browser_evnt_destroy( COMPONENT * c, long buff[8], void * data); -static void __CDECL browser_evnt_redraw( COMPONENT * c, long buff[8], void * data); -static void __CDECL browser_evnt_mbutton( COMPONENT * c, long buff[8], void * data); - #endif diff --git a/atari/browser_win.c b/atari/browser_win.c index 87f2dbcc7..4824a3808 100755 --- a/atari/browser_win.c +++ b/atari/browser_win.c @@ -67,7 +67,27 @@ extern short last_drag_x; extern short last_drag_y; void __CDECL std_szd( WINDOW * win, short buff[8], void * ); -void __CDECL std_mvd( WINDOW * win, short buff[8], void * ); +void __CDECL std_mvd( WINDOW * win, short buff[8], void * ); + + +/* -------------------------------------------------------------------------- */ +/* Static module methods follow here: */ +/* -------------------------------------------------------------------------- */ +static void evnt_toolbar_click(WINDOW * win, short buf[8], void * data); +static void __CDECL evnt_window_redraw( WINDOW *win, short buff[8], void *data ); +static void __CDECL evnt_window_icondraw( WINDOW *win, short buff[8], void *data ); +static void __CDECL evnt_window_newtop( WINDOW *win, short buff[8], void *data ); +void __CDECL evnt_window_resize( WINDOW *win, short buff[8], void * data ); +static void __CDECL evnt_window_move( WINDOW *win, short buff[8], void * data ); +static void __CDECL evnt_window_rt_resize( WINDOW *win, short buff[8], void * date ); +static void __CDECL evnt_window_close( WINDOW *win, short buff[8], void *data ); +static void __CDECL evnt_window_dd( WINDOW *win, short wbuff[8], void * data ) ; +static void __CDECL evnt_window_destroy( WINDOW *win, short buff[8], void *data ); +static void __CDECL evnt_window_keybd(WINDOW *win, short buff[8], void *data ); +static void __CDECL evnt_window_mbutton(WINDOW *win, short buff[8], void *data ); +static void __CDECL evnt_window_m1( WINDOW * win, short buff[8], void * data); +static void __CDECL evnt_window_slider( WINDOW * win, short buff[8], void * data); +static void __CDECL evnt_window_arrowed( WINDOW *win, short buff[8], void *data ); /* -------------------------------------------------------------------------- */ /* Module public functions: */ @@ -259,7 +279,8 @@ int window_destroy( struct gui_window * gw) /* needed? */ /*listRemove( (LINKABLE*)gw->root->cmproot ); */ if( gw->root ) { - /* TODO: check if no other browser is bound to this root window! */ + /* TODO: check if no other browser is bound to this root window! */ + /* only needed for tabs */ if( gw->root->title ) free( gw->root->title ); if( gw->root->cmproot ) @@ -289,7 +310,7 @@ void window_open( struct gui_window * gw) mt_CompEvntExec( gl_appvar, gw->browser->comp, lfbuff ); /* recompute the nested component sizes and positions: */ - browser_update_rects( gw ); + browser_update_rects( gw ); mt_WindGetGrect( &app, gw->root->handle, WF_CURRXYWH, (GRECT*)&gw->root->loc); browser_get_rect( gw, BR_CONTENT, &br ); plotter->move( plotter, br.g_x, br.g_y ); @@ -298,6 +319,7 @@ void window_open( struct gui_window * gw) if( gw->root->statusbar != NULL ){ gw->root->statusbar->attached = true; } + tb_adjust_size( gw ); /*TBD: get already present content and set size? */ } @@ -358,6 +380,7 @@ bool window_widget_has_focus( struct gui_window * gw, enum focus_element_type t, return( ( element == gw->root->focus.element && t == gw->root->focus.type) ); } + /* -------------------------------------------------------------------------- */ /* Event Handlers: */ /* -------------------------------------------------------------------------- */ @@ -390,7 +413,8 @@ static void __CDECL evnt_window_arrowed( WINDOW *win, short buff[8], void *data break; } browser_scroll( input_window, buff[4], value, abs ); -} +} + static void __CDECL evnt_window_dd( WINDOW *win, short wbuff[8], void * data ) { @@ -516,7 +540,6 @@ static void __CDECL evnt_window_m1( WINDOW * win, short buff[8], void * data) { struct gui_window * gw = input_window; static bool prev_url = false; - static bool prev_sb = false; short mx, my, mbut, mkstate; bool a = false; //flags if mouse is within controls or browser bool within = false; @@ -555,21 +578,10 @@ static void __CDECL evnt_window_m1( WINDOW * win, short buff[8], void * data) prev_url = a = true; } } - if( gw->root->statusbar && within == false /* && a == false */ ) { - if( mx >= sbbox.g_x + (sbbox.g_w-MOVER_WH) && mx <= sbbox.g_x + sbbox.g_w && - my >= sbbox.g_y + (sbbox.g_h-MOVER_WH) && my <= sbbox.g_y + sbbox.g_h ) { - /* mouse within sizer box ( bottom right ) */ - prev_sb = a = true; - gem_set_cursor( &gem_cursors.sizenwse ); - } - } if( !a ) { - if( prev_sb ) - gw->root->statusbar->resize_init = true; - if( prev_url || prev_sb ) { + if( prev_url ) { gem_set_cursor( &gem_cursors.arrow ); prev_url = false; - prev_sb = false; } /* report mouse move in the browser window */ if( within ){ @@ -632,14 +644,15 @@ static void __CDECL evnt_window_slider( WINDOW * win, short buff[8], void * data int dy = buff[5]; GRECT work, screen; struct gui_window * gw = data; - + if (!dx && !dy) return; if( input_window == NULL || input_window != gw ) { return; } - /* update the sliders _before_ we call redraw (which might depend on the slider possitions) */ + /* update the sliders _before_ we call redraw + (which might depend on the slider possitions) */ WindSlider( win, (dx?HSLIDER:0) | (dy?VSLIDER:0) ); if( dy > 0 ) @@ -650,6 +663,8 @@ static void __CDECL evnt_window_slider( WINDOW * win, short buff[8], void * data browser_scroll( gw, WA_RTPAGE, abs(dx), false ); else if( dx < 0 ) browser_scroll( gw, WA_LFPAGE, abs(dx), false ); + + } @@ -707,7 +722,7 @@ static void __CDECL evnt_window_move( WINDOW *win, short buff[8], void * data ) void __CDECL evnt_window_resize( WINDOW *win, short buff[8], void * data ) { short wx, wy, wh, ww, nw, nh; - short r; + short r; wind_get( win->handle, WF_CURRXYWH, &wx, &wy, &ww, &wh ); r = graf_rubberbox(wx, wy, 20, 20, &nw, &nh); @@ -726,8 +741,8 @@ static void __CDECL evnt_window_rt_resize( WINDOW *win, short buff[8], void * da { short x,y,w,h; struct gui_window * gw; - LGRECT rect; - + LGRECT rect; + if(buff[0] == WM_FORCE_MOVE ) { std_mvd(win, buff, &app); std_szd(win, buff, &app); @@ -736,30 +751,28 @@ static void __CDECL evnt_window_rt_resize( WINDOW *win, short buff[8], void * da wind_get( win->handle, WF_CURRXYWH, &x, &y, &w, &h ); gw = (struct gui_window *)data; - assert( gw != NULL ); + assert( gw != NULL ); if(gw->root->loc.g_w != w || gw->root->loc.g_h != h ){ /* report resize to component interface: */ - browser_update_rects( gw ); - mt_WindGetGrect( &app, gw->root->handle, WF_CURRXYWH, (GRECT*)&gw->root->loc); - browser_get_rect( gw, BR_CONTENT, &rect ); - if( gw->browser->bw->current_content != NULL ) - browser_window_reformat(gw->browser->bw, false, rect.g_w, rect.g_h ); - else - WindClear( gw->root->handle ); - gw->root->toolbar->url.scrollx = 0; - - /* send complete redraw to toolbar & statusbar: */ - mt_CompGetLGrect(&app, gw->root->toolbar->comp, WF_WORKXYWH, &rect); - ApplWrite( _AESapid, WM_REDRAW, gw->root->handle->handle, - rect.g_x, rect.g_y, rect.g_w, rect.g_h - ); - mt_CompGetLGrect(&app, gw->root->statusbar->comp, WF_WORKXYWH, &rect); - ApplWrite( _AESapid, WM_REDRAW, gw->root->handle->handle, - rect.g_x, rect.g_y, rect.g_w, rect.g_h - ); - - /* TODO: recalculate scroll position, instead of zeroing? */ + browser_update_rects( gw ); + tb_adjust_size( gw ); + if( gw->browser->bw->current_content != NULL ){ + /* Reformat will happen when next redraw message arrives: */ + gw->browser->reformat_pending = true; + if( sys_XAAES() ){ + if( gw->root->loc.g_w > w || gw->root->loc.g_h > h ){ + ApplWrite( _AESapid, WM_REDRAW, gw->root->handle->handle, + gw->root->loc.g_x, gw->root->loc.g_y, + gw->root->loc.g_w, gw->root->loc.g_h ); + } + } + mt_WindGetGrect( &app, gw->root->handle, WF_CURRXYWH, + (GRECT*)&gw->root->loc); + } + else { + WindClear( gw->root->handle ); + } } else { if(gw->root->loc.g_x != x || gw->root->loc.g_y != y ){ mt_WindGetGrect( &app, gw->root->handle, WF_CURRXYWH, (GRECT*)&gw->root->loc); diff --git a/atari/browser_win.h b/atari/browser_win.h index a17cb4c99..0826b8668 100755 --- a/atari/browser_win.h +++ b/atari/browser_win.h @@ -64,23 +64,4 @@ void window_set_icon(struct gui_window * gw, struct bitmap * bmp ); /* Public event handlers: */ /* -------------------------------------------------------------------------- */ - -/* -------------------------------------------------------------------------- */ -/* Static module methods follow here: */ -/* -------------------------------------------------------------------------- */ -static void evnt_toolbar_click(WINDOW * win, short buf[8], void * data); -static void __CDECL evnt_window_redraw( WINDOW *win, short buff[8], void *data ); -static void __CDECL evnt_window_icondraw( WINDOW *win, short buff[8], void *data ); -static void __CDECL evnt_window_newtop( WINDOW *win, short buff[8], void *data ); -void __CDECL evnt_window_resize( WINDOW *win, short buff[8], void * data ); -static void __CDECL evnt_window_move( WINDOW *win, short buff[8], void * data ); -static void __CDECL evnt_window_rt_resize( WINDOW *win, short buff[8], void * date ); -static void __CDECL evnt_window_close( WINDOW *win, short buff[8], void *data ); -static void __CDECL evnt_window_dd( WINDOW *win, short wbuff[8], void * data ) ; -static void __CDECL evnt_window_destroy( WINDOW *win, short buff[8], void *data ); -static void __CDECL evnt_window_keybd(WINDOW *win, short buff[8], void *data ); -static void __CDECL evnt_window_mbutton(WINDOW *win, short buff[8], void *data ); -static void __CDECL evnt_window_m1( WINDOW * win, short buff[8], void * data); -static void __CDECL evnt_window_slider( WINDOW * win, short buff[8], void * data); -static void __CDECL evnt_window_arrowed( WINDOW *win, short buff[8], void *data ); #endif diff --git a/atari/ctxmenu.c b/atari/ctxmenu.c index fadf69de2..06df25903 100644 --- a/atari/ctxmenu.c +++ b/atari/ctxmenu.c @@ -96,7 +96,7 @@ static struct s_context_info * get_context_info( struct gui_window * gw, short m memset( &ctxinfo.ccdata, sizeof(struct contextual_content), 0 ); browser_window_get_contextual_content( gw->browser->bw, - mx+gw->browser->scroll.current.x, + mx+gw->browser->scroll.current.x, my+gw->browser->scroll.current.y, (struct contextual_content*)&ctxinfo.ccdata ); @@ -149,7 +149,8 @@ void context_popup( struct gui_window * gw, short x, short y ) char * data; FILE * fp_tmpfile; char * tempfile; - int err = 0; + int err = 0; + char cmdline[128]; pop = get_tree( POP_CTX ); if( pop == NULL ) @@ -251,11 +252,18 @@ void context_popup( struct gui_window * gw, short x, short y ) fp_tmpfile = fopen( tempfile, "w" ); if( fp_tmpfile ){ fwrite( data, size, 1, fp_tmpfile ); - fclose( fp_tmpfile ); - err = ShelWrite( option_atari_editor, tempfile , NULL, 1, 0); + fclose( fp_tmpfile ); + // TODO: check if app is runnin, if not, use pexec or such. + /*sprintf((char*)&cmdline, "%s \"%s\"", option_atari_editor, tempfile ); + system( (char*)&cmdline ); + */ + //err = ShelWrite( option_atari_editor, tempfile , option_atari_editor, 1, 0); LOG(("launched: %s %s (%d)\n", option_atari_editor, tempfile, err )); - } + } + } + } else { + LOG(("Please set option_atari_editor!")); } break; diff --git a/atari/encoding.c b/atari/encoding.c new file mode 100644 index 000000000..f73451c81 --- /dev/null +++ b/atari/encoding.c @@ -0,0 +1,50 @@ +#include "atari/encoding.h" + + +/* TODO: this need a rework..., encoding to atari st doesn|t always work. +( gui_add_to_clipboard...) */ +utf8_convert_ret utf8_to_local_encoding(const char *string, + size_t len, + char **result) +{ + utf8_convert_ret r; + r = utf8_to_enc(string, "ATARIST", len, result); + if(r != UTF8_CONVERT_OK) { + r = utf8_to_enc(string, "UTF-8", len, result); + assert( r == UTF8_CONVERT_OK ); + } + return r; +} + +utf8_convert_ret local_encoding_to_utf8(const char *string, + size_t len, + char **result) +{ + return utf8_from_enc(string, "ATARIST", len, result); +} + + +/* borrowed from highwire project: */ +static const uint16_t Atari_to_Unicode[] = { + /* .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F */ + /* 7F */ 0x0394, + /* 8. */ 0x00C7,0x00FC,0x00E9,0x00E2,0x00E4,0x00E0,0x00E5,0x00E7,0x00EA,0x00EB,0x00E8,0x00EF,0x00EE,0x00EC,0x00C4,0x00C5, + /* 9. */ 0x00C9,0x00E6,0x00C6,0x00F4,0x00F6,0x00F2,0x00FB,0x00F9,0x00FF,0x00D6,0x00DC,0x00A2,0x00A3,0x00A5,0x00DF,0x0192, + /* A. */ 0x00E1,0x00ED,0x00F3,0x00FA,0x00F1,0x00D1,0x00AA,0x00BA,0x00BF,0x2310,0x00AC,0x00BD,0x00BC,0x00A1,0x00AB,0x00BB, + /* B. */ 0x00C3,0x00F5,0x00D8,0x00F8,0x0153,0x0152,0x00C0,0x00C3,0x00D5,0x00A8,0x00B4,0x2020,0x00B6,0x00A9,0x00AE,0x2122, + /* C. */ 0x0133,0x0132,0x05D0,0x05D1,0x05D2,0x05D3,0x05D4,0x05D5,0x05D6,0x05D7,0x05D8,0x05D9,0x05DB,0x05DC,0x05DE,0x05E0, + /* D. */ 0x05E1,0x05E2,0x05E4,0x05E6,0x05E7,0x05E8,0x05E9,0x05EA,0x05DF,0x05DA,0x05DD,0x05E3,0x05E5,0x00A7,0x2038,0x221E, + /* E. */ 0x03B1,0x03B2,0x0393,0x03C0,0x03A3,0x03C3,0x00B5,0x03C4,0x03A6,0x0398,0x03A9,0x03B4,0x222E,0x03C6,0x2208,0x2229, + /* F. */ 0x2261,0x00B1,0x2265,0x2264,0x2320,0x2321,0x00F7,0x2248,0x00B0,0x2022,0x00B7,0x221A,0x207F,0x00B2,0x00B3,0x00AF +}; +#define BEG_Atari_to_Unicode 0x7F + +int atari_to_ucs4(unsigned char atari) +{ + uint32_t ucs4 = 0xfffd; + if ( atari >= BEG_Atari_to_Unicode && atari <= 0xFE ) + ucs4 = (int)Atari_to_Unicode[(short)atari - BEG_Atari_to_Unicode]; + else + ucs4 = (int)atari; + return( ucs4 ); +} diff --git a/atari/encoding.h b/atari/encoding.h new file mode 100644 index 000000000..e2dd4ca4d --- /dev/null +++ b/atari/encoding.h @@ -0,0 +1,19 @@ +#ifndef NS_ATARI_ENCODING_H +#define NS_ATARI_ENCODING_H + +#include +#include +#include +#include + +#include "css/css.h" +#include "render/font.h" +#include "utils/utf8.h" + +utf8_convert_ret local_encoding_to_utf8(const char *string, + size_t len, + char **result); + +int atari_to_ucs4( unsigned char atarichar); + +#endif diff --git a/atari/font.c b/atari/font.c index caebefc6d..2098055eb 100755 --- a/atari/font.c +++ b/atari/font.c @@ -21,11 +21,6 @@ #include #include -/* -#include -#include FT_CACHE_H -*/ - #include "css/css.h" #include "render/font.h" #include "utils/utf8.h" @@ -45,68 +40,21 @@ extern GEM_FONT_PLOTTER fplotter; -/* TODO: this need a rework..., encoding to atari st doesn|t always work. ( gui_add_to_clipboard...) */ -utf8_convert_ret utf8_to_local_encoding(const char *string, - size_t len, - char **result) -{ - utf8_convert_ret r; - r = utf8_to_enc(string, "ATARIST", len, result); - if(r != UTF8_CONVERT_OK) { - r = utf8_to_enc(string, "UTF-8", len, result); - assert( r == UTF8_CONVERT_OK ); - } - return r; -} - -utf8_convert_ret local_encoding_to_utf8(const char *string, - size_t len, - char **result) -{ - return utf8_from_enc(string, "ATARIST", len, result); -} - - -/* borrowed from highwire project: */ -static const uint16_t Atari_to_Unicode[] = { - /* .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F */ - /* 7F */ 0x0394, - /* 8. */ 0x00C7,0x00FC,0x00E9,0x00E2,0x00E4,0x00E0,0x00E5,0x00E7,0x00EA,0x00EB,0x00E8,0x00EF,0x00EE,0x00EC,0x00C4,0x00C5, - /* 9. */ 0x00C9,0x00E6,0x00C6,0x00F4,0x00F6,0x00F2,0x00FB,0x00F9,0x00FF,0x00D6,0x00DC,0x00A2,0x00A3,0x00A5,0x00DF,0x0192, - /* A. */ 0x00E1,0x00ED,0x00F3,0x00FA,0x00F1,0x00D1,0x00AA,0x00BA,0x00BF,0x2310,0x00AC,0x00BD,0x00BC,0x00A1,0x00AB,0x00BB, - /* B. */ 0x00C3,0x00F5,0x00D8,0x00F8,0x0153,0x0152,0x00C0,0x00C3,0x00D5,0x00A8,0x00B4,0x2020,0x00B6,0x00A9,0x00AE,0x2122, - /* C. */ 0x0133,0x0132,0x05D0,0x05D1,0x05D2,0x05D3,0x05D4,0x05D5,0x05D6,0x05D7,0x05D8,0x05D9,0x05DB,0x05DC,0x05DE,0x05E0, - /* D. */ 0x05E1,0x05E2,0x05E4,0x05E6,0x05E7,0x05E8,0x05E9,0x05EA,0x05DF,0x05DA,0x05DD,0x05E3,0x05E5,0x00A7,0x2038,0x221E, - /* E. */ 0x03B1,0x03B2,0x0393,0x03C0,0x03A3,0x03C3,0x00B5,0x03C4,0x03A6,0x0398,0x03A9,0x03B4,0x222E,0x03C6,0x2208,0x2229, - /* F. */ 0x2261,0x00B1,0x2265,0x2264,0x2320,0x2321,0x00F7,0x2248,0x00B0,0x2022,0x00B7,0x221A,0x207F,0x00B2,0x00B3,0x00AF -}; -#define BEG_Atari_to_Unicode 0x7F - -int atari_to_ucs4(unsigned char atari) -{ - uint32_t ucs4 = 0xfffd; - if ( atari >= BEG_Atari_to_Unicode && atari <= 0xFE ) - ucs4 = (int)Atari_to_Unicode[(short)atari - BEG_Atari_to_Unicode]; - else - ucs4 = (int)atari; - return( ucs4 ); -} - -static bool atari_font_position_in_string(const plot_font_style_t * fstyle,const char *string, +static bool atari_font_position_in_string(const plot_font_style_t * fstyle,const char *string, size_t length,int x, size_t *char_offset, int *actual_x ) { fplotter->pixel_pos(fplotter, fstyle, string, length, x, char_offset, actual_x ); return( true ); } -static bool atari_font_split( const plot_font_style_t * fstyle, const char *string, +static bool atari_font_split( const plot_font_style_t * fstyle, const char *string, size_t length,int x, size_t *char_offset, int *actual_x ) { fplotter->str_split( fplotter, fstyle, string, length, x, char_offset, actual_x ); - return( true ); + return( true ); } -static bool atari_font_width( const plot_font_style_t *fstyle, const char * str, +static bool atari_font_width( const plot_font_style_t *fstyle, const char * str, size_t length, int * width ) { fplotter->str_width( fplotter, fstyle, str, length, width ); diff --git a/atari/font.h b/atari/font.h index 72271803e..2717497b4 100755 --- a/atari/font.h +++ b/atari/font.h @@ -16,16 +16,10 @@ * along with this program. If not, see . */ -#ifndef NS_ATARI_FT_FONT_H -#define NS_ATARI_FT_FONT_H +#ifndef NS_ATARI_FONT_H +#define NS_ATARI_FONT_H + -#include "utils/utf8.h" - -utf8_convert_ret local_encoding_to_utf8(const char *string, - size_t len, - char **result); - -int atari_to_ucs4( unsigned char atarichar); #endif /* NETSURF_FB_FONT_H */ diff --git a/atari/gui.c b/atari/gui.c index 69e69bbcc..c6dfb4f87 100755 --- a/atari/gui.c +++ b/atari/gui.c @@ -68,7 +68,7 @@ #include "atari/hotlist.h" #include "atari/login.h" #include "atari/global_evnt.h" -#include "atari/font.h" +#include "atari/encoding.h" #include "atari/res/netsurf.rsh" #include "atari/plot.h" #include "atari/clipboard.h" @@ -171,11 +171,16 @@ void gui_poll(bool active) for( g = window_list; g != NULL; g=g->next ) { if( browser_redraw_required( g ) ){ browser_redraw( g ); + } + if( g->root->toolbar ){ + if(g->root->toolbar->url.redraw ){ + tb_url_redraw( g ); + } } } if( evnt.timer != 0 && !active ){ - /* this suits for stuff with lower priority */ - //hotlist_redraw(); + /* this suits for stuff with lower priority */ + /* TBD: really be spare on redraws??? */ atari_treeview_redraw( hl.tv ); } } @@ -310,7 +315,7 @@ void gui_window_redraw_window(struct gui_window *gw) if (gw == NULL) return; b = gw->browser; - browser_get_rect( gw, BR_CONTENT, &rect ); + browser_get_rect( gw, BR_CONTENT, &rect ); browser_schedule_redraw( gw, 0, 0, rect.g_w, rect.g_h ); } @@ -326,7 +331,7 @@ void gui_window_update_box(struct gui_window *gw, const struct rect *rect) int y0 = rect->y0 - b->scroll.current.y; int w,h; w = rect->x1 - rect->x0; - h = rect->y1 - rect->y0; + h = rect->y1 - rect->y0; browser_schedule_redraw_rect( gw, x0, y0, w,h); } @@ -367,7 +372,7 @@ void gui_window_set_scroll(struct gui_window *w, int sx, int sy) void gui_window_scroll_visible(struct gui_window *w, int x0, int y0, int x1, int y1) { LOG(("%s:(%p, %d, %d, %d, %d)", __func__, w, x0, y0, x1, y1)); - gui_window_set_scroll(w,x0,y0); + gui_window_set_scroll(w,x0,y0); browser_schedule_redraw_rect( w, 0, 0, x1-x0,y1-y0); } @@ -530,7 +535,7 @@ void gui_window_stop_throbber(struct gui_window *w) work.g_x, work.g_y, work.g_w, work.g_h ); } -/* Place caret in window */ +/* Place caret in window */ void gui_window_place_caret(struct gui_window *w, int x, int y, int height) { LGRECT work; @@ -540,46 +545,37 @@ void gui_window_place_caret(struct gui_window *w, int x, int y, int height) if( w->browser->caret.current.g_w > 0 ) gui_window_remove_caret( w ); w->browser->caret.requested.g_x = x; - w->browser->caret.requested.g_y = y; - w->browser->caret.requested.g_w = 2; + w->browser->caret.requested.g_y = y; + w->browser->caret.requested.g_w = 1; w->browser->caret.requested.g_h = height; w->browser->caret.redraw = true; - browser_schedule_redraw_rect( - w, - x - b->scroll.current.x, - y - b->scroll.current.y, - w->browser->caret.requested.g_w, - w->browser->caret.requested.g_h - ); return; } /** * clear window caret - */ + */ void gui_window_remove_caret(struct gui_window *w) -{ +{ + LGRECT rect; if (w == NULL) return; - CMP_BROWSER b = w->browser; - w->browser->caret.requested.g_w = 0; - w->browser->caret.redraw = true; - browser_schedule_redraw_rect( w, - w->browser->caret.current.g_x - b->scroll.current.x, - w->browser->caret.current.g_y - b->scroll.current.y, - w->browser->caret.current.g_w, - w->browser->caret.current.g_h - ); + CMP_BROWSER b = w->browser; + + if( w->browser->caret.background.fd_addr != NULL ){ + browser_restore_caret_background( w, NULL ); + w->browser->caret.requested.g_w = 0; + w->browser->caret.current.g_w = 0; + } + return; } void gui_window_set_icon(struct gui_window *g, hlcache_handle *icon) { - /* Untestet, favicon support has been dropped, so this is dead code. */ g->icon = (icon != NULL) ? content_get_bitmap(icon) : NULL; - } void @@ -871,8 +867,6 @@ void gui_quit(void) hotlist_destroy(); - /* send WM_DESTROY to windows purely managed by windom: */ - urldb_save_cookies(option_cookie_file); urldb_save(option_url_file); @@ -1025,10 +1019,6 @@ static void gui_init(int argc, char** argv) atari_plotter_init( option_atari_screen_driver, option_atari_font_driver ); LOG(("Knockout rendering: %s\n", option_atari_knockout ? "yes" : "no")); plot_set_knockout( option_atari_knockout ); - /* Interface colours */ - option_gui_colour_bg_1 = 0xFFFFFF; /** Background (bbggrr) */ - option_gui_colour_fg_1 = 0xFF0000; /** Foreground (bbggrr) */ - option_gui_colour_fg_2 = 0x000000; /** Foreground selected (bbggrr) */ } static char *theapp = (char*)"NetSurf"; diff --git a/atari/history.c b/atari/history.c index b26257475..36edcda00 100755 --- a/atari/history.c +++ b/atari/history.c @@ -21,6 +21,7 @@ void global_history_add_recent(const char *url) { + } char **global_history_get_recent(int *count) diff --git a/atari/plot.h b/atari/plot.h index 02d9f37a9..7348c71c7 100755 --- a/atari/plot.h +++ b/atari/plot.h @@ -31,6 +31,7 @@ int atari_plotter_finalise( void ); void plot_set_knockout( int set ); bool plot_get_clip(struct rect * out); bool plot_clip(const struct rect *clip); -bool plot_rectangle( int x0, int y0, int x1, int y1,const plot_style_t *style ); +bool plot_rectangle( int x0, int y0, int x1, int y1,const plot_style_t *style ); +bool plot_line( int x0, int y0, int x1, int y1, const plot_style_t *style ); #endif diff --git a/atari/redrawslots.c b/atari/redrawslots.c new file mode 100644 index 000000000..f3969c283 --- /dev/null +++ b/atari/redrawslots.c @@ -0,0 +1,79 @@ + +#include +#include "windom.h" +#include "utils/types.h" +#include "atari/redrawslots.h" + +void redraw_slots_init(struct s_redrw_slots * slots, short size) +{ + slots->size = MIN( MAX_REDRW_SLOTS , size); + slots->areas_used = 0; +} + + +static inline bool rect_intersect( struct rect * box1, struct rect * 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 slots, coords are relative. +*/ +void redraw_slot_schedule(struct s_redrw_slots * slots, short x0, short y0, short x1, short y1) +{ + int i; + struct rect area; + + area.x0 = x0; + area.y0 = y0; + area.x1 = x1; + area.y1 = y1; + + for( i=0; iareas_used; i++) { + if( slots->areas[i].x0 <= x0 + && slots->areas[i].x1 >= x1 + && slots->areas[i].y0 <= y0 + && slots->areas[i].y1 >= y1 ){ + /* the area is already queued for redraw */ + return; + } else { + if( rect_intersect(&slots->areas[i], &area ) ){ + slots->areas[i].x0 = MIN(slots->areas[i].x0, x0); + slots->areas[i].y0 = MIN(slots->areas[i].y0, y0); + slots->areas[i].x1 = MAX(slots->areas[i].x1, x1); + slots->areas[i].y1 = MAX(slots->areas[i].y1, y1); + return; + } + } + } + + if( slots->areas_used < slots->size ) { + slots->areas[slots->areas_used].x0 = x0; + slots->areas[slots->areas_used].x1 = x1; + slots->areas[slots->areas_used].y0 = y0; + slots->areas[slots->areas_used].y1 = y1; + slots->areas_used++; + } else { + /* + we are out of available slots, merge box with last slot + this is dumb... but also a very rare case. + */ + slots->areas[slots->size-1].x0 = MIN(slots->areas[i].x0, x0); + slots->areas[slots->size-1].y0 = MIN(slots->areas[i].y0, y0); + slots->areas[slots->size-1].x1 = MAX(slots->areas[i].x1, x1); + slots->areas[slots->size-1].y1 = MAX(slots->areas[i].y1, y1); + } +done: + return; +} diff --git a/atari/redrawslots.h b/atari/redrawslots.h new file mode 100644 index 000000000..ae4b77f6a --- /dev/null +++ b/atari/redrawslots.h @@ -0,0 +1,27 @@ +#ifndef ATARI_REDRAW_SLOTS_H +#define ATARI_REDRAW_SLOTS_H + +/* + MAX_REDRW_SLOTS + This is the number of redraw requests that the slotlist can store. + 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 + +/* + This struct holds scheduled redraw requests. +*/ +struct rect; +struct s_redrw_slots +{ + struct rect areas[MAX_REDRW_SLOTS]; + short size; + short areas_used; +}; + +void redraw_slots_init(struct s_redrw_slots * slots, short size); +void redraw_slot_schedule(struct s_redrw_slots * slots, short x0, short y0, short x1, short y1); + + +#endif diff --git a/atari/toolbar.c b/atari/toolbar.c index 9f41bf3d4..a5e747295 100755 --- a/atari/toolbar.c +++ b/atari/toolbar.c @@ -33,7 +33,8 @@ #include "desktop/history_core.h" #include "desktop/netsurf.h" #include "desktop/browser.h" -#include "desktop/mouse.h" +#include "desktop/mouse.h" +#include "desktop/plot_style.h" #include "desktop/plotters.h" #include "atari/clipboard.h" #include "atari/gui.h" @@ -43,13 +44,26 @@ #include "atari/clipboard.h" #include "atari/misc.h" #include "atari/global_evnt.h" +#include "atari/plot.h" #include "cflib.h" #include "atari/res/netsurf.rsh" -#include "atari/plot/plotter.h" - +#include "atari/plot/plotter.h" + + extern char * cfg_homepage_url; extern short vdih; -extern void * h_gem_rsrc; +extern void * h_gem_rsrc; +extern GEM_PLOTTER plotter; +static OBJECT * throbber_form = NULL; + +static const plot_font_style_t font_style_url = { + .family = PLOT_FONT_FAMILY_SANS_SERIF, + .size = TOOLBAR_URL_TEXT_SIZE_PT*FONT_SIZE_SCALE, + .weight = 400, + .flags = FONTF_NONE, + .background = 0xffffff, + .foreground = 0x0 + }; /* prototypes & order for button widgets: */ static struct s_tb_button tb_buttons[] = @@ -60,10 +74,9 @@ static struct s_tb_button tb_buttons[] = { TOOLBAR_BT_RELOAD, tb_reload_click, NULL }, { TOOLBAR_BT_STOP, tb_stop_click, NULL }, { 0, NULL, NULL } -}; - -static OBJECT * throbber_form = NULL; - +}; + +static void tb_txt_request_redraw(void *data, int x, int y, int w, int h); static void __CDECL button_redraw( COMPONENT *c, long buff[8]) { @@ -218,116 +231,67 @@ void __CDECL evnt_throbber_redraw( COMPONENT *c, long buff[8]) static void __CDECL evnt_url_redraw( COMPONENT *c, long buff[8] ) -{ +{ LGRECT work, clip; + struct gui_window * gw; short pxy[10]; - short i; - short d; - short mchars; - struct gui_window * gw = (struct gui_window *)mt_CompDataSearch(&app, c, CDT_OWNER); - assert( gw != NULL ); - assert( gw->browser != NULL ); - assert( gw->root != NULL ); - assert( gw->browser->bw != NULL ); - CMP_TOOLBAR tb = gw->root->toolbar; + gw = (struct gui_window *)mt_CompDataSearch(&app, c, CDT_OWNER); + if( gw == NULL ) + return; - mt_CompGetLGrect(&app, c, WF_WORKXYWH, &work); + CMP_TOOLBAR tb = gw->root->toolbar; + mt_CompGetLGrect(&app, tb->url.comp, WF_WORKXYWH, &work); + + // this last pixel is drawn by the root component of the toolbar: + // it's the black border, so we leave it out: + work.g_h--; clip = work; - if ( !rc_lintersect( (LGRECT*)&buff[4], &clip ) ) return; - + if ( !rc_lintersect( (LGRECT*)&buff[4], &clip ) ) return; + pxy[0] = clip.g_x; pxy[1] = clip.g_y; - pxy[2] = clip.g_w + clip.g_x; - pxy[3] = clip.g_h + clip.g_y; - vs_clip( vdih, 1, (short*)&pxy ); + pxy[2] = clip.g_w + clip.g_x-1; + pxy[3] = clip.g_h + clip.g_y-1; + vs_clip( vdih, 1, (short*)&pxy ); - mchars = (work.g_w-6 / tb->url.char_size); /* subtract 6px -> 3px padding around text on each side */ - - vswr_mode( vdih, MD_REPLACE); vsf_perimeter( vdih, 0 ); vsf_interior( vdih , 1 ); - vsf_color( vdih, LWHITE ); - vst_point( vdih, 10, &pxy[0], &pxy[1], &pxy[2], &pxy[3] ); - vst_alignment(vdih, 0, 5, &d, &d ); - vst_effects( vdih, 0 ); - vst_color( vdih, BLACK ); - /* gray the whole component: */ - + vsf_color( vdih, LWHITE ); + + //left margin: pxy[0] = work.g_x; pxy[1] = work.g_y; - pxy[2] = work.g_x + work.g_w; - pxy[3] = work.g_y + work.g_h-2; - v_bar( vdih, (short*)&pxy ); - - /* draw outer line, left top: */ - pxy[0] = work.g_x + 2; - pxy[1] = work.g_y + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2); - /* right, top: */ - pxy[2] = work.g_x + work.g_w - 4; - pxy[3] = work.g_y + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2); - /* right, bottom: */ - pxy[4] = work.g_x + work.g_w - 4; - pxy[5] = work.g_y + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2) + URLBOX_HEIGHT; - /* left, bottom: */ - pxy[6] = work.g_x + 2; - pxy[7] = work.g_y + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2) + URLBOX_HEIGHT; - /* left, top again: */ - pxy[8] = work.g_x + 2; - pxy[9] = work.g_y + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2); - vsf_interior( vdih, FIS_SOLID ); - vsf_style( vdih, 1); - vsl_color( vdih, BLACK); - v_pline( vdih, 5, pxy ); - - /* draw white txt box: */ - pxy[0] = pxy[0] + 1; - pxy[1] = pxy[1] + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2) - 1; - pxy[2] = pxy[2] - 1; - pxy[3] = work.g_y + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2) + URLBOX_HEIGHT ; - vsf_color( vdih, WHITE); - v_bar( vdih, pxy ); - if( gw->root->toolbar->url.used > 1 ) { - short curx; - short vqw[4]; - char t[2]; - short cw = 0; - t[0]=tb->url.text[0]; - t[1]=0; - if( atari_sysinfo.sfont_monospaced ) { - vqt_width( vdih, t[0], &vqw[0], &vqw[1], &vqw[2] ); - cw = vqw[0]; - } - int maxx = (clip.g_x + clip.g_w) - cw; - for( curx = work.g_x + 3, i=tb->url.scrollx ; curx < maxx && i < tb->url.used-1; i++ ){ - t[0] = tb->url.text[i]; - v_gtext( vdih, curx, work.g_y + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2) + 2, (char*)&t ); - if( !atari_sysinfo.sfont_monospaced ) { - vqt_width( vdih, t[0], &vqw[0], &vqw[1], &vqw[2] ); - curx += vqw[0]; - } else { - curx += cw; - } - } - } - - if( window_url_widget_has_focus( gw ) ) { - /* draw caret: */ - pxy[0] = 3 + work.g_x + ((tb->url.caret_pos - tb->url.scrollx) * tb->url.char_size); - pxy[1] = pxy[1] + 1; - pxy[2] = 3 + work.g_x + ((tb->url.caret_pos - tb->url.scrollx) * tb->url.char_size); - pxy[3] = pxy[3] - 1 ; - v_pline( vdih, 2, pxy ); - /* draw selection: */ - if( tb->url.selection_len != 0 ) { - vswr_mode( vdih, MD_XOR); - vsl_color( vdih, BLACK); - pxy[0] = 3 + work.g_x + ((tb->url.caret_pos - tb->url.scrollx) * tb->url.char_size); - pxy[2] = pxy[0] + ( gw->root->toolbar->url.selection_len * tb->url.char_size); - v_bar( vdih, pxy ); - vswr_mode( vdih, MD_REPLACE ); - } - } - vs_clip( vdih, 0, (short*)&pxy ); + pxy[2] = work.g_x + TOOLBAR_URL_MARGIN_LEFT-1; + pxy[3] = work.g_y + work.g_h-1; + v_bar( vdih, pxy ); + + // right margin: + pxy[0] = work.g_x+work.g_w-TOOLBAR_URL_MARGIN_RIGHT; + pxy[1] = work.g_y; + pxy[2] = work.g_x+work.g_w-1; + pxy[3] = work.g_y+work.g_h-1; + v_bar( vdih, pxy ); + + // top margin: + pxy[0] = work.g_x; + pxy[1] = work.g_y; + pxy[2] = work.g_x+work.g_w-1; + pxy[3] = work.g_y+TOOLBAR_URL_MARGIN_TOP-1; + v_bar( vdih, pxy ); + + // bottom margin: + pxy[0] = work.g_x; + pxy[1] = work.g_y+work.g_h-TOOLBAR_URL_MARGIN_BOTTOM; + pxy[2] = work.g_x+work.g_w-1; + pxy[3] = work.g_y+work.g_h-1; + v_bar( vdih, pxy ); + + vs_clip( vdih, 0, (short*)&pxy ); + + // TBD: request redraw of textarea for specific region. + clip.g_x -= work.g_x+TOOLBAR_URL_MARGIN_LEFT; + clip.g_y -= work.g_y+TOOLBAR_URL_MARGIN_TOP; + tb_txt_request_redraw( tb, clip.g_x, clip.g_y, clip.g_w, clip.g_h ); } static @@ -342,37 +306,45 @@ void __CDECL evnt_url_click( COMPONENT *c, long buff[8] ) assert( gw != NULL ); CMP_TOOLBAR tb = gw->root->toolbar; mt_CompGetLGrect(&app, c, WF_WORKXYWH, &work); - mx = evnt.mx - work.g_x; - my = evnt.my - work.g_y; + mx = evnt.mx - (work.g_x + TOOLBAR_URL_MARGIN_LEFT); + my = evnt.my - (work.g_y + TOOLBAR_URL_MARGIN_TOP); /* TODO: reset mouse state of browser window? */ /* select whole text when newly focused, otherwise set caret to end of text */ if( !window_url_widget_has_focus(gw) ) { - tb_url_place_caret( gw, strlen(tb->url.text), true); - tb->url.selection_len = -tb->url.caret_pos; - window_set_focus( gw, URL_WIDGET, (void*)&tb->url ); + // TODO select all ( needs textarea change ) + window_set_focus( gw, URL_WIDGET, (void*)&tb->url ); + textarea_mouse_action( tb->url.textarea, BROWSER_MOUSE_PRESS_1, mx, my ); } else { if( mb & 1 ) { - /* if the button is dragging, place selection: */ - old = tb->url.selection_len; - tb->url.selection_len = (tb->url.scrollx + (mx / tb->url.char_size)) - tb->url.caret_pos; - if(tb->url.caret_pos + tb->url.selection_len > (int)strlen(tb->url.text) ) - tb->url.selection_len = strlen(tb->url.text) - tb->url.caret_pos; - if( old == tb->url.selection_len ) - /* avoid redraw when nothing changed */ - return; + /* TODO: if the button is dragging, report draw event */ } else { - /* TODO: recognize click + shift key */ - tb->url.selection_len = 0; - tb_url_place_caret( gw, tb->url.scrollx + (mx / tb->url.char_size), true); + /* TODO: recognize click + shift key */ + int mstate = BROWSER_MOUSE_PRESS_1; + if( (kstat & (K_LSHIFT|K_RSHIFT)) != 0 ) + mstate = BROWSER_MOUSE_MOD_1; + textarea_mouse_action( tb->url.textarea, BROWSER_MOUSE_PRESS_1, mx, my ); } } - + // TODO: do not send an complete redraw! ApplWrite( _AESapid, WM_REDRAW, gw->root->handle->handle, work.g_x, work.g_y, work.g_w, work.g_h ); +} + +void tb_adjust_size( struct gui_window * gw ) +{ + LGRECT work; + CMP_TOOLBAR t = gw->root->toolbar; + + mt_CompGetLGrect( &app, t->url.comp, WF_WORKXYWH, &work); + work.g_w -= (TOOLBAR_URL_MARGIN_LEFT + TOOLBAR_URL_MARGIN_RIGHT); + /* do not overwrite the black border, because of that, add 1 */ + work.g_h -= (TOOLBAR_URL_MARGIN_TOP + TOOLBAR_URL_MARGIN_BOTTOM+1); + textarea_set_dimensions( t->url.textarea, work.g_w, work.g_h ); + tb_txt_request_redraw( t, 0,0, work.g_w-1, work.g_h-1); } - + static void __CDECL evnt_toolbar_redraw( COMPONENT *c, long buff[8], void *data ) { LGRECT work, clip; @@ -392,9 +364,112 @@ static void __CDECL evnt_toolbar_redraw( COMPONENT *c, long buff[8], void *data pxy[1] = pxy[3] = work.g_y + work.g_h-1 ; pxy[2] = clip.g_x + clip.g_w; v_pline( vdih, 2, (short*)&pxy ); +} + + +static void tb_txt_request_redraw(void *data, int x, int y, int w, int h) +{ + LGRECT work; + if( data == NULL ) + return; + CMP_TOOLBAR t = data; + if( t->url.redraw == false ){ + t->url.redraw = true; + t->url.rdw_area.g_x = x; + t->url.rdw_area.g_y = y; + t->url.rdw_area.g_w = w; + t->url.rdw_area.g_h = h; + } else { + /* merge the redraw area to the new area.: */ + int newx1 = x+w; + int newy1 = y+h; + int oldx1 = t->url.rdw_area.g_x + t->url.rdw_area.g_w; + int oldy1 = t->url.rdw_area.g_y + t->url.rdw_area.g_h; + t->url.rdw_area.g_x = MIN(t->url.rdw_area.g_x, x); + t->url.rdw_area.g_y = MIN(t->url.rdw_area.g_y, y); + t->url.rdw_area.g_w = ( oldx1 > newx1 ) ? + oldx1 - t->url.rdw_area.g_x : newx1 - t->url.rdw_area.g_x; + t->url.rdw_area.g_h = ( oldy1 > newy1 ) ? + oldy1 - t->url.rdw_area.g_y : newy1 - t->url.rdw_area.g_y; + } +} + +void tb_url_redraw( struct gui_window * gw ) +{ + CMP_TOOLBAR t = gw->root->toolbar; + if (t != NULL) { + if( t->url.redraw && ((plotter->flags & PLOT_FLAG_OFFSCREEN) == 0) ) { + + const struct redraw_context ctx = { + .interactive = true, + .plot = &atari_plotters + }; + short todo[4]; + LGRECT work; + + mt_CompGetLGrect(&app, gw->root->toolbar->url.comp, WF_WORKXYWH, &work); + work.g_x += TOOLBAR_URL_MARGIN_RIGHT; + work.g_y += TOOLBAR_URL_MARGIN_LEFT; + work.g_w -= TOOLBAR_URL_MARGIN_RIGHT; + work.g_h -= TOOLBAR_URL_MARGIN_BOTTOM; + + plotter->resize(plotter, work.g_w, work.g_h ); + plotter->move(plotter, work.g_x, work.g_y ); + plotter->lock( plotter ); + + todo[0] = work.g_x; + todo[1] = work.g_y; + todo[2] = todo[0] + work.g_w-1; + todo[3] = todo[1] + work.g_h-1; + vs_clip(plotter->vdi_handle, 1, (short*)&todo ); + + 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 relative coords: */ + todo[0] = todo[0] - work.g_x; + todo[1] = todo[1] - work.g_y; + if( todo[0] < 0 ){ + todo[2] = todo[2] + todo[0]; + todo[0] = 0; + } + if( todo[1] < 0 ){ + todo[3] = todo[3] + todo[1]; + todo[1] = 0; + } + + if (rc_intersect(&t->url.rdw_area,(GRECT *)&todo)) { + struct rect clip = { + .x0 = todo[0], + .y0 = todo[1], + .x1 = todo[0]+todo[2], + .y1 = todo[1]+todo[3] + }; + textarea_redraw( t->url.textarea, 0, 0, &clip, &ctx ); + } + if (wind_get(gw->root->handle->handle, WF_NEXTXYWH, + &todo[0], &todo[1], &todo[2], &todo[3])==0) { + break; + } + } + } else { + plotter->unlock( plotter ); + return; + } + plotter->unlock( plotter ); + vs_clip(plotter->vdi_handle, 0, (short*)&todo); + t->url.redraw = false; + t->url.rdw_area.g_x = 65000; + t->url.rdw_area.g_y = 65000; + t->url.rdw_area.g_w = -1; + t->url.rdw_area.g_h = -1; + } else { + /* just copy stuff from the offscreen buffer */ + } + } } - - + CMP_TOOLBAR tb_create( struct gui_window * gw ) { int i; @@ -404,7 +479,7 @@ CMP_TOOLBAR tb_create( struct gui_window * gw ) if( t == NULL ) return( NULL ); - t->owner = gw; + t->owner = gw; /* create the root component: */ t->comp = (COMPONENT*)mt_CompCreate(&app, CLT_HORIZONTAL, TOOLBAR_HEIGHT, 0); @@ -435,11 +510,13 @@ CMP_TOOLBAR tb_create( struct gui_window * gw ) } /* create the url widget: */ - t->url.char_size = 8; - t->url.text = malloc( 2*URL_WIDGET_BSIZE ); - strcpy( t->url.text, "http://" ); - t->url.allocated = 2*URL_WIDGET_BSIZE; - t->url.scrollx = 0; + t->url.textarea = textarea_create( 300, TOOLBAR_TEXTAREA_HEIGHT, 0, + &font_style_url, tb_txt_request_redraw, + t ); + if( t->url.textarea != NULL ){ + textarea_set_text(t->url.textarea, "http://"); + } + t->url.comp = (COMPONENT*)mt_CompCreate(&app, CLT_HORIZONTAL, TOOLBAR_HEIGHT, 1); mt_CompEvntAttach( &app, t->url.comp, WM_REDRAW, evnt_url_redraw ); mt_CompEvntAttach( &app, t->url.comp, WM_XBUTTON, evnt_url_click ); @@ -475,9 +552,8 @@ void tb_destroy( CMP_TOOLBAR tb ) mt_ObjcFree( &app, (OBJECT*)mt_CompDataSearch(&app, tb->buttons[i].comp, CDT_OBJECT) ); i++; } - free( tb->buttons ); - if( tb->url.text != NULL ) - free( tb->url.text ); + free( tb->buttons ); + textarea_destroy( tb->url.textarea ); mt_CompDelete( &app, tb->comp); free( tb ); } @@ -535,7 +611,6 @@ void tb_update_buttons( struct gui_window * gw ) ((OBJECT*)mt_CompDataSearch(&app, bt->comp, CDT_OBJECT))->ob_state &= ~OS_DISABLED; } mt_CompEvntRedraw( &app, bt->comp ); - } @@ -553,69 +628,21 @@ void tb_url_set( struct gui_window * gw, char * text ) if( gw->browser->attached == false ) return; - struct s_url_widget * url = &gw->root->toolbar->url; - - if( len+1 > url->allocated ) { - newsize = (len / (URL_WIDGET_BSIZE-1))+1; - newtext = realloc( url->text, newsize*URL_WIDGET_BSIZE ); - if(newtext != NULL) { - url->text = newtext; - url->allocated = newsize * URL_WIDGET_BSIZE; - } - } - if( len+1 < url->allocated - URL_WIDGET_BSIZE - && url->allocated - URL_WIDGET_BSIZE > URL_WIDGET_BSIZE*2 ) { - newsize = (len / (URL_WIDGET_BSIZE-1) )+1; - newtext = realloc( url->text, newsize*URL_WIDGET_BSIZE ); - if(newtext != NULL) { - url->text = newtext; - url->allocated = newsize * URL_WIDGET_BSIZE; - } - } - - strncpy((char*)url->text, text, url->allocated-1 ); - url->used = MIN(len+1,url->allocated ); - tb_url_place_caret( gw, 0, true); - url->scrollx = 0; - mt_CompGetLGrect(&app, url->comp, WF_WORKXYWH, &work); - ApplWrite( _AESapid, WM_REDRAW, gw->root->handle->handle, - (short)work.g_x, (short)work.g_y, (short)work.g_w, (short)work.g_h ); -} - - -/* place the caret and adjust scrolling position */ -void tb_url_place_caret( struct gui_window * gw, int steps, bool abs) -{ - LGRECT work; - CMP_TOOLBAR tb = gw->root->toolbar; - assert(tb!=NULL); - mt_CompGetLGrect(&app, tb->url.comp, WF_WORKXYWH, &work); - int ws = (work.g_w / tb->url.char_size)-1; /* widget size in chars */ - if(abs) { - tb->url.caret_pos = steps; - } else { - tb->url.caret_pos = tb->url.caret_pos + steps; - } - if( (int)tb->url.caret_pos > (int)strlen(tb->url.text) ) - tb->url.caret_pos = strlen(tb->url.text); - if( tb->url.caret_pos > tb->url.allocated-2 ) - tb->url.caret_pos = tb->url.allocated-2; - if( tb->url.caret_pos < 0) - tb->url.caret_pos = 0; - - if( tb->url.caret_pos < tb->url.scrollx ) { - /* the caret has moved out of the widget to the left */ - tb->url.scrollx -= ws; - } - if( tb->url.caret_pos > tb->url.scrollx + ws ) { - /* the caret has moved out of the widget to the right */ - if(!abs) - tb->url.scrollx += steps; - else - tb->url.scrollx = tb->url.caret_pos - ws; - } - if(tb->url.scrollx < 0) - tb->url.scrollx = 0; + struct s_url_widget * url = &gw->root->toolbar->url; + + assert( gw != NULL ); + assert( gw->browser != NULL ); + assert( gw->root != NULL ); + assert( gw->browser->bw != NULL ); + + textarea_set_text(url->textarea, text); + + mt_CompGetLGrect( &app, gw->root->toolbar->url.comp, WF_WORKXYWH, &work); + work.g_w -= (TOOLBAR_URL_MARGIN_LEFT + TOOLBAR_URL_MARGIN_RIGHT); + /* do not overwrite the black border, because of that, add 1 */ + work.g_h -= (TOOLBAR_URL_MARGIN_TOP + TOOLBAR_URL_MARGIN_BOTTOM+1); + tb_txt_request_redraw( gw->root->toolbar, 0,0,work.g_w,work.g_h ); + return; } @@ -628,153 +655,30 @@ bool tb_url_input( struct gui_window * gw, short nkc ) CMP_TOOLBAR tb = gw->root->toolbar; assert(tb!=NULL); LGRECT work; - int start = 0; - int i; - char * newtext; - short newsize; - char backup; - bool ctrl = (nkc & NKF_CTRL); - bool shift = (nkc & NKF_SHIFT); - bool alt = (nkc & NKF_ALT); - bool ret = (ctrl) ? false : true; - char code = (nkc & 0xFF); + bool ret = false; - assert( gw != NULL ); + assert( gw != NULL ); + + long ucs4; + long ik = nkc_to_input_key( nkc, &ucs4 ); + + if( ik == 0 ){ + if ( (nkc&0xFF) >= 9 ) { + ret = textarea_keypress( tb->url.textarea, ucs4 ); + } + } + else if( ik == KEY_CR || ik == KEY_NL ){ + char tmp_url[PATH_MAX]; + if( textarea_get_text( tb->url.textarea, tmp_url, PATH_MAX) > 0 ) { + window_set_focus( gw, BROWSER, gw->browser->bw); + browser_window_go(gw->browser->bw, (const char*)&tmp_url, 0, true); + ret = true; + } + } + else { + ret = textarea_keypress( tb->url.textarea, ik ); + } - if( (code == NK_LEFT) && !shift ){ - /* TODO: recognize shift + click */ - tb->url.selection_len = 0; - tb_url_place_caret( gw, -1, false ); - } - else if( (code == NK_RIGHT) && !shift ) { - /* TODO: recognize shift + click */ - tb->url.selection_len = 0; - tb_url_place_caret( gw, +1, false ); - } - else if( (ctrl && code == 'C') ) { - if( tb->url.selection_len != 0 ) { - char * from; - char tmp[abs(tb->url.selection_len)+1]; - int len; - if( tb->url.selection_len < 0 ) { - from = &tb->url.text[tb->url.caret_pos+tb->url.selection_len]; - } else { - from = &tb->url.text[tb->url.caret_pos]; - } - len = MIN( abs(tb->url.selection_len), (int)strlen(from) ) ; - memcpy(&tmp, from, len); - tmp[len] = 0; - int r = scrap_txt_write(&app, (char*)&tmp); - ret = true; - } - } - else if( (ctrl && code == 'V') || code == NK_INS ) { - char * clip = scrap_txt_read( &app ); - if( clip != NULL ) { - size_t l = strlen( clip ); - unsigned int i = 0; - for( i = 0; iurl.selection_len != 0 ) { - if( tb->url.selection_len < 0 ) { - strcpy( - &tb->url.text[tb->url.caret_pos+tb->url.selection_len], - &tb->url.text[tb->url.caret_pos] - ); - tb_url_place_caret( gw, tb->url.selection_len, false ); - } else { - strcpy( - &tb->url.text[tb->url.caret_pos], - &tb->url.text[tb->url.caret_pos+tb->url.selection_len] - ); - } - tb->url.used = strlen( tb->url.text ) + 1; - } else { - if( tb->url.caret_pos < tb->url.used -1) { - strcpy( - &tb->url.text[tb->url.caret_pos+tb->url.selection_len], - &tb->url.text[tb->url.caret_pos+1] - ); - tb->url.used--; - } - } - tb->url.selection_len = 0; - } - else if( code == NK_BS ) { - if( tb->url.caret_pos > 0 && - tb->url.selection_len != 0 ) { - if( tb->url.selection_len < 0 ) { - strcpy(&tb->url.text[tb->url.caret_pos+tb->url.selection_len], &tb->url.text[tb->url.caret_pos]); - tb_url_place_caret( gw, tb->url.selection_len, false ); - } else { - strcpy(&tb->url.text[tb->url.caret_pos], &tb->url.text[tb->url.caret_pos+tb->url.selection_len]); - } - tb->url.used = strlen( tb->url.text ) + 1; - } else { - tb->url.text[tb->url.caret_pos-1] = 0; - tb->url.used--; - strcat(tb->url.text, &tb->url.text[tb->url.caret_pos]); - tb_url_place_caret( gw , -1, false ); - } - tb->url.selection_len = 0; - } - else if( code == NK_ESC ) { - tb->url.text[0] = 0; - tb->url.scrollx = 0; - tb->url.used = 1; - tb_url_place_caret( gw, 0, true ); - } - else if( code == NK_CLRHOME ) { - tb_url_place_caret( gw, 0, true ); - } - else if( code == NK_M_END ) { - tb_url_place_caret( gw, - strlen((char*)&tb->url.text)-1, - true - ); - } - else if( code == NK_ENTER || code == NK_RET ) { - tb_url_place_caret( gw, 0, true ); - window_set_focus( gw, BROWSER, gw->browser->bw); - browser_window_go(gw->browser->bw, (const char*)tb->url.text, 0, true); - } - else if( code > 30 ) { - if( tb->url.used+1 > tb->url.allocated ){ - newsize = ( (tb->url.used+1) / (URL_WIDGET_BSIZE-1))+1; - newtext = realloc(tb->url.text, newsize*URL_WIDGET_BSIZE ); - if(newtext) { - tb->url.text = newtext; - tb->url.allocated = newsize * URL_WIDGET_BSIZE; - } - } - i = tb->url.caret_pos; - backup = tb->url.text[tb->url.caret_pos]; - while( i < tb->url.allocated - 1) { - tb->url.text[i] = code; - if( tb->url.text[i] == (char)0 ) - break; - code = backup; - i++; - backup = tb->url.text[i]; - } - tb->url.used++; - tb->url.text[tb->url.allocated-1] = 0; - tb_url_place_caret( gw, +1, false ); - tb->url.selection_len = 0; - } else { - ret = false; - } - if(tb->url.used < 1) - tb->url.used = 1; /* at least one byte (0) is used */ - mt_CompGetLGrect(&app, tb->url.comp, WF_WORKXYWH, &work); - ApplWrite( _AESapid, WM_REDRAW, gw->root->handle->handle, - work.g_x, work.g_y, work.g_w, work.g_h ); return( ret ); } diff --git a/atari/toolbar.h b/atari/toolbar.h index 851609bc4..efd8e33ce 100755 --- a/atari/toolbar.h +++ b/atari/toolbar.h @@ -17,7 +17,11 @@ */ #ifndef NS_ATARI_TOOLBAR_H -#define NS_ATARI_TOOLBAR_H +#define NS_ATARI_TOOLBAR_H + +#include "desktop/textarea.h" +#include "desktop/textinput.h" +#include "atari/browser.h" #define TB_BUTTON_WIDTH 32 #define TB_BUTTON_HEIGHT 21 /* includes 1px 3d effect */ @@ -27,13 +31,13 @@ #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 - + +#define TOOLBAR_URL_TEXT_SIZE_PT 14 +#define TOOLBAR_TEXTAREA_HEIGHT 19 +#define TOOLBAR_URL_MARGIN_LEFT 2 +#define TOOLBAR_URL_MARGIN_RIGHT 2 +#define TOOLBAR_URL_MARGIN_TOP 2 +#define TOOLBAR_URL_MARGIN_BOTTOM 2 struct s_tb_button { short rsc_id; @@ -44,15 +48,10 @@ struct s_tb_button 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 text_area *textarea; + COMPONENT * comp; + GRECT rdw_area; }; struct s_throbber_widget @@ -62,14 +61,15 @@ struct s_throbber_widget short max_index; bool running; }; - + struct s_toolbar { COMPONENT * comp; - struct gui_window * owner; + struct gui_window * owner; struct s_url_widget url; - struct s_throbber_widget throbber; - GRECT btdim; /* size & location of buttons */ + struct s_throbber_widget throbber; + GRECT btdim; + /* size & location of buttons: */ struct s_tb_button * buttons; int btcnt; }; @@ -81,7 +81,9 @@ void tb_destroy( CMP_TOOLBAR tb ); static void __CDECL evnt_toolbar_redraw( COMPONENT *c, long buff[8], void *data ); //static void __CDECL evnt_toolbar_mbutton( COMPONENT *c, long buff[8], void *data ); static void __CDECL evnt_toolbar_resize( COMPONENT *c, long buff[8], void *data ); - + +/* recalculate size/position of nested controls within the toolbar: */ +void tb_adjust_size( struct gui_window * gw ); /* report click to toolbar, relative coords : */ void tb_click( struct gui_window * gw, short mx, short my, short mb, short kstat ); void tb_back_click( struct gui_window * gw ); @@ -96,10 +98,10 @@ void tb_update_buttons( struct gui_window * gw ); void tb_url_click( struct gui_window * gw, short mx, short my, short mb, short kstat ); /* handle keybd event while url widget has focus:*/ bool tb_url_input( struct gui_window * gw, short keycode ); -/* place the caret and adjust scrolling position: */ -void tb_url_place_caret( struct gui_window * gw, int steps, bool abs); /* set the url: */ -void tb_url_set( struct gui_window * gw, char * text ); +void tb_url_set( struct gui_window * gw, char * text ); +/* perform redraw of invalidated url textinput areas: */ +void tb_url_redraw( struct gui_window * gw ); struct gui_window * tb_gui_window( CMP_TOOLBAR tb ); diff --git a/atari/treeview.c b/atari/treeview.c index 07fe395fb..1c1c9b9ab 100755 --- a/atari/treeview.c +++ b/atari/treeview.c @@ -104,8 +104,10 @@ static void __CDECL evnt_tv_redraw( WINDOW *win, short buff[8], void * data ) clip.g_y = 0; } if( clip.g_h > 0 && clip.g_w > 0 ) { - atari_treeview_request_redraw( win->xpos*win->w_u + clip.g_x, win->ypos*win->h_u + clip.g_y, - clip.g_w, clip.g_h, tv + atari_treeview_request_redraw( + win->xpos*win->w_u + clip.g_x, + win->ypos*win->h_u + clip.g_y, + clip.g_w, clip.g_h, tv ); } } @@ -355,7 +357,7 @@ void atari_treeview_redraw( NSTREEVIEW tv) */ void atari_treeview_request_redraw(int x, int y, int w, int h, void *pw) { - if (pw != NULL) { + if ( pw != NULL ) { NSTREEVIEW tv = (NSTREEVIEW) pw; if( tv->redraw == false ){ tv->redraw = true; -- cgit v1.2.3