Atari frontend (credit: Ole Loots)

svn path=/trunk/netsurf/; revision=11218
This commit is contained in:
John Mark Bell 2011-01-05 21:02:22 +00:00
parent 9422e6dad0
commit 124e4cd788
63 changed files with 11211 additions and 3 deletions

View File

@ -82,7 +82,7 @@ else
endif
ifeq ($(HOST),mint)
ifeq ($(TARGET),)
TARGET := framebuffer
TARGET := atari
endif
endif
@ -102,7 +102,9 @@ ifneq ($(TARGET),riscos)
ifneq ($(TARGET),amiga)
ifneq ($(TARGET),framebuffer)
ifneq ($(TARGET),windows)
$(error Unknown TARGET "$(TARGET)", should either be "riscos", "gtk", "beos", "amiga", "framebuffer" or "windows")
ifneq ($(TARGET),atari)
$(error Unknown TARGET "$(TARGET)", should either be "riscos", "gtk", "beos", "amiga", "framebuffer", "windows" or "atari")
endif
endif
endif
endif
@ -203,7 +205,7 @@ else
PKG_CONFIG := PKG_CONFIG_LIBDIR="$(GCCSDK_INSTALL_ENV)/lib/pkgconfig" pkg-config
endif
else
# Building for GTK, Framebuffer
# Building for GTK, Framebuffer, Atari
PKG_CONFIG := pkg-config
endif
endif

View File

@ -306,6 +306,45 @@ ifeq ($(TARGET),windows)
endif
# ----------------------------------------------------------------------------
# Atari-specific options
# ----------------------------------------------------------------------------
ifeq ($(TARGET),atari)
# Force using glibc internal iconv implementation instead of external libiconv
# Valid options: YES, NO
NETSURF_USE_LIBICONV_PLUG := NO
# Enable NetSurf's use of librosprite for displaying RISC OS Sprites
# Valid options: YES, NO, AUTO
NETSURF_USE_ROSPRITE := NO
# Enable NetSurf's use of libwebp/libvpx for displaying WebPs
# Valid options: YES, NO
NETSURF_USE_WEBP := NO
# Enable NetSurf's use of librsvg in conjunction with Cairo to display SVGs
# Valid options: YES, NO, AUTO
NETSURF_USE_RSVG := AUTO
# Enable NetSurf's use of libsvgtiny for displaying SVGs
# Valid options: YES, NO, AUTO
NETSURF_USE_NSSVG := AUTO
NETSURF_USE_MNG := NO
NETSURF_ATARI_USE_FREETYPE := YES
# Optimisation levels
CFLAGS += -m68000 -O2 -Wuninitialized -DNO_IPV6
WARNFLAGS = -W -Wundef -Wpointer-arith \
-Wcast-align -Wwrite-strings -Wstrict-prototypes \
-Wmissing-prototypes -Wmissing-declarations -Wredundant-decls \
-Wnested-externs -Wl,-t
endif
# Include any local configuration
-include Makefile.config

50
atari/Makefile.target Normal file
View File

@ -0,0 +1,50 @@
# ----------------------------------------------------------------------------
# Atari target setup
# ----------------------------------------------------------------------------
$(eval $(call feature_enabled,MNG,-DWITH_MNG,-lmng,PNG/MNG/JNG (libmng)))
$(eval $(call feature_enabled,PNG,-DWITH_PNG,-lpng,PNG (libpng) ))
CFLAGS += -I/usr/GEM/include
LDFLAGS += -L/usr/GEM/lib -lcflib
CFLAGS += -DATARI_USE_FREETYPE $(shell freetype-config --cflags)
LDFLAGS += $(shell freetype-config --libs)
# define additional CFLAGS and LDFLAGS requirements for pkg-configed libs here
NETSURF_FEATURE_RSVG_CFLAGS := -DWITH_RSVG
NETSURF_FEATURE_HUBBUB_CFLAGS := -DWITH_HUBBUB
NETSURF_FEATURE_BMP_CFLAGS := -DWITH_BMP
NETSURF_FEATURE_GIF_CFLAGS := -DWITH_GIF
$(eval $(call pkg_config_find_and_add,BMP,libnsbmp,BMP))
$(eval $(call pkg_config_find_and_add,GIF,libnsgif,GIF))
CFLAGS += -std=c99 -I. -Dsmall $(WARNFLAGS) -Dnsatari \
-D_BSD_SOURCE \
-D_XOPEN_SOURCE=600 \
-D_POSIX_C_SOURCE=200112L \
$(shell $(PKG_CONFIG) --cflags libhubbub libcss openssl) \
$(shell xml2-config --cflags) \
$(shell curl-config --cflags)
LDFLAGS += $(shell curl-config --libs)
LDFLAGS += $(shell $(PKG_CONFIG) --libs libhubbub openssl libcss)
LDFLAGS += -L/usr/lib/ -lxml2 -lz -lHermes -liconv -L/usr/lib -lwindom -lldg -lgem -lm
# S_ATARI are sources purely for the Atari FreeMiNT build
S_ATARI := gui.c findfile.c filetype.c misc.c bitmap.c schedule.c \
download.c thumbnail.c login.c verify_ssl.c treeview.c hotlist.c history.c\
font.c \
plot.c plot/plotter.c plot/plotter_vdi.c plot/eddi.s \
plot/font_vdi.c plot/font_freetype.c \
browser_win.c toolbar.c statusbar.c browser.c \
global_evnt.c
S_ATARI := $(addprefix atari/,$(S_ATARI))
SOURCES := $(S_COMMON) $(S_IMAGE) $(S_BROWSER) $(S_ATARI)
EXETARGET := ns$(SUBTARGET).prg

384
atari/bitmap.c Normal file
View File

@ -0,0 +1,384 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <inttypes.h>
#include <sys/types.h>
#include <string.h>
#include <windom.h>
#include "assert.h"
#include "image/bitmap.h"
#include "atari/bitmap.h"
#include "atari/plot.h"
#include "utils/log.h"
/**
* Create a bitmap.
*
* \param width width of image in pixels
* \param height width of image in pixels
* \param state a flag word indicating the initial state
* \return an opaque struct bitmap, or NULL on memory exhaustion
*/
void *bitmap_create(int w, int h, unsigned int state)
{
return bitmap_create_ex( w, h, NS_BMP_DEFAULT_BPP, w * NS_BMP_DEFAULT_BPP, state, NULL );
}
/**
* Create a bitmap.
*
* \param w width of image in pixels
* \param h height of image in pixels
* \param bpp number of BYTES per pixel
* \param rowstride linewidth in bytes
* \param state a flag word indicating the initial state
* \param pixdata NULL or an memory address to use as the bitmap pixdata
* \return an opaque struct bitmap, or NULL on memory exhaustion
*/
void * bitmap_create_ex( int w, int h, short bpp, int rowstride, unsigned int state, void * pixdata )
{
struct bitmap * bitmap;
LOG(("width %d, height %d, state %u",w, h, state ));
if( rowstride == 0) {
rowstride = bpp * w;
}
assert( rowstride >= w * bpp );
bitmap = calloc(1 , sizeof(struct bitmap) );
if (bitmap) {
if( pixdata == NULL) {
bitmap->pixdata = calloc(1, (rowstride * h)+128);
}
else {
bitmap->pixdata = pixdata;
}
if (bitmap->pixdata != NULL) {
bitmap->width = w;
bitmap->height = h;
bitmap->opaque = false;
bitmap->bpp = bpp;
bitmap->resized = NULL;
bitmap->rowstride = rowstride;
} else {
free(bitmap);
bitmap=NULL;
LOG(("Out of memory!"));
}
}
LOG(("bitmap %p", bitmap));
return bitmap;
}
void * bitmap_realloc( int w, int h, short bpp, int rowstride, unsigned int state, void * bmp )
{
struct bitmap * bitmap = bmp;
int newsize = rowstride * h;
if( bitmap == NULL ) {
return( NULL );
}
if( bitmap->pixdata == NULL ) {
assert( 1 == 0 );
/* add some buffer for bad code */
bitmap->pixdata = malloc( newsize + 128 );
} else {
int oldsize = bitmap->rowstride * bitmap->height;
bool doalloc = ( state == BITMAP_GROW) ? (newsize > oldsize) : (newsize != oldsize);
if( newsize > oldsize )
assert( doalloc == true );
if( doalloc ) {
bitmap->pixdata = realloc( bitmap->pixdata, newsize + 128 );
if( bitmap->pixdata == NULL )
return( NULL );
}
}
bitmap->width = w;
bitmap->height = h;
bitmap->opaque = false;
bitmap->bpp = bpp;
bitmap->resized = NULL;
bitmap->rowstride = rowstride;
bitmap_modified( bitmap );
return( bitmap );
}
void bitmap_to_mfdb(void * bitmap, MFDB * out)
{
struct bitmap * bm;
uint32_t dstsize;
uint8_t * tmp;
size_t dststride, oldstride;
bm = bitmap;
assert( out != NULL );
assert( bm->pixdata != NULL );
oldstride = bitmap_get_rowstride( bm );
dststride = MFDB_STRIDE( bm->width );
if( oldstride != dststride * bm->bpp )
{
/* we need to convert the img to new rowstride */
tmp = bm->pixdata;
bm->pixdata = calloc(1, dststride * bm->bpp * bm->height );
if( tmp == NULL ){
bm->pixdata = tmp;
out->fd_addr = NULL;
return;
}
bm->rowstride = dststride * bm->bpp;
int i=0;
for( i=0; i<bm->height; i++) {
memcpy( (bm->pixdata+i*bm->rowstride), (tmp + i*oldstride), oldstride);
}
free( tmp );
}
out->fd_w = dststride;
out->fd_h = bm->height;
out->fd_wdwidth = dststride >> 4;
out->fd_addr = bm->pixdata;
out->fd_stand = 0;
out->fd_nplanes = (short)bm->bpp;
out->fd_r1 = out->fd_r2 = out->fd_r3 = 0;
}
/**
* Return a pointer to the pixel data in a bitmap.
*
* \param bitmap a bitmap, as returned by bitmap_create()
* \return pointer to the pixel buffer
*
* The pixel data is packed as BITMAP_FORMAT, possibly with padding at the end
* of rows. The width of a row in bytes is given by bitmap_get_rowstride().
*/
unsigned char *bitmap_get_buffer(void *bitmap)
{
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
LOG(("NULL bitmap!"));
return NULL;
}
return bm->pixdata;
}
size_t bitmap_buffer_size( void * bitmap )
{
struct bitmap * bm = bitmap;
if( bm == NULL )
return 0;
return( bm->rowstride * bm->height );
}
/**
* Find the width of a pixel row in bytes.
*
* \param bitmap a bitmap, as returned by bitmap_create()
* \return width of a pixel row in the bitmap
*/
size_t bitmap_get_rowstride(void *bitmap)
{
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
LOG(("NULL bitmap!"));
return 0;
}
return bm->rowstride;
}
/**
* Free a bitmap.
*
* \param bitmap a bitmap, as returned by bitmap_create()
*/
void bitmap_destroy(void *bitmap)
{
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
LOG(("NULL bitmap!"));
return;
}
if( bm->resized != NULL ) {
bitmap_destroy(bm->resized);
}
free(bm->pixdata);
free(bm);
}
/**
* Save a bitmap in the platform's native format.
*
* \param bitmap a bitmap, as returned by bitmap_create()
* \param path pathname for file
* \return true on success, false on error and error reported
*/
bool bitmap_save(void *bitmap, const char *path, unsigned flags)
{
return true;
}
/**
* The bitmap image has changed, so flush any persistant cache.
*
* \param bitmap a bitmap, as returned by bitmap_create()
*/
void bitmap_modified(void *bitmap)
{
struct bitmap *bm = bitmap;
if( bm->resized != NULL ) {
bitmap_destroy( bm->resized );
bm->resized = NULL;
}
}
/**
* The bitmap image can be suspended.
*
* \param bitmap a bitmap, as returned by bitmap_create()
* \param private_word a private word to be returned later
* \param suspend the function to be called upon suspension
* \param resume the function to be called when resuming
*/
void bitmap_set_suspendable(void *bitmap, void *private_word,
void (*invalidate)(void *bitmap, void *private_word)) {
}
/**
* Sets whether a bitmap should be plotted opaque
*
* \param bitmap a bitmap, as returned by bitmap_create()
* \param opaque whether the bitmap should be plotted opaque
*/
void bitmap_set_opaque(void *bitmap, bool opaque)
{
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
LOG(("NULL bitmap!"));
return;
}
LOG(("setting bitmap %p to %s", bm, opaque?"opaque":"transparent"));
bm->opaque = opaque;
}
/**
* Tests whether a bitmap has an opaque alpha channel
*
* \param bitmap a bitmap, as returned by bitmap_create()
* \return whether the bitmap is opaque
*/
bool bitmap_test_opaque(void *bitmap)
{
int tst;
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
LOG(("NULL bitmap!"));
return false;
}
tst = bm->width * bm->height;
while (tst-- > 0) {
if (bm->pixdata[(tst << 2) + 3] != 0xff) {
LOG(("bitmap %p has transparency",bm));
return false;
}
}
LOG(("bitmap %p is opaque", bm));
return true;
}
/**
* Gets whether a bitmap should be plotted opaque
*
* \param bitmap a bitmap, as returned by bitmap_create()
*/
bool bitmap_get_opaque(void *bitmap)
{
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
LOG(("NULL bitmap!"));
return false;
}
return bm->opaque;
}
int bitmap_get_width(void *bitmap)
{
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
LOG(("NULL bitmap!"));
return 0;
}
return(bm->width);
}
int bitmap_get_height(void *bitmap)
{
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
LOG(("NULL bitmap!"));
return 0;
}
return(bm->height);
}
size_t bitmap_get_bpp(void *bitmap)
{
struct bitmap *bm = bitmap;
return bm->bpp;
}
/*
* Local Variables:
* c-basic-offset:8
* End:
*/

44
atari/bitmap.h Normal file
View File

@ -0,0 +1,44 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NS_ATARI_BITMAP_H
#define NS_ATARI_BITMAP_H
#define BITMAP_SHRINK 0
#define BITMAP_GROW 0x01
struct bitmap {
int width;
int height;
uint8_t *pixdata;
bool opaque;
short bpp; /* number of BYTES! per pixel */
size_t rowstride;
struct bitmap * resized;
};
#define NS_BMP_DEFAULT_BPP 4
/* calculate MFDB compatible rowstride (in number of pixels!) */
#define MFDB_STRIDE( w ) (((w & 15) != 0) ? (w | 15)+1 : w)
void * bitmap_create_ex( int w, int h, short bpp, int rowstride, unsigned int state, void * pixdata );
void bitmap_to_mfdb(void * bitmap, MFDB * out);
void * bitmap_realloc( int w, int h, short bpp, int rowstride, unsigned int state, void * bmp );
size_t bitmap_buffer_size( void * bitmap ) ;
#endif

944
atari/browser.c Normal file
View File

@ -0,0 +1,944 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>
#include <assert.h>
#include <windom.h>
#include <cflib.h>
#include "desktop/gui.h"
#include "desktop/netsurf.h"
#include "desktop/browser.h"
#include "desktop/mouse.h"
#include "desktop/textinput.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "atari/gui.h"
#include "atari/browser_win.h"
#include "atari/misc.h"
#include "atari/global_evnt.h"
#include "atari/browser_win.h"
#include "atari/res/netsurf.rsh"
#include "atari/browser.h"
#include "atari/plot/plotter.h"
#include "atari/plot.h"
#include "atari/font.h"
extern browser_mouse_state bmstate;
extern GEM_PLOTTER plotter;
extern struct gui_window *input_window;
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 );
static bool frameinit = true;
/* create an browser component */
struct s_browser * browser_create( struct gui_window * gw,
struct browser_window *bw,
struct browser_window * clone,
enum browser_type type,
int lt, int w, int flex )
{
LGRECT cwork;
COMPONENT * scrollv, * scrollh, * drawable;
if( frameinit ) {
mt_FrameInit( &app );
frameinit = false;
}
CMP_BROWSER bnew = (CMP_BROWSER)malloc( sizeof(struct s_browser) );
if( bnew )
{
memset(bnew, 0, sizeof(struct s_browser) );
bnew->type = type;
bnew->bw = bw;
bnew->attached = false;
if(clone)
bw->scale = clone->scale;
else
bw->scale = 1;
bnew->compwin = mt_WindCreate( &app, VSLIDE|HSLIDE, 40, 40, app.w, app.h);
bnew->compwin->w_u = 1;
bnew->compwin->h_u = 1;
/* needs to be adjusted when content width is known: */
bnew->compwin->ypos_max = w;
bnew->compwin->xpos_max = w;
mt_WindSlider( &app, bnew->compwin, HSLIDER|VSLIDER);
bnew->comp = (COMPONENT*)comp_widget_create( (void*)&app, (WINDOW*)bnew->compwin, 100, 1 );
if( bnew->comp == NULL ) {
free(bnew);
return(NULL);
}
mt_EvntDataAdd( &app, bnew->compwin, WM_XBUTTON,
browser_evnt_mbutton, (void*)gw, EV_BOT );
mt_CompEvntDataAttach( &app, bnew->comp, WM_REDRAW,
browser_evnt_redraw, (void*)gw );
mt_EvntDataAttach( &app, bnew->compwin , WM_REDRAW, browser_evnt_redraw_x, NULL );
mt_EvntDataAttach( &app, bnew->compwin, WM_SLIDEXY,
browser_evnt_slider, gw );
mt_EvntDataAttach( &app, bnew->compwin, WM_ARROWED,
browser_evnt_arrowed, gw );
mt_CompEvntDataAttach( &app, bnew->comp, WM_DESTROY,
browser_evnt_destroy, (void*)bnew );
/* just stub, as an reminder: */
mt_EvntDataAttach( &app, bnew->compwin, WM_DESTROY,
browser_evnt_wdestroy, (void*)bnew );
mt_CompDataAttach( &app, bnew->comp, CDT_OWNER, gw );
}
return( bnew );
}
bool browser_destroy( struct s_browser * b )
{
short type = BT_ROOT;
LGRECT restore;
/* only free the components if it is an root browser,
this should delete all attached COMPONENTS...
*/
LOG(("%s (%s)\n", b->bw->name, (b->type == BT_ROOT) ? "ROOT" : "FRAME"));
assert( b != NULL );
assert( b->comp != NULL );
assert( b->bw != NULL );
struct gui_window * rootgw = browser_find_root( b->bw->window );
if( b->type == BT_ROOT ) {
} else if( BT_FRAME ){
type = BT_FRAME;
} else {
assert( 1 == 0 );
}
if( b->compwin != NULL ){
COMPONENT * old = b->comp;
WINDOW * oldwin = b->compwin;
b->comp = NULL;
b->compwin = NULL;
/* Im not sure if this is the right thing to do (after compdelete above,... */
/* listRemove should be used when we just remove an frame... */
/* (I encountered spurious events when not doing that...) */
/* listRemove( (LINKABLE*) oldwin ); */
/* listRemove( (LINKABLE*) old ); */
WindDelete( oldwin );
mt_CompDelete(&app, old );
}
if( type == BT_FRAME ) {
/* TODO: restore the remaining frameset (rebuild???) */
}
return( true );
}
bool browser_attach_frame( struct gui_window * container, struct gui_window * frame )
{
struct browser_window * cbw = container->browser->bw;
int lt = CLT_STACK;
if (cbw->rows >= cbw->cols)
lt = CLT_VERTICAL;
else
lt = CLT_HORIZONTAL;
/* todo: if first frame, destroy compwin, create browser frame with old component interface :/ */
mt_CompAttach( &app, container->browser->comp, frame->browser->comp );
container->browser->comp->type = lt;
browser_update_rects( container );
container->browser->attached = true;
/*browser_update_rects( frame );
LGRECT brect;
browser_get_rect( frame, BR_CONTENT, &brect );
*/
}
/* find the root of an frame ( or just return gw if is already the root) */
struct gui_window * browser_find_root( struct gui_window * gw )
{
if( gw->parent == NULL )
return( gw );
struct gui_window * g;
for( g=window_list; g; g=g->next){
if( g->root == gw->root && g->parent == NULL )
return( g );
}
return( NULL );
}
void browser_get_rect( struct gui_window * gw, enum browser_rect type, LGRECT * out)
{
GRECT work;
assert( out != NULL);
int slider_v_w = 20;
int slider_v_h = 22;
int slider_h_w = 20;
int slider_h_h = 22;
WindGetGrect( gw->browser->compwin, WF_WORKXYWH, &work);
if( type == BR_CONTENT ){
out->g_w = work.g_w;
out->g_h = work.g_h;
out->g_x = work.g_x;
out->g_y = work.g_y;
return;
}
LGRECT cur;
mt_CompGetLGrect(&app, gw->browser->comp, WF_WORKXYWH, &cur);
if( type == BR_HSLIDER ){
out->g_x = cur.g_x;
out->g_y = cur.g_y + work.g_h;
out->g_h = cur.g_h - work.g_h;
out->g_w = cur.g_w;
}
if( type == BR_VSLIDER ){
out->g_x = cur.g_x + work.g_w;
out->g_y = cur.g_y;
out->g_w = cur.g_w - work.g_w;
out->g_h = work.g_h;
}
}
/* Report an resize to the COMPONENT interface */
void browser_update_rects(struct gui_window * gw )
{
short buff[8];
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);
}
void browser_set_content_size(struct gui_window * gw, int w, int h)
{
CMP_BROWSER b = gw->browser;
b->compwin->ypos = 0;
b->compwin->xpos = 0;
b->compwin->ypos_max = h;
b->compwin->xpos_max = w;
/* TODO: instead of zeroin, recalculate scroll? */
browser_scroll(gw, WA_LFLINE, 0, true );
browser_scroll(gw, WA_UPLINE, 0, true );
/* force update of scrollbars: */
b->scroll.required = true;
}
static void __CDECL browser_evnt_wdestroy( WINDOW * c, short buff[8], void * data)
{
struct s_browser * b = (struct s_browser*)data;
LOG((""));
}
static void __CDECL browser_evnt_destroy( COMPONENT * c, long buff[8], void * data)
{
struct s_browser * b = (struct s_browser*)data;
struct gui_window * gw = b->bw->window;
LOG(("%s: %s (%s)\n", __FUNCTION__ ,gw->browser->bw->name, ( gw->browser->type == BT_FRAME) ? "FRAME" : "NOFRAME"));
assert( b != NULL );
assert( gw != NULL );
/* TODO: inspect why this assert fails with frames / iframes
/* this should have been happened alrdy */
/* assert( b->comp == NULL ); */
free( b );
gw->browser = NULL;
}
static void __CDECL browser_evnt_arrowed( WINDOW *win, short buff[8], void * data)
{
bool abs = false;
int value = BROWSER_SCROLL_SVAL;
struct gui_window * gw = data;
LGRECT cwork;
browser_get_rect( gw, BR_CONTENT, &cwork );
switch( buff[4] ) {
case WA_UPPAGE:
case WA_DNPAGE:
value = cwork.g_h;
break;
case WA_LFPAGE:
case WA_RTPAGE:
value = cwork.g_w;
break;
default:
break;
}
browser_scroll( gw, buff[4], value, abs );
}
void __CDECL browser_evnt_slider( WINDOW *win, short buff[8], void * data)
{
int dx = buff[4];
int dy = buff[5];
struct gui_window * gw = data;
GRECT work, screen;
if (!dx && !dy) return;
/* update the sliders _before_ we call redraw (which might depend on the slider possitions) */
mt_WindSlider( &app, win, (dx?HSLIDER:0) | (dy?VSLIDER:0) );
if( dy > 0 )
browser_scroll( gw, WA_DNPAGE, abs(dy), false );
else if ( dy < 0)
browser_scroll( gw, WA_UPPAGE, abs(dy), false );
if( dx > 0 )
browser_scroll( gw, WA_RTPAGE, abs(dx), false );
else if( dx < 0 )
browser_scroll( gw, WA_LFPAGE, abs(dx), false );
}
static void __CDECL browser_evnt_mbutton( WINDOW * c, short buff[8], void * data)
{
long lbuff[8];
short mx,my;
browser_mouse_state bms;
LGRECT cwork;
struct gui_window * gw = data;
input_window = gw;
window_set_focus( gw, BROWSER, (void*)gw->browser );
browser_get_rect( gw, BR_CONTENT, &cwork );
SBUF8_TO_LBUF8(buff, lbuff)
bms = global_track_evnt_mbutton( gw->root->handle, lbuff, data );
mx = evnt.mx - cwork.g_x + gw->browser->scroll.current.x;
my = evnt.my - cwork.g_y + gw->browser->scroll.current.y;
LOG(("mevent within %s at %d / %d", gw->browser->bw->name, mx, my ));
if( bms & BROWSER_MOUSE_DRAG_1) {
browser_window_mouse_track(gw->browser->bw, BROWSER_MOUSE_DRAG_1, mx, my );
bmstate |= BROWSER_MOUSE_HOLDING_1 | BROWSER_MOUSE_DRAG_ON;
LOG(("drag within %s at %d / %d", gw->browser->bw->name, mx, my ));
}
if( bms & BROWSER_MOUSE_DRAG_2) {
browser_window_mouse_track(gw->browser->bw, BROWSER_MOUSE_DRAG_2, mx, my );
bmstate |= BROWSER_MOUSE_HOLDING_2 | BROWSER_MOUSE_DRAG_ON;
LOG(("drag within %s at %d / %d", gw->browser->bw->name, mx, my ));
}
if( bms & BROWSER_MOUSE_CLICK_1) {
window_set_focus( gw, BROWSER, (void*)gw->browser );
browser_window_mouse_click(gw->browser->bw,BROWSER_MOUSE_PRESS_1,mx,my);
browser_window_mouse_click(gw->browser->bw,BROWSER_MOUSE_CLICK_1,mx,my);
LOG(("Click within %s at %d / %d", gw->browser->bw->name, mx, my ));
}
if( bms & BROWSER_MOUSE_CLICK_2) {
window_set_focus( gw, BROWSER, (void*)gw->browser );
browser_window_mouse_click(gw->browser->bw,BROWSER_MOUSE_PRESS_2,mx,my);
browser_window_mouse_click(gw->browser->bw,BROWSER_MOUSE_CLICK_2,mx,my);
LOG(("Click within %s at %d / %d", gw->browser->bw->name, mx, my ));
}
}
void browser_scroll( struct gui_window * gw, short mode, int value, bool abs )
{
LGRECT work;
int max_y_scroll;
int max_x_scroll;
int oldx = gw->browser->scroll.current.x;
int oldy = gw->browser->scroll.current.y;
struct s_browser * b = gw->browser;
LOG((""));
if( gw->browser->bw->current_content == NULL ) {
assert( 1 == 0);
return;
}
browser_get_rect( gw, BR_CONTENT, &work);
max_y_scroll = (content_get_height( b->bw->current_content ) - work.g_h );
max_x_scroll = (content_get_width( b->bw->current_content ) - work.g_w);
switch( mode ) {
case WA_UPPAGE:
case WA_UPLINE:
if( abs == false )
b->scroll.requested.y -= value;
else
b->scroll.requested.y = value - b->scroll.current.y;
break;
case WA_DNPAGE:
case WA_DNLINE:
if( abs == false )
b->scroll.requested.y += value;
else
b->scroll.requested.y = value - b->scroll.current.y;
break;
case WA_LFPAGE:
case WA_LFLINE:
if( abs == false )
b->scroll.requested.x -= value;
else
b->scroll.requested.x = value - b->scroll.current.x;
break;
case WA_RTPAGE:
case WA_RTLINE:
if( abs == false )
b->scroll.requested.x += value;
else
b->scroll.requested.x = value - b->scroll.current.x;
break;
default: break;
}
if( b->scroll.current.y + b->scroll.requested.y < 0 ) {
b->scroll.requested.y = -b->scroll.current.y;
}
if( b->scroll.current.y + b->scroll.requested.y > max_y_scroll ) {
b->scroll.requested.y = max_y_scroll - b->scroll.current.y;
}
if( b->scroll.current.x + b->scroll.requested.x < 0 ) {
b->scroll.requested.x = -b->scroll.current.x;
}
if( b->scroll.current.x + b->scroll.requested.x > max_x_scroll ) {
b->scroll.requested.x = max_x_scroll - b->scroll.current.x;
}
if( oldy != b->scroll.current.y + b->scroll.requested.y ||
oldx != b->scroll.current.x + b->scroll.requested.x ) {
b->scroll.required = true;
}
}
/*
perform the requested scrolling.
gw -> the browser window to act upon.
bwrect -> the dimensions of the browser, so that this function
doesn't need to get it.
*/
static void browser_process_scroll( struct gui_window * gw, LGRECT bwrect )
{
struct s_browser * b = gw->browser;
GRECT src;
GRECT dst;
short h,w;
h = (short) abs( b->scroll.requested.y );
w = (short) abs( b->scroll.requested.x );
/* if the request exceeds the browser size, redraw the whole area */
if ( b->scroll.requested.y > bwrect.g_h || b->scroll.requested.y < -bwrect.g_h ||
b->scroll.requested.x > bwrect.g_w || b->scroll.requested.x < -bwrect.g_w ) {
b->scroll.current.y += b->scroll.requested.y;
b->scroll.current.x += b->scroll.requested.x;
browser_schedule_redraw( gw, 0, 0, bwrect.g_w, bwrect.g_h);
/* don't scroll again: */
b->scroll.requested.y = 0;
b->scroll.requested.x = 0;
}
if( b->scroll.requested.y < 0 ) {
/* scroll up */
src.g_x = 0;
src.g_y = 0;
src.g_w = bwrect.g_w;
src.g_h = bwrect.g_h - h;
dst.g_x = 0;
dst.g_y = h;
dst.g_w = src.g_w;
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 ) ;
}
if( b->scroll.requested.y > 0 ) {
/* scroll down */
src.g_x = 0;
src.g_y = h;
src.g_w = bwrect.g_w;
src.g_h = bwrect.g_h - h;
dst.g_x = 0;
dst.g_y = 0;
dst.g_w = bwrect.g_w;
dst.g_h = bwrect.g_h - h;
plotter->copy_rect( plotter, src, dst );
b->scroll.current.y += b->scroll.requested.y;
browser_schedule_redraw( gw, 0, bwrect.g_h - h, bwrect.g_w, bwrect.g_h );
}
if( b->scroll.requested.x < 0 ) {
/* scroll to the left */
src.g_x = 0;
src.g_y = 0;
src.g_w = bwrect.g_w - w;
src.g_h = bwrect.g_h;
dst.g_x = w;
dst.g_y = 0;
dst.g_w = bwrect.g_w - w;
dst.g_h = bwrect.g_h;
plotter->copy_rect( plotter, src, dst );
b->scroll.current.x += b->scroll.requested.x;
browser_schedule_redraw( gw, 0, 0, w, bwrect.g_h );
}
if( b->scroll.requested.x > 0 ) {
/* scroll to the right */
src.g_x = w;
src.g_y = 0;
src.g_w = bwrect.g_w - w;
src.g_h = bwrect.g_h;
dst.g_x = 0;
dst.g_y = 0;
dst.g_w = bwrect.g_w - w;
dst.g_h = bwrect.g_h;
plotter->copy_rect( plotter, src, dst );
b->scroll.current.x += b->scroll.requested.x;
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;
gw->browser->compwin->xpos = b->scroll.current.x;
gw->browser->compwin->ypos = b->scroll.current.y;
mt_WindSlider( &app, gw->browser->compwin, HSLIDER|VSLIDER);
}
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) ) {
if (ascii >= 9 ) {
int ucs4 = atari_to_ucs4(ascii);
r = browser_window_key_press(gw->browser->bw, ucs4 );
}
}
return( r );
/*
switch ( nkc ) {
case NKF_LSH|NK_UP:
case NKF_RSH|NK_UP:
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 );
break;
case NKF_RSH|NK_DOWN:
case NKF_LSH|NK_DOWN:
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 );
break;
default:
if (ascii != 0) {
int ucs4 = atari_to_ucs4(ascii);
r = browser_window_key_press(gw->browser->bw, ucs4 );
}
break;
}
return( r );
*/
}
static void __CDECL browser_evnt_redraw_x( WINDOW * c, short buf[8], void * data)
{
/* just an stub to prevent wndclear */
/* Probably the browser redraw is better placed here? dunno! */
return;
}
/* determines if a browser window needs redraw */
bool browser_redraw_required( struct gui_window * gw)
{
bool ret = true;
int frames = 0;
CMP_BROWSER b = gw->browser;
{
/* don't do redraws if we have subframes */
/* iframes will be an special case and must be handled special... */
struct gui_window * g;
for( g=window_list; g; g=g->next ) {
if ( g != gw && g->parent == gw ) {
if( g->browser->type == BT_FRAME ) {
frames++;
}
}
}
}
ret = ( (b->redraw.required && frames == 0) || b->scroll.required || b->caret.redraw );
return( ret );
}
/* 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)
{
CMP_BROWSER b = gw->browser;
/* 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 )
*/
b->redraw.required = true;
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);
}
static void browser_redraw_content( struct gui_window * gw, int xoff, int yoff )
{
LGRECT work;
CMP_BROWSER b = gw->browser;
GRECT area;
current_redraw_browser = b->bw;
LOG(("%s clip: %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;
assert( area.g_w > 0 && area.g_h > 0 );
content_redraw( b->bw->current_content,
xoff-b->scroll.current.x, yoff-b->scroll.current.y,
area.g_w, area.g_h,
b->redraw.area.x0, b->redraw.area.y0,
b->redraw.area.x1, b->redraw.area.y1,
b->bw->scale, 0xFFFFFF);
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;
}
void browser_redraw_caret( struct gui_window * gw, GRECT * area )
{
GRECT caret;
struct s_browser * b = gw->browser;
if( b->caret.redraw == true ){
caret = b->caret.requested;
caret.g_x -= gw->browser->scroll.current.x;
caret.g_y -= gw->browser->scroll.current.y;
struct s_clipping oldclip;
plot_get_clip( &oldclip );
/* clip to cursor: */
plot_clip( caret.g_x-1, caret.g_y -1,
caret.g_x + caret.g_w + 1, caret.g_y + caret.g_h + 1
);
plot_rectangle( caret.g_x, caret.g_y,
caret.g_x+caret.g_w, caret.g_y+caret.g_h,
plot_style_caret );
/* restore clip area: */
plot_clip( oldclip.x0, oldclip.y0, oldclip.x1,oldclip.y1);
b->caret.current = caret;
}
}
void browser_redraw( struct gui_window * gw )
{
LGRECT bwrect;
struct s_browser * b = gw->browser;
short todo[4];
if( b->attached == false ) {
return;
}
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 );
plotter->clip( plotter, 0, 0, bwrect.g_w, bwrect.g_h );
if( b->scroll.required == true && b->bw->current_content != NULL) {
browser_process_scroll( gw, bwrect );
b->scroll.required = false;
}
if (b->redraw.required == true && b->bw->current_content != NULL ) {
if( (plotter->flags & PLOT_FLAG_OFFSCREEN) == 0 ) {
GRECT area;
BBOX cliporg;
todo[0] = bwrect.g_x;
todo[1] = bwrect.g_y;
todo[2] = todo[0] + bwrect.g_w;
todo[3] = todo[1] + bwrect.g_h;
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;
}
if( todo[1] < 0 ){
todo[3] = todo[3] + todo[1];
todo[1] = 0;
}
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 );
}
if (wind_get(gw->root->handle->handle, WF_NEXTXYWH,
&todo[0], &todo[1], &todo[2], &todo[3])==0) {
break;
}
}
}
vs_clip(plotter->vdi_handle, 0, (short*)&todo);
} else {
/* its save to do a complete redraw :) */
}
b->redraw.required = false;
}
if( b->caret.redraw == true && b->bw->current_content != NULL ) {
GRECT area;
todo[0] = bwrect.g_x;
todo[1] = bwrect.g_y;
todo[2] = todo[0] + bwrect.g_w;
todo[3] = todo[1] + bwrect.g_h;
area.g_x = bwrect.g_x;
area.g_y = bwrect.g_y;
area.g_w = bwrect.g_w;
area.g_h = bwrect.g_h;
vs_clip(plotter->vdi_handle, 1, (short*)&todo[0]);
browser_redraw_caret( gw, &area );
vs_clip(plotter->vdi_handle, 0, (short*)&todo[0]);
b->caret.redraw = false;
}
/* TODO: if we use offscreen bitmap, trigger content redraw here */
}
static void __CDECL browser_evnt_redraw( COMPONENT * c, long buff[8], void * data)
{
short pxy[8];
WINDOW * w;
struct gui_window * gw = (struct gui_window *) data;
CMP_BROWSER b = gw->browser;
struct gui_window * rgw = browser_find_root( gw );
LGRECT work, lclip, rwork;
int xoff,yoff,width,heigth;
short cw, ch, cellw, cellh;
w = (WINDOW*)mt_CompGetPtr( &app, c, CF_WINDOW );
browser_get_rect( gw, BR_CONTENT, &work );
browser_get_rect( rgw, BR_CONTENT, &rwork );
lclip = work;
if ( !rc_lintersect( (LGRECT*)&buff[4], &lclip ) ) return;
if( b->bw->current_content == NULL )
return;
/* convert redraw coords to framebuffer coords: */
lclip.g_x -= work.g_x;
lclip.g_y -= work.g_y;
if( lclip.g_x < 0 ) {
lclip.g_w = work.g_w + lclip.g_x;
lclip.g_x = 0;
}
if( lclip.g_y < 0 ) {
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
);
}
return;
}

70
atari/browser.h Normal file
View File

@ -0,0 +1,70 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NS_ATARI_BROWSER_H
#define NS_ATARI_BROWSER_H
/*
Each browser_window in the Atari Port is represented by an struct s_browser,
which cosnist mainly of an WinDom COMPONENT.
*/
#define BROWSER_SCROLL_SVAL 64 /* The small scroll inc. value */
enum browser_type
{
BT_ROOT=1,
BT_FRAME=2,
BT_FRAMESET=3,
BT_IFRAME=4
};
enum browser_rect
{
BR_CONTENT = 1,
BR_FULL = 2,
BR_HSLIDER = 3,
BR_VSLIDER = 4
};
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);
bool browser_input( struct gui_window * gw, unsigned short nkc ) ;
void browser_redraw( struct gui_window * gw );
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 );
bool browser_attach_frame( struct gui_window * container, struct gui_window * frame );
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);
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(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_mbutton( WINDOW * c, short buff[8], void * data);
static void __CDECL browser_evnt_arrowed( WINDOW *win, short buff[8], void * data);
static void __CDECL browser_evnt_slider( WINDOW *win, short buff[8], void * data);
static void __CDECL browser_evnt_redraw( COMPONENT * c, long buff[8], void * data);
static void __CDECL browser_evnt_redraw_x( WINDOW * c, short buff[8], void * data);
#endif

459
atari/browser_win.c Normal file
View File

@ -0,0 +1,459 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <windom.h>
#include <assert.h>
#include <math.h>
#include "utils/log.h"
#include "desktop/gui.h"
#include "desktop/history_core.h"
#include "desktop/netsurf.h"
#include "desktop/browser.h"
#include "desktop/mouse.h"
#include "desktop/plotters.h"
#include "atari/gui.h"
#include "atari/browser_win.h"
#include "atari/browser.h"
#include "atari/misc.h"
#include "atari/global_evnt.h"
#include "atari/res/netsurf.rsh"
#include "atari/browser.h"
#include "atari/toolbar.h"
#include "atari/statusbar.h"
#include "atari/plot/plotter.h"
bool cfg_rt_resize = false;
bool cfg_rt_move = false;
extern void * h_gem_rsrc;
extern struct gui_window *input_window;
extern GEM_PLOTTER plotter;
void __CDECL std_szd( WINDOW * win, short buff[8], void * );
void __CDECL std_mvd( WINDOW * win, short buff[8], void * );
/* -------------------------------------------------------------------------- */
/* Module public functions: */
/* -------------------------------------------------------------------------- */
static void __CDECL evnt_window_arrowed( WINDOW *win, short buff[8], void *data )
{
bool abs = false;
LGRECT cwork;
int value = BROWSER_SCROLL_SVAL;
if( input_window == NULL ) {
return;
}
browser_get_rect( input_window, BR_CONTENT, &cwork );
switch( buff[4] ) {
case WA_UPPAGE:
case WA_DNPAGE:
value = cwork.g_h;
break;
case WA_LFPAGE:
case WA_RTPAGE:
value = cwork.g_w;
break;
default:
break;
}
browser_scroll( input_window, buff[4], value, abs );
}
int window_create( struct gui_window * gw, struct browser_window * bw, unsigned long inflags)
{
short buff[8];
OBJECT * tbtree;
int err = 0;
bool tb, sb;
tb = (inflags & WIDGET_TOOLBAR );
sb = (inflags & WIDGET_STATUSBAR);
short w,h, wx, wy, wh, ww;
int flags = CLOSER | MOVER | NAME | FULLER | SMALLER ;
gw->parent = NULL;
gw->root = malloc( sizeof(struct s_gui_win_root) );
if( gw->root == NULL )
return( -1 );
gw->root->handle = WindCreate( flags,40, 40, app.w, app.h );
gw->root->cmproot = mt_CompCreate(&app, CLT_VERTICAL, 1, 1);
WindSetPtr( gw->root->handle, WF_COMPONENT, gw->root->cmproot, NULL);
if( tb ) {
gw->root->toolbar = tb_create( gw );
assert( gw->root->toolbar );
mt_CompAttach( &app, gw->root->cmproot, gw->root->toolbar->comp );
} else {
gw->root->toolbar = NULL;
}
gw->browser = browser_create( gw, bw, NULL, BT_ROOT, CLT_HORIZONTAL, 1, 1 );
mt_CompAttach( &app, gw->root->cmproot, gw->browser->comp );
if( sb ) {
gw->root->statusbar = sb_create( gw );
mt_CompAttach( &app, gw->root->cmproot, gw->root->statusbar->comp );
} else {
gw->root->statusbar = NULL;
}
WindSetStr(gw->root->handle, WF_ICONTITLE, (char*)"NetSurf");
EvntDataAttach( gw->root->handle, WM_CLOSED, evnt_window_close, NULL );
/* capture resize/move events so we can handle that manually */
if( !cfg_rt_resize ) {
EvntAttach( gw->root->handle, WM_SIZED, evnt_window_resize);
} else {
EvntAdd( gw->root->handle, WM_SIZED, evnt_window_rt_resize, EV_BOT );
}
if( !cfg_rt_move ) {
EvntAttach( gw->root->handle, WM_MOVED, evnt_window_move );
} else {
EvntAdd( gw->root->handle, WM_MOVED, evnt_window_rt_resize, EV_BOT );
}
EvntAttach( gw->root->handle, WM_FORCE_MOVE, evnt_window_rt_resize );
EvntDataAdd( gw->root->handle, WM_DESTROY,evnt_window_destroy, NULL, EV_TOP );
EvntDataAdd( gw->root->handle, WM_ARROWED,evnt_window_arrowed, NULL, EV_TOP );
EvntDataAdd( gw->root->handle, WM_NEWTOP, evnt_window_newtop, &evnt_data, EV_BOT);
EvntDataAdd( gw->root->handle, WM_TOPPED, evnt_window_newtop, &evnt_data, EV_BOT);
EvntDataAttach( gw->root->handle, WM_ICONDRAW, evnt_window_icondraw, gw);
/*
OBJECT * tbut;
RsrcGaddr( h_gem_rsrc, R_TREE, FAVICO , &tbut );
window_set_icon(gw, &tbut[]);
*/
/* TODO: check if window is openend as "foreground" window... */
window_set_focus( gw, BROWSER, gw->browser);
return (err);
}
int window_destroy( struct gui_window * gw)
{
short buff[8];
int err = 0;
if( gw->browser->type != BT_ROOT ) {
return(0);
}
/* test this with frames: */
/* assert( gw->parent == NULL); */
if( input_window == gw )
input_window = NULL;
if( gw->root ) {
if( gw->root->toolbar )
tb_destroy( gw->root->toolbar );
if( gw->root->statusbar )
sb_destroy( gw->root->statusbar );
}
LOG(("Freeing browser window"));
if( gw->browser )
browser_destroy( gw->browser );
/* destroy the icon: */
/*window_set_icon(gw, NULL, false );*/
/* needed? */ /*listRemove( (LINKABLE*)gw->root->cmproot ); */
LOG(("Freeing root window"));
if( gw->root ) {
if( gw->root->cmproot )
mt_CompDelete( &app, gw->root->cmproot );
ApplWrite( _AESapid, WM_DESTROY, gw->root->handle->handle, 0, 0, 0, 0);
EvntWindom( MU_MESAG );
gw->root->handle = NULL;
free( gw->root );
gw->root = NULL;
}
return( err );
}
void window_open( struct gui_window * gw)
{
LGRECT br;
WindOpen(gw->root->handle, 20, 20, app.w/2, app.h/2 );
/* apply focus to the root frame: */
long lfbuff[8] = { CM_GETFOCUS };
mt_CompEvntExec( gl_appvar, gw->browser->comp, lfbuff );
/* recompute the nested component sizes and positions: */
browser_update_rects( gw );
browser_get_rect( gw, BR_CONTENT, &br );
plotter->move( plotter, br.g_x, br.g_y );
plotter->resize( plotter, br.g_w, br.g_h );
gw->browser->attached = true;
snd_rdw( gw->root->handle );
}
/*
TODO
void window_set_icon(struct gui_window * gw, void * data, bool is_rsc )
{
#define CDT_ICON_TYPE_OBJECT 1UL
#define CDT_ICON_TYPE_BITMAP 2UL
void * prev_type;
void * ico = DataSearch(&app, gw->root->handle, CDT_ICON );
if(ico != NULL) {
prev_type = DataSearch(&app, gw->root->handle, CDT_ICON_TYPE );
if( prev_type == (void*)CDT_ICON_TYPE_OBJECT ){
mt_ObjcFree( &app, (OBJECT*)ico );
}
if( prev_type == (void*)CDT_ICON_TYPE_BITMAP ){
bitmap_destroy(ico);
}
}
if( data != NULL ) {
DataAttach( &app, gw->root->handle, CDT_ICON, data);
if(is_rsc) {
DataAttach( &app, gw->root->handle, CDT_ICON_TYPE, CDT_ICON_TYPE_OBJECT);
} else {
DataAttach( &app, gw->root->handle, CDT_ICON_TYPE, CDT_ICON_TYPE_BITMAP);
}
}
#undef CDT_ICON_TYPE_OBJECT
#undef CDT_ICON_TYPE_BITMAP
}
*/
/* update back forward buttons (see tb_update_buttons (bug) ) */
void window_update_back_forward( struct gui_window * gw)
{
tb_update_buttons( gw );
}
static void window_redraw_controls(struct gui_window *gw, uint32_t flags)
{
LGRECT rect;
/* redraw sliders manually, dunno why this is needed (mt_WindSlider should do the job anytime)!*/
browser_get_rect( gw, BR_VSLIDER, &rect);
ApplWrite( _AESapid, WM_REDRAW, gw->root->handle->handle,
rect.g_x, rect.g_y, rect.g_w, rect.g_h );
browser_get_rect( gw, BR_HSLIDER, &rect);
ApplWrite( _AESapid, WM_REDRAW, gw->root->handle->handle,
rect.g_x, rect.g_y, rect.g_w, rect.g_h );
/* send redraw to toolbar & statusbar & scrollbars: */
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 );
}
/* set focus to an arbitary element */
void window_set_focus( struct gui_window * gw, enum focus_element_type type, void * element )
{
if( gw->root->focus.type != type || gw->root->focus.element != element ) {
LOG(("Set focus: %p (%d)\n", element, type));
gw->root->focus.type = type;
gw->root->focus.element = element;
}
}
/* check if the url widget has focus */
bool window_url_widget_has_focus( struct gui_window * gw )
{
assert( gw );
assert( gw->root );
if( gw->root->focus.type == URL_WIDGET && gw->root->focus.element != NULL ) {
assert( ( &gw->root->toolbar->url == (struct s_url_widget*)gw->root->focus.element ) );
assert( GUIWIN_VISIBLE(gw) );
return true;
}
return false;
}
/* check if an arbitary window widget / or frame has the focus */
bool window_widget_has_focus( struct gui_window * gw, enum focus_element_type t, void * element )
{
if( gw == NULL )
return( false );
if( element == NULL ){
assert( 1 != 0 );
return( (gw->root->focus.type == t ) );
}
assert( gw->root != NULL );
return( ( element == gw->root->focus.element && t == gw->root->focus.type) );
}
/* -------------------------------------------------------------------------- */
/* Non Public Modul event handlers: */
/* -------------------------------------------------------------------------- */
static void __CDECL evnt_window_destroy( WINDOW *win, short buff[8], void *data )
{
LOG(("%s\n", __FUNCTION__ ));
if( data )
free( data );
}
static void __CDECL evnt_window_close( WINDOW *win, short buff[8], void *data )
{
struct gui_window * gw = find_root_gui_window( win );
if( gw != NULL ) {
browser_window_destroy( gw->browser->bw );
}
}
static void __CDECL evnt_window_newtop( WINDOW *win, short buff[8], void *data )
{
input_window = find_root_gui_window( win );
LOG(("newtop: iw: %p, win: %p", input_window, win ));
assert( input_window != NULL );
window_redraw_controls(input_window, 0);
}
static void __CDECL evnt_window_shaded( WINDOW *win, short buff[8], void *data )
{
if(buff[0] == WM_SHADED){
LOG(("WM_SHADED, vis: %d, state: %d", GEMWIN_VISIBLE(win), win->status ));
}
if(buff[0] == WM_UNSHADED){
}
}
static void __CDECL evnt_window_icondraw( WINDOW *win, short buff[8], void * data )
{
short x,y,w,h;
struct gui_window * gw = (struct gui_window*)data;
bool has_favicon = false;
WindClear( win);
WindGet( win, WF_WORKXYWH, &x, &y, &w, &h);
if( has_favicon == false ) {
OBJECT * tree;
RsrcGaddr( h_gem_rsrc, R_TREE, ICONIFY , &tree );
tree->ob_x = x;
tree->ob_y = y;
tree->ob_width = w;
tree->ob_height = h;
mt_objc_draw( tree, 0, 8, buff[4], buff[5], buff[6], buff[7], app.aes_global );
}
}
static void __CDECL evnt_window_move( WINDOW *win, short buff[8] )
{
short mx,my, mb, ks;
short wx, wy, wh, ww, nx, ny;
short r;
short xoff, yoff;
if( cfg_rt_move ) {
std_mvd( win, buff, &app );
evnt_window_rt_resize( win, buff );
} else {
wind_get( win->handle, WF_CURRXYWH, &wx, &wy, &ww, &wh );
if( graf_dragbox( ww, wh, wx, wy, app.x-ww, app.y, app.w+ww, app.h+wh, &nx, &ny )){
buff[4] = nx;
buff[5] = ny;
buff[6] = ww;
buff[7] = wh;
std_mvd( win, buff, &app );
evnt_window_rt_resize( win, buff );
}
}
}
void __CDECL evnt_window_resize( WINDOW *win, short buff[8] )
{
short mx,my, mb, ks;
short wx, wy, wh, ww, nw, nh;
short r;
graf_mkstate( &mx, &my, &mb, &ks );
if( cfg_rt_resize ) {
std_szd( win, buff, &app );
evnt_window_rt_resize( win, buff );
} else {
wind_get( win->handle, WF_CURRXYWH, &wx, &wy, &ww, &wh );
r = graf_rubberbox(wx, wy, 20, 20, &nw, &nh);
if( nw < 40 && nw < 40 )
return;
buff[4] = wx;
buff[5] = wy;
buff[6] = nw;
buff[7] = nh;
std_szd( win, buff, &app );
evnt_window_rt_resize( win, buff );
}
}
/* perform the actual resize */
static void __CDECL evnt_window_rt_resize( WINDOW *win, short buff[8] )
{
short x,y,w,h;
struct gui_window * gw;
LGRECT rect;
bool resized;
bool moved;
if(buff[0] == WM_FORCE_MOVE ) {
std_mvd(win, buff, &app);
std_szd(win, buff, &app);
}
wind_get( win->handle, WF_WORKXYWH, &x, &y, &w, &h );
gw = find_root_gui_window( win );
assert( gw != NULL );
if(gw->root->loc.g_x != x || gw->root->loc.g_y != y ){
moved = true;
gw->root->loc.g_x = x;
gw->root->loc.g_y = y;
browser_update_rects( gw );
}
if(gw->root->loc.g_w != w || gw->root->loc.g_h != h ){
resized = true;
/* report resize to component interface: */
browser_update_rects( gw );
browser_get_rect( gw, BR_CONTENT, &rect );
if( gw->browser->bw->current_content != NULL )
browser_window_reformat(gw->browser->bw, rect.g_w, rect.g_h );
gw->root->toolbar->url.scrollx = 0;
window_redraw_controls(gw, 0);
/* TODO: recalculate scroll position, istead of zeroing? */
}
}

79
atari/browser_win.h Normal file
View File

@ -0,0 +1,79 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NS_ATARI_BROWSER_WIN_H
#define NS_ATARI_BROWSER_WIN_H
#define GUIWIN_VISIBLE(gw) (gw->root->handle->status & WS_OPEN)
#define GEMWIN_VISIBLE(win) (win->status & WS_OPEN)
#define WIDGET_STATUSBAR 0x1
#define WIDGET_TOOLBAR 0x2
/* WinDom & Custom bindings for gui window */
/* -------------------------------------------------------------------------- */
/* Public module functions: */
/* -------------------------------------------------------------------------- */
/* Creates an normal Browser window with [toolbar], [statusbar] */
int window_create( struct gui_window * gw, struct browser_window * bw, unsigned long flags );
/* Destroys WinDom part of gui_window */
int window_destroy( struct gui_window * gw );
/* show the window */
void window_open( struct gui_window * gw);
void window_snd_redraw(struct gui_window * gw, short x, short y, short w, short h );
/* Update Shade / Unshade state of the fwd/back buttons*/
void window_update_back_forward(struct gui_window * gw);
/* set root browser component: */
void window_attach_browser( struct gui_window * gw, CMP_BROWSER b);
/* set focus element */
void window_set_focus( struct gui_window * gw, enum focus_element_type type, void * element );
/* adjust scroll settings */
void window_set_scroll_info(struct gui_window *gw, int content_h, int content_w);
/* Shade / Unshade the forward/back bt. of toolbar, depending on history.*/
bool window_widget_has_focus( struct gui_window * gw, enum focus_element_type t, void * element);
bool window_url_widget_has_focus( struct gui_window * gw );
void window_set_url( struct gui_window * gw, const char * text);
void window_center(struct gui_window * gw);
//void window_set_icon(struct gui_window * gw, void * data, bool is_rsc );
/* -------------------------------------------------------------------------- */
/* Public event handlers: */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* Static module methods follow here: */
/* -------------------------------------------------------------------------- */
static void evnt_toolbar_click(WINDOW * win, short buf[8]);
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] );
static void __CDECL evnt_window_move( WINDOW *win, short buff[8] );
static void __CDECL evnt_window_rt_resize( WINDOW *win, short buff[8] );
static void __CDECL evnt_window_close( WINDOW *win, short buff[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 );
#endif

25
atari/clipboard.h Normal file
View File

@ -0,0 +1,25 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NS_ATARI_CLIPBOARD_H
#define NS_ATARI_CLIPBOARD_H
int scrap_txt_write( APPvar app, char *str);
char *scrap_txt_read( APPvar app );
#endif

5
atari/doc/bugs Normal file
View File

@ -0,0 +1,5 @@
BUGS
- On native Ataris there is an Problem with Redraw & Mouse Cursor
- Visiting pages that contain frames: undefined behavior

30
atari/doc/readme.txt Normal file
View File

@ -0,0 +1,30 @@
Known bugs & Missing Features:
------------------------------
- Frames are not implemented - if you hit an page with frames, you are advised to close the window and open a
new one.
- Many of the Menu items are not working yet.
- No Bookmarks & No History
- No Download Manager
- The browser window can only be resized after a page has been loaded.
- removing the selection from the URL bar just works with backspace key,
del doesn't work.
Things to test:
---------------
- Networking code
- SSL
- Window Redraw - sometimes it looks like the page is redrawn all the times... (ebay...)
When you start to scroll, this stops.
Find out if the redraw stops at some point without the need of the user interaction.
- Navigate to a lot of pages, note the ones that crashed, please don't report pages that you visited
after visiting pages with frames... Make sure you don't call pages with frames. I know that it's not working,
and I know that it can cause BUGS.
- Have a look at the memory usage...
- Copy & Paste ( please don't report unsupported characters, I know it's not perfect)
Doing selections with the mouse (Press mouse key and wait until statusbar says "selecting") is not working so well...
But you can use CTRL+A to select everything. Try it.

33
atari/doc/todo Normal file
View File

@ -0,0 +1,33 @@
TODO's (no priority order)
- Optimize drawing of 1px width / height tiled bitmaps (stretch)
- Optimize remove / redraw of caret, use pixbuffer instead?
- Optimize drawing of bitmaps on Low-Memory machines
- Optimize Clipping for Plotters ( use OS clipping instead of own clipping )
- Restore the Palette when Windows get's the Focus
- Make drawing of tiled bitmaps optional
- Implement TreeView
- Implement TreeView Hotlits
- Implement TreeView History
- Implement TreeView SSL Dialog
- Implement Native Select Menu
- Implement Frames (?)
- Implement IFrames
- Implement offscreen plotter
- Implement Options Dialog
- Implement Favicon Display
- Optimize behaviour when windows gets the newtop,
set focus to the frame where the click occured,
not just the frame container.
- Replace RSC strings with string from messages file.
- Implement Selection within URL Widget by depressing SHIFT + Mouse Click
- Implement Home / End Cursors within the URL Widget
- Test pages that use a refferer.
- Optimize Offscreen Plotter: Save inactive framebuffers to disk?
- Ensure that a font-face is set to the default font when it couldn't be loaded.
- Loose focus for browser / url widget etc. when changing focus
( at best, implement callback for this...)
- Yahoo.de / .com etc. still crashes - this is probably not an Atari-Version
fault, but applies to all other netsurf versions.

67
atari/download.c Normal file
View File

@ -0,0 +1,67 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>
#include <windom.h>
#include <hubbub/hubbub.h>
#include "content/urldb.h"
#include "content/fetch.h"
#include "css/utils.h"
#include "desktop/gui.h"
#include "desktop/history_core.h"
#include "desktop/plotters.h"
#include "desktop/netsurf.h"
#include "desktop/options.h"
#include "desktop/save_complete.h"
#include "desktop/selection.h"
#include "desktop/textinput.h"
#include "render/html.h"
#include "utils/url.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/utils.h"
#include "atari/gui.h"
struct gui_download_window *gui_download_window_create(download_context *ctx,
struct gui_window *parent)
{
return NULL;
}
nserror gui_download_window_data(struct gui_download_window *dw,
const char *data, unsigned int size)
{
return NSERROR_OK;
}
void gui_download_window_error(struct gui_download_window *dw,
const char *error_msg)
{
}
void gui_download_window_done(struct gui_download_window *dw)
{
}

22
atari/download.h Normal file
View File

@ -0,0 +1,22 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NS_ATARI_DOWNLOAD_H
#define NS_ATARI_DOWNLOAD_H
#endif

63
atari/filetype.c Normal file
View File

@ -0,0 +1,63 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "utils/messages.h"
#include "utils/utils.h"
#include "utils/url.h"
#include "utils/log.h"
#include "content/fetch.h"
/**
* filetype -- determine the MIME type of a local file
*/
const char *fetch_filetype(const char *unix_path)
{
int l;
LOG(("unix path %s", unix_path));
l = strlen(unix_path);
/* This line is adding for devlopment versions running from the root dir: */
if (2 < l && strcasecmp(unix_path + l - 3, "f79") == 0)
return "text/css";
if (2 < l && strcasecmp(unix_path + l - 3, "css") == 0)
return "text/css";
if (2 < l && strcasecmp(unix_path + l - 3, "jpg") == 0)
return "image/jpeg";
if (3 < l && strcasecmp(unix_path + l - 4, "jpeg") == 0)
return "image/jpeg";
if (2 < l && strcasecmp(unix_path + l - 3, "gif") == 0)
return "image/gif";
if (2 < l && strcasecmp(unix_path + l - 3, "png") == 0)
return "image/png";
if (2 < l && strcasecmp(unix_path + l - 3, "jng") == 0)
return "image/jng";
if (2 < l && strcasecmp(unix_path + l - 3, "svg") == 0)
return "image/svg";
return "text/html";
}
char *fetch_mimetype(const char *ro_path)
{
return strdup("text/plain");
}

144
atari/findfile.c Normal file
View File

@ -0,0 +1,144 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <limits.h>
#include <unistd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include "utils/log.h"
#include "utils/url.h"
#include "atari/findfile.h"
char *path_to_url(const char *path)
{
int urllen = strlen(path) + FILE_SCHEME_PREFIX_LEN + 1;
char *url = malloc(urllen);
if (*path == '/') {
path++; /* file: paths are already absolute */
}
snprintf(url, urllen, "%s%s", FILE_SCHEME_PREFIX, path);
return url;
}
char *url_to_path(const char *url)
{
char *url_path = curl_unescape(url, 0);
char *path;
/* return the absolute path including leading / */
path = strdup(url_path + (FILE_SCHEME_PREFIX_LEN - 1));
curl_free(url_path);
return path;
}
/**
* Locate a shared resource file by searching known places in order.
*
* \param buf buffer to write to. must be at least PATH_MAX chars
* \param filename file to look for
* \param def default to return if file not found
* \return buf
*
* Search order is: ./, NETSURF_GEM_RESPATH, ./$HOME/.netsurf/, $NETSURFRES/ (where NETSURFRES is an
* environment variable),
*/
#ifndef NETSURF_GEM_RESPATH
#define NETSURF_GEM_RESPATH "./res/"
#endif
char * atari_find_resource(char *buf, const char *filename, const char *def)
{
char *cdir = NULL;
char t[PATH_MAX];
LOG(("%s (def: %s)", filename, def ));
strcpy(t, NETSURF_GEM_RESPATH);
strcat(t, filename);
LOG(("checking %s", (char*)&t));
if (realpath(t, buf) != NULL) {
if (access(buf, R_OK) == 0) {
return buf;
}
}
strcpy(t, "./");
strcat(t, filename);
LOG(("checking %s", (char*)&t));
if (realpath(t, buf) != NULL) {
if (access(buf, R_OK) == 0) {
return buf;
}
}
cdir = getenv("HOME");
if (cdir != NULL) {
strcpy(t, cdir);
strcat(t, "/.netsurf/");
strcat(t, filename);
LOG(("checking %s", (char*)&t));
if (realpath(t, buf) != NULL) {
if (access(buf, R_OK) == 0)
return buf;
}
}
cdir = getenv("NETSURFRES");
if (cdir != NULL) {
if (realpath(cdir, buf) != NULL) {
strcat(buf, "/");
strcat(buf, filename);
LOG(("checking %s", (char*)&t));
if (access(buf, R_OK) == 0)
return buf;
}
}
if (def[0] == '~') {
snprintf(t, PATH_MAX, "%s%s", getenv("HOME"), def + 1);
LOG(("checking %s", (char*)&t));
if (realpath(t, buf) == NULL) {
strcpy(buf, t);
}
} else {
LOG(("checking %s", (char*)def));
if (realpath(def, buf) == NULL) {
strcpy(buf, def);
}
}
return buf;
}
/*
* Local Variables:
* c-basic-offset: 8
* End:
*/

24
atari/findfile.h Normal file
View File

@ -0,0 +1,24 @@
/*
* Copyright 2008 Daniel Silverstone <dsilvers@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NS_ATARI_FINDFILE_H
#define NS_ATARI_FINDFILE_H
extern char *atari_find_resource(char *buf, const char *filename, const char *def);
#endif /* NETSURF_ATARI_FINDFILE_H */

120
atari/font.c Normal file
View File

@ -0,0 +1,120 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <inttypes.h>
#include <assert.h>
#include <stdbool.h>
#include <windom.h>
#include <ft2build.h>
#include FT_CACHE_H
#include "css/css.h"
#include "render/font.h"
#include "utils/utf8.h"
#include "utils/log.h"
#include "desktop/options.h"
#include "desktop/mouse.h"
#include "desktop/plotters.h"
#include "atari/gui.h"
#include "atari/font.h"
#include "atari/plot.h"
#include "atari/options.h"
#include "atari/findfile.h"
#include "atari/gui.h"
#include "atari/plot.h"
#include "atari/plot/plotter.h"
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,
size_t length,int x, size_t *char_offset, int *actual_x )
{
fplotter->pixel_position(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,
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 );
}
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 );
return( true );
}
const struct font_functions nsfont = {
atari_font_width,
atari_font_position_in_string,
atari_font_split
};

31
atari/font.h Normal file
View File

@ -0,0 +1,31 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NS_ATARI_FT_FONT_H
#define NS_ATARI_FT_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 */

760
atari/global_evnt.c Normal file
View File

@ -0,0 +1,760 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>
#include <assert.h>
#include <windom.h>
#include <cflib.h>
#include "desktop/gui.h"
#include "desktop/netsurf.h"
#include "desktop/browser.h"
#include "desktop/mouse.h"
#include "desktop/textinput.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "atari/gui.h"
#include "atari/browser_win.h"
#include "atari/toolbar.h"
#include "atari/browser.h"
#include "atari/hotlist.h"
#include "atari/misc.h"
#include "atari/global_evnt.h"
#include "atari/browser_win.h"
#include "atari/res/netsurf.rsh"
extern const char * cfg_homepage_url;
extern struct gui_window *input_window;
extern OBJECT * h_gem_menu;
extern int mouse_click_time[3];
extern int mouse_hold_start[3];
extern browser_mouse_state bmstate;
/* Zero based resource tree ids: */
#define T_ABOUT 0
#define T_FILE MAINMENU_T_FILE - MAINMENU_T_FILE + 1
#define T_EDIT MAINMENU_T_EDIT - MAINMENU_T_FILE + 1
#define T_VIEW MAINMENU_T_VIEW - MAINMENU_T_FILE + 1
#define T_NAV MAINMENU_T_NAVIGATE - MAINMENU_T_FILE + 1
#define T_UTIL MAINMENU_T_UTIL - MAINMENU_T_FILE + 1
#define T_HELP MAINMENU_T_NAVIGATE - MAINMENU_T_FILE + 1
/* Count of the above defines: */
#define NUM_MENU_TITLES 7
static char * menu_titles[NUM_MENU_TITLES] = {NULL};
/* Menu event handlers: */
static void __CDECL menu_about(WINDOW *win, int item, int title, void *data)
{
LOG(("%s", __FUNCTION__));
}
static void __CDECL menu_new_win(WINDOW *win, int item, int title, void *data)
{
LOG(("%s", __FUNCTION__));
browser_window_create(cfg_homepage_url, 0, 0, true, false);
}
static void __CDECL menu_open_url(WINDOW *win, int item, int title, void *data)
{
struct gui_window * gw;
struct browser_window * bw ;
gw = input_window;
if( gw == NULL ) {
bw = browser_window_create("", 0, 0, true, false);
gw = bw->window;
}
/* TODO: reset url? */
LOG(("%s", __FUNCTION__));
}
static void __CDECL menu_open_file(WINDOW *win, int item, int title, void *data)
{
LOG(("%s", __FUNCTION__));
}
static void __CDECL menu_close_win(WINDOW *win, int item, int title, void *data)
{
LOG(("%s", __FUNCTION__));
if( input_window == NULL )
return;
gui_window_destroy( input_window );
}
static void __CDECL menu_save_page(WINDOW *win, int item, int title, void *data)
{
LOG(("%s", __FUNCTION__));
}
static void __CDECL menu_quit(WINDOW *win, int item, int title, void *data)
{
short buff[8];
memset( &buff, 0, sizeof(short)*8 );
LOG(("%s", __FUNCTION__));
global_evnt_apterm( NULL, buff );
}
static void __CDECL menu_cut(WINDOW *win, int item, int title, void *data)
{
if( input_window != NULL )
browser_window_key_press( input_window->browser->bw, KEY_CUT_SELECTION);
}
static void __CDECL menu_copy(WINDOW *win, int item, int title, void *data)
{
LOG(("%s", __FUNCTION__));
if( input_window != NULL )
browser_window_key_press( input_window->browser->bw, KEY_COPY_SELECTION);
}
static void __CDECL menu_paste(WINDOW *win, int item, int title, void *data)
{
LOG(("%s", __FUNCTION__));
if( input_window != NULL )
browser_window_key_press( input_window->browser->bw, KEY_PASTE);
}
static void __CDECL menu_find(WINDOW *win, int item, int title, void *data)
{
LOG(("%s", __FUNCTION__));
}
static void __CDECL menu_choices(WINDOW *win, int item, int title, void *data)
{
LOG(("%s", __FUNCTION__));
}
static void __CDECL menu_stop(WINDOW *win, int item, int title, void *data)
{
LOG(("%s", __FUNCTION__));
if( input_window == NULL )
return;
tb_stop_click( input_window );
}
static void __CDECL menu_reload(WINDOW *win, int item, int title, void *data)
{
if( input_window == NULL)
return;
tb_reload_click( input_window );
LOG(("%s", __FUNCTION__));
}
static void __CDECL menu_toolbars(WINDOW *win, int item, int title, void *data)
{
LOG(("%s", __FUNCTION__));
}
static void __CDECL menu_savewin(WINDOW *win, int item, int title, void *data)
{
LOG(("%s", __FUNCTION__));
}
static void __CDECL menu_debug_render(WINDOW *win, int item, int title, void *data)
{
LOG(("%s", __FUNCTION__));
}
static void __CDECL menu_back(WINDOW *win, int item, int title, void *data)
{
LOG(("%s", __FUNCTION__));
if( input_window == NULL )
return;
tb_back_click( input_window );
}
static void __CDECL menu_forward(WINDOW *win, int item, int title, void *data)
{
LOG(("%s", __FUNCTION__));
if( input_window == NULL )
return;
tb_forward_click( input_window );
}
static void __CDECL menu_home(WINDOW *win, int item, int title, void *data)
{
LOG(("%s", __FUNCTION__));
if( input_window == NULL )
return;
tb_home_click( input_window );
}
static void __CDECL menu_lhistory(WINDOW *win, int item, int title, void *data)
{
LOG(("%s", __FUNCTION__));
}
static void __CDECL menu_ghistory(WINDOW *win, int item, int title, void *data)
{
LOG(("%s", __FUNCTION__));
}
static void __CDECL menu_add_bookmark(WINDOW *win, int item, int title, void *data)
{
LOG(("%s", __FUNCTION__));
}
static void __CDECL menu_bookmarks(WINDOW *win, int item, int title, void *data)
{
LOG(("%s", __FUNCTION__));
hotlist_open();
}
static void __CDECL menu_help_content(WINDOW *win, int item, int title, void *data)
{
LOG(("%s", __FUNCTION__));
}
static struct s_menu_item_evnt menu_evnt_tbl[] =
{
{T_FILE, MAINMENU_M_NEWWIN, "NewWindow", menu_new_win, {0,0,0}, NULL},
{T_FILE, MAINMENU_M_OPENURL, "OpenURL", menu_open_url, {0,0,0}, NULL},
{T_FILE, MAINMENU_M_OPENFILE, "OpenFile", menu_open_file, {0,0,0}, NULL},
{T_FILE, MAINMENU_M_CLOSEWIN, "CloseWindow", menu_close_win, {0,0,0}, NULL},
{T_FILE, MAINMENU_M_SAVEPAGE, "Save", menu_save_page, {0,0,0}, NULL},
{T_FILE, MAINMENU_M_QUIT, "Quit", menu_quit, {'Q',0,K_CTRL}, NULL},
{T_EDIT, MAINMENU_M_CUT, "Cut", menu_cut, {0,0,0}, NULL},
{T_EDIT, MAINMENU_M_COPY, "Copy", menu_copy, {0,0,0}, NULL},
{T_EDIT, MAINMENU_M_PASTE, "Paste", menu_paste, {0,0,0}, NULL},
{T_EDIT, MAINMENU_M_FIND, "FindText", menu_find, {0,0,0}, NULL},
{T_VIEW, MAINMENU_M_RELOAD, "Reload", menu_reload, {0,NK_F5,0}, NULL},
{T_VIEW, MAINMENU_M_TOOLBARS, "Toolbars", menu_toolbars, {0,0,0}, NULL},
{T_VIEW, MAINMENU_M_SAVEWIN, "", menu_savewin, {0,0,0}, NULL},
{T_VIEW, MAINMENU_M_DEBUG_RENDER, "", menu_debug_render, {0,0,0}, NULL},
{T_VIEW, MAINMENU_M_STOP, "Stop", menu_stop, {0,0,0}, NULL},
{T_NAV, MAINMENU_M_BACK, "Back", menu_back, {0,0,0}, NULL},
{T_NAV, MAINMENU_M_FORWARD, "Forward", menu_forward, {0,0,0}, NULL},
{T_NAV, MAINMENU_M_HOME, "Home", menu_home, {0,0,0}, NULL},
{T_UTIL, MAINMENU_M_LHISTORY, "HistLocal", menu_lhistory, {0,0,0}, NULL},
{T_UTIL, MAINMENU_M_GHISTORY, "HistGlobal", menu_ghistory, {0,0,0}, NULL},
{T_UTIL, MAINMENU_M_ADD_BOOKMARK, "HotlistAdd", menu_add_bookmark, {0,0,0}, NULL},
{T_UTIL, MAINMENU_M_BOOKMARKS, "HotlistShow", menu_bookmarks, {0,0,0}, NULL},
{T_UTIL, MAINMENU_M_CHOICES, "Choices", menu_choices, {0,0,0}, NULL},
{T_HELP, MAINMENU_M_HELP_CONTENT, "Help", menu_help_content, {0,0,0}, NULL},
{T_HELP, -1, "", NULL,{0,0,0}, NULL }
};
void __CDECL global_evnt_apterm( WINDOW * win, short buff[8] )
{
int i = 0;
LOG((""));
netsurf_quit = true;
}
void __CDECL global_evnt_keybd( WINDOW * win, short buff[8], void * data)
{
char sascii;
long kstate = 0;
long kcode = 0;
unsigned short nkc = 0;
unsigned short nks = 0;
int i=0;
bool done = false;
struct s_evnt_data * loc_evnt_data;
loc_evnt_data = (struct s_event_data*)data;
struct gui_window * gw = input_window;
struct gui_window * gw_tmp;
if( gw == NULL )
return;
if( loc_evnt_data->ignore )
return;
kstate = evnt.mkstate;
kcode = evnt.keybd;
nkc= gem_to_norm( (short)kstate, (short)kcode );
nks = (nkc & 0xFF00);
loc_evnt_data->ignore = false;
if( kstate & (K_LSHIFT|K_RSHIFT))
kstate |= K_LSHIFT|K_RSHIFT;
if( window_url_widget_has_focus( gw ) ) {
/* make sure we report for the root window and report...: */
done = tb_url_input( browser_find_root(gw), nkc );
if( done ) return;
} else {
gw_tmp = window_list;
/* search for active browser component: */
while( gw_tmp != NULL && done == false ) {
if( window_widget_has_focus( (struct gui_window *)input_window,
BROWSER,(void*)gw_tmp->browser)) {
done = browser_input( gw_tmp, nkc );
break;
} else {
gw_tmp = gw_tmp->next;
}
}
}
sascii = keybd2ascii( evnt.keybd, K_LSHIFT);
while( menu_evnt_tbl[i].rid != -1 && done == false) {
if(menu_evnt_tbl[i].nsid[0] != 0 ) {
if( kstate == menu_evnt_tbl[i].accel.mod && menu_evnt_tbl[i].accel.ascii != 0) {
if( menu_evnt_tbl[i].accel.ascii == sascii) {
menu_evnt_tbl[i].menu_func( NULL, menu_evnt_tbl[i].rid, MAINMENU, buff);
done = true;
break;
}
} else {
/* the accel code hides in the keycode: */
if( menu_evnt_tbl[i].accel.keycode != 0) {
if( menu_evnt_tbl[i].accel.keycode == (nkc & 0xFF) &&
kstate == menu_evnt_tbl[i].accel.mod &&
menu_evnt_tbl[i].menu_func != NULL) {
menu_evnt_tbl[i].menu_func( NULL,
menu_evnt_tbl[i].rid,
MAINMENU, buff
);
done = true;
break;
}
}
}
}
i++;
}
}
browser_mouse_state global_track_evnt_mbutton( WINDOW * win, long buff[8], void * data )
{
short i;
short mbut, mkstat, mx, my;
browser_mouse_state retval = 0;
graf_mkstate(&mx, &my, &mbut, &mkstat);
for( i = 1; i<2; i++) {
if( (mbut & i) ) {
if( mouse_hold_start[i-1] == 0 ) {
mouse_hold_start[i-1] = clock()*1000 / CLOCKS_PER_SEC;
LOG(("Drag %d starts", i));
if( i == 1 ) {
retval |= BROWSER_MOUSE_DRAG_1;
}
if( i == 2 ) {
retval |= BROWSER_MOUSE_DRAG_2;
}
}
} else {
/* remember click time, so we can track double clicks: */
mouse_click_time[i-1] = clock()*1000 / CLOCKS_PER_SEC; /* clock in ms */
/* check if this event was during an drag op: */
if( mouse_hold_start[i-1] < 10 ) {
if( i == 1)
retval |= BROWSER_MOUSE_CLICK_1;
if( i == 2 )
retval |= BROWSER_MOUSE_CLICK_2;
}
mouse_hold_start[i-1] = 0;
}
}
return( retval );
}
void global_track_mouse_state( void ){
int i = 0;
int nx, ny;
short mbut, mkstat, mx, my;
long hold_time = 0;
COMPONENT * cmp;
LGRECT cmprect;
if( !input_window ) {
bmstate = 0;
return;
}
graf_mkstate(&mx, &my, &mbut, &mkstat);
cmp = mt_CompFind( &app, input_window->root->cmproot, mx, my );
if( cmp == NULL ) {
bmstate = 0;
mouse_hold_start[0] = 0;
mouse_hold_start[1] = 0;
return;
}
mt_CompGetLGrect( &app, cmp, WF_WORKXYWH, &cmprect );
nx = mx - cmprect.g_x;
ny = my - cmprect.g_y;
if( !(mbut&1) && !(mbut&2) ) {
if(bmstate & BROWSER_MOUSE_DRAG_ON )
bmstate &= ~( BROWSER_MOUSE_DRAG_ON );
}
for( i = 1; i<3; i++ ) {
if( (mbut & i) ) {
/* the mouse is still pressed...
report further dragging ?
BROWSER_MOUSE_PRESS_2 needed ?
*/
if(i==1)
bmstate |= BROWSER_MOUSE_DRAG_ON|BROWSER_MOUSE_HOLDING_1;
if( i==2 )
bmstate |= BROWSER_MOUSE_DRAG_ON|BROWSER_MOUSE_HOLDING_2;
LOG(("still dragging %d, time ms: %d", i, (clock()*1000 / CLOCKS_PER_SEC) - mouse_hold_start[i-1] ));
browser_window_mouse_track( input_window->browser->bw, bmstate, nx, ny );
} else {
if( mouse_hold_start[i-1] > 0 ) {
mouse_hold_start[i-1] = 0;
LOG(("drag release %d", i));
/* TODO: not just use the input window browser, find the right one by component! */
if( i==1 ) {
bmstate &= ~( BROWSER_MOUSE_HOLDING_1 );
browser_window_mouse_drag_end( input_window->browser->bw,
bmstate, nx, ny);
}
if( i==2 ) {
bmstate &= ~( BROWSER_MOUSE_HOLDING_2 );
browser_window_mouse_drag_end( input_window->browser->bw,
bmstate, nx, ny);
}
}
}
}
browser_window_mouse_track(input_window->browser->bw, bmstate, nx, ny );
}
void __CDECL global_evnt_m1( WINDOW * win, short buff[8], void * data)
{
struct gui_window * gw = input_window;
static bool prev_url = false;
static bool prev_sb = false;
bool a=false;
LGRECT urlbox, bwbox, sbbox;
int nx, ny; /* relative mouse position */
if( gw == NULL)
return;
if( gw->root->toolbar )
mt_CompGetLGrect(&app, gw->root->toolbar->url.comp, WF_WORKXYWH, &urlbox);
mt_CompGetLGrect(&app, gw->browser->comp, WF_WORKXYWH, &bwbox);
mt_CompGetLGrect(&app, gw->root->statusbar->comp, WF_WORKXYWH, &sbbox);
if( evnt.m1_flag == MO_LEAVE && input_window != NULL ) {
if( gw->root->toolbar ) {
if( (evnt.mx > urlbox.g_x && evnt.mx < urlbox.g_x + urlbox.g_w ) &&
(evnt.my > urlbox.g_y && evnt.my < + urlbox.g_y + urlbox.g_h )) {
gem_set_cursor( &gem_cursors.ibeam );
prev_url = a = true;
}
}
if( gw->root->statusbar && a == false ) {
if( evnt.mx >= sbbox.g_x + (sbbox.g_w-MOVER_WH) && evnt.mx <= sbbox.g_x + sbbox.g_w &&
evnt.my >= sbbox.g_y + (sbbox.g_h-MOVER_WH) && evnt.my <= sbbox.g_y + sbbox.g_h ) {
/* mouse within mover */
prev_sb = a = true;
gem_set_cursor( &gem_cursors.sizenwse );
}
}
if( !a ) {
if( prev_url || prev_sb ) {
gem_set_cursor( &gem_cursors.arrow );
prev_url = false;
prev_sb = false;
}
/* report mouse move in the browser window */
if( evnt.mx > bwbox.g_x && evnt.mx < bwbox.g_x + bwbox.g_w &&
evnt.my > bwbox.g_y && evnt.my < bwbox.g_y + bwbox.g_h ){
/* TODO: use global mouse state instead of zero
TODO: find COMPONENT and report to its browser, or maybe
its better to catch mouse movements with component events?
*/
nx = evnt.mx - bwbox.g_x;
ny = evnt.my - bwbox.g_y;
/*printf("m1 bw: %p, x: %d, y: %d, state: %d\n" , input_window->browser->bw, nx, ny, bmstate);*/
browser_window_mouse_track( input_window->browser->bw, 0, nx + gw->browser->scroll.current.x, ny + gw->browser->scroll.current.y );
}
}
}
}
/*
mode = 0 -> return string ptr
(build from accel definition in s_accelerator accel)
mode = 1 -> return ptr to (untranslated) NS accel string, if any
*/
static char * get_accel(int mode, char * message, struct s_accelerator * accel )
{
static char result[8];
int pos = 0;
char * r = NULL;
char * s = NULL;
memset( &result, 0, 8);
if( (accel->ascii != 0 || accel->keycode != 0) && mode == 0)
goto predefined_accel;
s = strrchr(message, (int)' ' ) ;
if(!s)
goto error;
if( strlen( s ) < 2)
goto error;
if(strlen(s) >= 2){
s++;
/* if string after space begins with lowercase ascii, its not an accelerator: */
if( s[0] >= 0x061 && s[0] <= 0x07A )
goto error;
if( strncmp(s, "URL", 3) == 0)
goto error;
if(mode == 1)
return( s );
/* detect obscure shift accelerator: */
if(!strncmp("\xe2\x87\x91", s, 3)){
s = s+3;
strcpy((char*)&result, "");
strncpy((char*)&result[1], s, 14);
goto success;
}
strncpy((char*)&result, s, 15);
}
goto success;
predefined_accel:
if( (accel->mod & K_RSHIFT) || (accel->mod & K_RSHIFT) ) {
result[pos]='';
pos++;
}
if(accel->mod == K_CTRL ) {
result[pos]='^';
pos++;
}
if(accel->ascii != 0L ) {
result[pos]= accel->ascii;
pos++;
}
else if(accel->keycode != 0L ) {
if( accel->keycode >= NK_F1 && accel->keycode <= NK_F10){
result[pos++] = 'F';
sprintf( (char*)&result[pos++], "%d", ((accel->keycode - NK_F1)+1) );
} else {
*((char*)0) = 1;
switch( accel->keycode ) {
/* TODO: Add further Keycodes & Symbols here, if needed. */
default:
goto error;
}
}
}
success:
r = (char*)&result;
error:
return r;
}
/* create accelerator info and keep track of the line length */
static int parse_accel( char * message, struct s_accelerator * accel)
{
int retval = strlen( message ) ;
char * s = get_accel( 0, message, accel );
if(!s && (accel->keycode == 0 && accel->ascii == 0 && accel->mod == 0) ) {
return retval+4; /* add 3 "imaginary" accel characters + blank */
}
/* the accel is already defined: */
if(accel->keycode != 0 ||accel->ascii != 0 || accel->mod != 0) {
return( retval+1 );
}
if(s[0] == '' ) { /* arrow up */
accel->mod |= (K_LSHIFT|K_RSHIFT);
s++;
}
else if(s[0] == 0x05E ) { /* ^ */
accel->mod |= K_CTRL;
s++;
}
parsekey:
/* expect F1/F10 or something like A, B, C ... : */
if(strlen(s) >= 2 && s[0] == 'F' ) {
if(s[1] >= 49 && s[1] <= 57) {
accel->keycode = NK_F1 + (atoi(&s[1])-1);
}
}
else {
accel->ascii = s[0];
}
return( retval+1 ); /* add 1 blank */
}
void __CDECL global_evnt_menu( WINDOW * win, short buff[8] )
{
int title = buff[ 3];
INT16 x,y;
char *str;
struct gui_window * gw = window_list;
int i=0;
MenuTnormal( NULL, title, 1);
while( gw ) {
window_set_focus( gw, WIDGET_NONE, NULL );
gw = gw->next;
}
while( menu_evnt_tbl[i].rid != -1) {
if( menu_evnt_tbl[i].rid == buff[4] ) {
menu_evnt_tbl[i].menu_func(win, (int)buff[4], (int)buff[3], NULL );
break;
}
i++;
}
}
static void set_menu_title(int rid, const char * nsid)
{
static int count=0;
char * msgstr;
msgstr = (char*)messages_get(nsid);
if(msgstr != NULL) {
if(msgstr[0] != 0) {
assert(count < NUM_MENU_TITLES);
menu_titles[count] = malloc( strlen(msgstr)+3 );
strcpy((char*)menu_titles[count], " ");
strncat((char*)menu_titles[count], msgstr, strlen(msgstr)+1 );
strncat((char*)menu_titles[count], " ", 2 );
MenuText(NULL, rid, menu_titles[count] );
count++;
}
}
}
/* Bind global and menu events to event handler functions, create accelerators */
void bind_global_events( void )
{
int i, len;
int maxlen[NUM_MENU_TITLES]={0};
char * m, *u, *t;
char spare[128];
memset( (void*)&evnt_data, 0, sizeof(struct s_evnt_data) );
EvntDataAttach( NULL, WM_XKEYBD, global_evnt_keybd, (void*)&evnt_data );
EvntAttach( NULL, AP_TERM, global_evnt_apterm );
EvntAttach( NULL, MN_SELECTED, global_evnt_menu );
EvntDataAttach( NULL, WM_XM1, global_evnt_m1, NULL );
/* TODO: maybe instant redraw after this is better! */
set_menu_title( MAINMENU_T_FILE, "Page");
set_menu_title( MAINMENU_T_EDIT, "Edit" );
set_menu_title( MAINMENU_T_NAVIGATE, "Navigate");
set_menu_title( MAINMENU_T_VIEW, "View");
set_menu_title( MAINMENU_T_UTIL, "Utilities");
set_menu_title( MAINMENU_T_HELP, "Help");
/* measure items in titles : */
i = 0;
while( menu_evnt_tbl[i].rid != -1 ) {
if( menu_evnt_tbl[i].nsid[0] != 0 ) {
m = (char*)messages_get(menu_evnt_tbl[i].nsid);
assert(strlen(m)<40);
/* create accelerator: */
len = parse_accel(m, &menu_evnt_tbl[i].accel);
maxlen[menu_evnt_tbl[i].title]=MAX(len, maxlen[menu_evnt_tbl[i].title] );
assert(maxlen[menu_evnt_tbl[i].title]<40);
}
i++;
}
for( i=0; i<NUM_MENU_TITLES; i++) {
if ( maxlen[i] > 120 )
maxlen[i] = 120;
}
/* set menu texts : */
i = 0;
while( menu_evnt_tbl[i].rid != -1 ) {
if( menu_evnt_tbl[i].nsid[0] != 0 ) {
m = (char*)messages_get(menu_evnt_tbl[i].nsid);
if(m == NULL) {
m = (char*)menu_evnt_tbl[i].nsid;
}
u = get_accel( 1, m, &menu_evnt_tbl[i].accel); /* get NS accel str */
t = get_accel( 0, m, &menu_evnt_tbl[i].accel); /* get NS or custom accel */
memset((char*)&spare, ' ', 121);
spare[0]=' '; /*''; */
spare[1]=' ';
if( u != NULL && t != NULL ) {
LOG(("Menu Item %s: found NS accelerator, ascii: %c, scancode: %x, mod: %x",
m,
menu_evnt_tbl[i].accel.ascii,
menu_evnt_tbl[i].accel.keycode,
menu_evnt_tbl[i].accel.mod
));
/* Accelerator is defined in menu string: */
memcpy((char*)&spare[2], m, u-m-1);
strncpy(&spare[maxlen[menu_evnt_tbl[i].title]-strlen(t)], t, 4);
}
else if( t != NULL && u == NULL) {
LOG(("Menu Item %s: found RSC accelerator, ascii: %c, scancode: %x, mod: %x",
m,
menu_evnt_tbl[i].accel.ascii,
menu_evnt_tbl[i].accel.keycode,
menu_evnt_tbl[i].accel.mod
));
/* Accelerator is defined in struct: */
memcpy( (char*)&spare[2], m, strlen(m) );
strncpy(&spare[maxlen[menu_evnt_tbl[i].title]-strlen(t)], t, 4);
}
else {
/* No accel defined: */
strcpy((char*)&spare[2], m);
}
spare[ maxlen[menu_evnt_tbl[i].title]+1 ] = 0;
menu_evnt_tbl[i].menustr = malloc(strlen((char*)&spare)+1);
if( menu_evnt_tbl[i].menustr ) {
strcpy( menu_evnt_tbl[i].menustr , (char*)&spare );
}
}
i++;
}
i=0;
while( menu_evnt_tbl[i].rid != -1 ) {
if( menu_evnt_tbl[i].menustr != NULL ) {
MenuText( NULL, menu_evnt_tbl[i].rid, menu_evnt_tbl[i].menustr );
}
i++;
}
/* TODO: Fix pixel sizes for Titles and Items (for non-8px fonts) */
}
void unbind_global_events( void )
{
int i;
for( i=0; i<NUM_MENU_TITLES; i++){
if( menu_titles[i]!= NULL)
free( menu_titles[i] );
}
i=0;
while(menu_evnt_tbl[i].rid != -1) {
if( menu_evnt_tbl[i].menustr != NULL )
free(menu_evnt_tbl[i].menustr);
i++;
}
}
void snd_redraw( short x, short y, short w, short h)
{
struct gui_window * gw;
gw = window_list;
while( gw != NULL && gw->browser->type == 0 ) {
ApplWrite( _AESapid, WM_REDRAW, gw->root->handle->handle, x, y, w, h);
gw = gw->next;
}
return;
}

78
atari/global_evnt.h Normal file
View File

@ -0,0 +1,78 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NS_ATARI_GLOBAL_EVNT_H
#define NS_ATARI_GLOBAL_EVNT_H
struct s_keybd_evnt_data
{
char ascii;
} keybd_evnt_data;
struct s_evnt_data
{
bool ignore;
union {
struct s_keybd_evnt_data keybd;
} u;
};
struct s_evnt_data evnt_data;
struct s_accelerator
{
char ascii; /* either ascii or */
long keycode; /* normalised keycode is valid */
short mod; /* shift / ctrl etc */
};
typedef void __CDECL (*menu_evnt_func)(WINDOW * win, int item, int title, void * data);
struct s_menu_item_evnt {
short title; /* to which menu this item belongs */
short rid; /* resource ID */
const char * nsid; /* Netsurf message ID */
menu_evnt_func menu_func; /* click handler */
struct s_accelerator accel; /* accelerator info */
char * menustr;
};
/*
Global & Menu event handlers
*/
/* Call this after each call to evnt_multi, to check for states that evnt_multi doesn't: */
void snd_redraw(short x, short y, short w, short h);
void snd_win_redraw(WINDOW * win, short x, short y, short w, short h);
void global_track_mouse_state( void );
browser_mouse_state global_track_evnt_mbutton( WINDOW * win, long buff[8], void * data );
void bind_global_events( void );
void unbind_global_events( void );
/* Global event handlers: */
static void __CDECL global_evnt_apterm( WINDOW * win, short buff[8] );
static void __CDECL global_evnt_menu( WINDOW * win, short buff[8] );
static void __CDECL global_evnt_keybd( WINDOW * win, short buff[8], void * data);
static void __CDECL global_evnt_m1( WINDOW * win, short buff[8], void * data);
/* Menu event handlers: */
static void __CDECL menu_about(WINDOW *win, int item, int title, void *data);
static char * get_accel(int mode, char * message, struct s_accelerator * accel);
static int parse_accel( char * message, struct s_accelerator * accel);
#endif

1131
atari/gui.c Normal file

File diff suppressed because it is too large Load Diff

236
atari/gui.h Normal file
View File

@ -0,0 +1,236 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NS_ATARI_GUI_H_
#define NS_ATARI_GUI_H_
#include <windom.h>
#define WM_FORCE_MOVE 1024 + 3
struct point_s {
int x;
int y;
};
struct bbox_s {
int x0;
int y0;
int x1;
int y1;
};
typedef struct bbox_s BBOX;
typedef struct point_s POINT;
#define MFORM_EX_FLAG_USERFORM 0x01
#define MFORM_EX_FLAG_REDRAW_REQUIRED 0x02
struct mform_ex_s
{
unsigned char flags;
int number;
OBJECT * tree;
};
typedef struct mform_ex_s MFORM_EX;
struct s_gem_cursors {
MFORM_EX hand;
MFORM_EX ibeam;
MFORM_EX cross;
MFORM_EX sizeall;
MFORM_EX sizewe;
MFORM_EX sizens;
MFORM_EX sizenesw;
MFORM_EX sizenwse;
MFORM_EX wait;
MFORM_EX appstarting;
MFORM_EX nodrop;
MFORM_EX deny;
MFORM_EX help;
MFORM_EX menu;
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,
BROWSER
};
struct s_focus_info
{
enum focus_element_type type;
void * element;
};
struct s_gui_input_state {
short mbut;
short mkstat;
short mx;
short my;
} 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 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[255];
};
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;
};
typedef struct s_toolbar * CMP_TOOLBAR;
typedef struct s_statusbar * CMP_STATUSBAR;
typedef struct s_browser * CMP_BROWSER;
struct s_gui_win_root
{
WINDOW * handle;
CMP_TOOLBAR toolbar;
CMP_STATUSBAR statusbar;
COMPONENT * cmproot;
MFORM_EX cursor;
struct s_focus_info focus;
float scale;
bool throbbing;
GRECT loc; /* current size of window on screen */
};
struct gui_window {
struct s_gui_win_root * root;
CMP_BROWSER browser;
struct gui_window * parent;
struct gui_window *next, *prev;
};
extern struct gui_window *window_list;
/* scroll a window */
void gem_window_scroll(struct browser_window * , int x, int y);
#define MOUSE_IS_DRAGGING() (mouse_hold_start[0] || mouse_hold_start[1])
#endif

30
atari/history.c Normal file
View File

@ -0,0 +1,30 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "content/urldb.h"
#include "desktop/browser.h"
void global_history_add_recent(const char *url)
{
}
char **global_history_get_recent(int *count)
{
return NULL;
}

22
atari/history.h Normal file
View File

@ -0,0 +1,22 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NS_ATARI_HISTORY_H
#define NS_ATARI_HISTORY_H
#endif

165
atari/hotlist.c Normal file
View File

@ -0,0 +1,165 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "desktop/browser.h"
#include "content/content.h"
#include "content/hlcache.h"
#include "content/urldb.h"
#include "desktop/options.h"
#include "desktop/hotlist.h"
#include "desktop/tree.h"
#include "desktop/gui.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/utils.h"
#include "utils/url.h"
#include "atari/gui.h"
#include "atari/misc.h"
#include "atari/treeview.h"
#include "atari/hotlist.h"
#include "atari/findfile.h"
#include "atari/res/netsurf.rsh"
static struct atari_hotlist {
WINDOW * window;
NSTREEVIEW tv; /*< The hotlist treeview handle. */
bool open;
} hl;
static const struct {
const char *url;
const char *msg_key;
} default_entries[] = {
{ "http://www.netsurf-browser.org/", "HotlistHomepage" },
{ "http://www.netsurf-browser.org/downloads/riscos/testbuilds", "HotlistTestBuild" },
{ "http://www.netsurf-browser.org/documentation", "HotlistDocumentation" },
{ "http://sourceforge.net/tracker/?atid=464312&group_id=51719",
"HotlistBugTracker" },
{ "http://sourceforge.net/tracker/?atid=464315&group_id=51719",
"HotlistFeatureRequest" }
};
#define ENTRIES_COUNT (sizeof(default_entries) / sizeof(default_entries[0]))
static void evnt_hl_toolbar( WINDOW *win, short buff[8]) {
int obj = buff[4]; /* Selected object */
LOG(("item: %d clicked", obj ));
switch( obj) {
case TOOLBAR_HOTLIST_CREATE_FOLDER:
break;
case TOOLBAR_HOTLIST_ADD:
break;
case TOOLBAR_HOTLIST_DELETE:
break;
}
/* object state to normal and redraw object */
/*
ObjcChange( TOOLBAR_HOTLIST, hl.window, obj, SELECTED, 1);
ObjcChange( TOOLBAR_HOTLIST, hl.window, obj, 0 , 1);
*/
}
static void __CDECL evnt_hl_close( WINDOW *win, short buff[8] )
{
hotlist_close();
}
void hotlist_init(void)
{
char hlfilepath[PATH_MAX];
atari_find_resource(
(char*)&hlfilepath, "hotlist", "./res/Hotlist"
);
if( hl.window == NULL ){
int flags = CLOSER | MOVER | SIZER| NAME | FULLER | SMALLER ;
OBJECT * tree = get_tree(TOOLBAR_HOTLIST);
assert( tree );
hl.open = false;
hl.window = WindCreate( flags,40, 40, app.w, app.h );
if( hl.window == NULL ) {
LOG(("Failed to allocate Hotlist"));
return;
}
/* TODO: load hotlist strings from messages */
WindSetStr( hl.window, WF_NAME, (char*)"Hotlist" );
WindSetPtr( hl.window, WF_TOOLBAR,
tree,
evnt_hl_toolbar
);
EvntAttach( hl.window, WM_CLOSED, evnt_hl_close );
hl.tv = atari_treeview_create(
hotlist_get_tree_flags(),
hl.window
);
if (hl.tv == NULL) {
LOG(("Failed to allocate treeview"));
return;
}
hotlist_initialise(
atari_treeview_get_tree(hl.tv),
/* TODO: use option_hotlist_file or slt*/
(char*)&hlfilepath,
hlfilepath
);
} else {
}
}
void hotlist_open(void)
{
hotlist_init();
if( hl.open == false ) {
WindOpen( hl.window, -1, -1, app.w/3, app.h/2);
hl.open = true;
}
tree_set_redraw(atari_treeview_get_tree(hl.tv), true);
}
void hotlist_close(void)
{
WindClose(hl.window);
hl.open = false;
}
void hotlist_destroy(void)
{
if( hl.window != NULL ) {
if( hl.open )
hotlist_close();
WindDelete( hl.window );
printf("delete hl tree");
atari_treeview_destroy( hl.tv );
hl.window = NULL;
}
}

30
atari/hotlist.h Normal file
View File

@ -0,0 +1,30 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NS_ATARI_HOTLIST_H
#define NS_ATARI_HOTLIST_H
/* The hotlist window, toolbar and treeview data. */
void hotlist_init(void);
void hotlist_open(void);
void hotlist_close(void);
void hotlist_destroy(void);
#endif

110
atari/login.c Normal file
View File

@ -0,0 +1,110 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "desktop/401login.h"
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <windom.h>
#include "utils/config.h"
#include "content/content.h"
#include "content/hlcache.h"
#include "content/urldb.h"
#include "desktop/browser.h"
#include "desktop/401login.h"
#include "desktop/gui.h"
#include "utils/errors.h"
#include "utils/utils.h"
#include "utils/messages.h"
#include "utils/log.h"
#include "utils/url.h"
#include "content/urldb.h"
#include "content/fetch.h"
#include "atari/login.h"
#include "atari/res/netsurf.rsh"
extern void * h_gem_rsrc;
bool login_form_do( char * url, char * realm, char ** out )
{
OBJECT *tree, *newtree;
WINDOW * form;
char user[255];
char pass[255];
bool bres = false;
int res = 0;
const char * auth;
char * host;
assert( url_host( url, &host) == URL_FUNC_OK );
if( realm == NULL ){
realm = (char*)"Secure Area";
}
int len = strlen(realm) + strlen(host) + 4;
char * title = malloc( len );
strncpy(title, realm, len );
strncpy(title, ": ", len-strlen(realm) );
strncat(title, host, len-strlen(realm)+2 );
auth = urldb_get_auth_details(url, realm);
user[0] = 0;
pass[0] = 0;
/*
TODO: use auth details if available:
if( auth == NULL ){
} else {
}*/
RsrcGaddr (h_gem_rsrc , R_TREE, LOGIN, &tree);
ObjcChange( OC_OBJC, tree, LOGIN_BT_LOGIN, 0, 0 );
ObjcChange( OC_OBJC, tree, LOGIN_BT_ABORT, 0, 0 );
ObjcString( tree, LOGIN_TB_USER, (char*)&user );
ObjcString( tree, LOGIN_TB_PASSWORD, (char*)&pass );
form = FormWindBegin( tree, (char *)title );
res = -1;
while( res != LOGIN_BT_LOGIN && res != LOGIN_BT_ABORT ){
res = FormWindDo( MU_MESAG );
switch( res ){
case LOGIN_BT_LOGIN:
bres = true;
break;
case LOGIN_BT_ABORT:
bres = false;
break;
}
}
if( bres ) {
*out = malloc(strlen((char*)&user) + strlen((char*)&pass) + 2 );
strcpy(*out, (char*)&user);
strcat(*out, ":");
strcat(*out, (char*)&pass);
} else {
*out = NULL;
}
FormWindEnd( );
free( title );
return( bres );
}

24
atari/login.h Normal file
View File

@ -0,0 +1,24 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NS_LOGIN_H_INCLUDED
#define NS_LOGIN_H_INCLUDED
bool login_form_do( char * host, char * realm, char **cbpw );
#endif

184
atari/misc.c Normal file
View File

@ -0,0 +1,184 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <windom.h>
#include "desktop/cookies.h"
#include "desktop/mouse.h"
#include "utils/messages.h"
#include "utils/utils.h"
#include "utils/url.h"
#include "utils/log.h"
#include "content/fetch.h"
#include "atari/gui.h"
#include "atari/toolbar.h"
#include "atari/misc.h"
extern void * h_gem_rsrc;
void warn_user(const char *warning, const char *detail)
{
size_t len = 1 + ((warning != NULL) ? strlen(messages_get(warning)) :
0) + ((detail != 0) ? strlen(detail) : 0);
char message[len];
snprintf(message, len, messages_get(warning), detail);
printf("%s\n", message);
}
void die(const char *error)
{
printf("%s\n", error);
exit(1);
}
bool cookies_update(const char *domain, const struct cookie_data *data)
{
return true;
}
/**
* Return the filename part of a full path
*
* \param path full path and filename
* \return filename (will be freed with free())
*/
char *filename_from_path(char *path)
{
char *leafname;
leafname = strrchr(path, '\\');
if (!leafname)
leafname = path;
else
leafname += 1;
return strdup(leafname);
}
/**
* Add a path component/filename to an existing path
*
* \param path buffer containing path + free space
* \param length length of buffer "path"
* \param newpart string containing path component to add to path
* \return true on success
*/
bool path_add_part(char *path, int length, const char *newpart)
{
if(path[strlen(path) - 1] != '/')
strncat(path, "/", length);
strncat(path, newpart, length);
return true;
}
#define IS_TOPLEVEL_BROWSER_WIN( gw ) (gw->root->handle == win && gw->parent == NULL )
struct gui_window * find_root_gui_window( WINDOW * win )
{
int i=0;
struct gui_window * gw;
gw = window_list;
while( gw != NULL ) {
if( IS_TOPLEVEL_BROWSER_WIN( gw ) ) {
return( gw );
}
else
gw = gw->next;
i++;
assert( i < 1000);
}
return( NULL );
}
struct gui_window * find_cmp_window( COMPONENT * c )
{
struct gui_window * gw;
int i=0;
gw = window_list;
while( gw != NULL ) {
assert( gw->browser != NULL );
if( gw->browser->comp == c ) {
return( gw );
}
else
gw = gw->next;
i++;
assert( i < 1000);
}
return( NULL );
}
/* -------------------------------------------------------------------------- */
/* GEM Utillity functions: */
/* -------------------------------------------------------------------------- */
/* Return a string from resource file */
char *get_rsc_string( int idx) {
char *txt;
RsrcGaddr( h_gem_rsrc, R_STRING, idx, &txt );
return txt;
}
OBJECT *get_tree( int idx) {
OBJECT *tree;
RsrcGaddr( h_gem_rsrc, R_TREE, idx, &tree);
return tree;
}
void gem_set_cursor( MFORM_EX * cursor )
{
static unsigned char flags = 255;
static int number = 255;
if( flags == cursor->flags && number == cursor->number )
return;
if( cursor->flags & MFORM_EX_FLAG_USERFORM ) {
MouseSprite( cursor->tree, cursor->number);
} else {
graf_mouse(cursor->number, NULL );
}
number = cursor->number;
flags = cursor->flags;
}
void dbg_lgrect( char * str, LGRECT * r )
{
printf("%s: x: %d, y: %d, w: %d, h: %d\n", str,
r->g_x, r->g_y, r->g_w, r->g_h );
}
void dbg_grect( char * str, GRECT * r )
{
printf("%s: x: %d, y: %d, w: %d, h: %d\n", str,
r->g_x, r->g_y, r->g_w, r->g_h );
}
void dbg_pxy( char * str, short * pxy )
{
printf("%s: x: %d, y: %d, w: %d, h: %d\n", str,
pxy[0], pxy[1], pxy[2], pxy[3] );
}

38
atari/misc.h Normal file
View File

@ -0,0 +1,38 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NS_ATARI_MISC_H
#define NS_ATARI_MISC_H
#define SBUF8_TO_LBUF8(sbuf,lbuf)\
lbuf[0] = (long)sbuf[0];\
lbuf[1] = (long)sbuf[1];\
lbuf[2] = (long)sbuf[2];\
lbuf[3] = (long)sbuf[3];\
lbuf[4] = (long)sbuf[4];\
lbuf[5] = (long)sbuf[5];\
lbuf[6] = (long)sbuf[6];\
lbuf[7] = (long)sbuf[7];
struct gui_window * find_root_gui_window( WINDOW * win );
struct gui_window * find_cmp_window( COMPONENT * c );
OBJECT *get_tree( int idx );
char *get_rsc_string( int idx );
void gem_set_cursor( MFORM_EX * cursor );
void dbg_grect( char * str, GRECT * r );
#endif

73
atari/options.h Normal file
View File

@ -0,0 +1,73 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NS_ATARI_OPTIONS_H_
#define NS_ATARI_OPTIONS_H_
#include "desktop/options.h"
extern char * option_atari_screen_driver;
extern char * option_atari_font_driver;
extern int option_atari_font_monochrom;
extern int option_atari_dither;
extern int option_atari_transparency;
extern char *option_atari_face_sans_serif; /* default sans face */
extern char *option_atari_face_sans_serif_bold; /* bold sans face */
extern char *option_atari_face_sans_serif_italic; /* bold sans face */
extern char *option_atari_face_sans_serif_italic_bold; /* bold sans face */
extern char *option_atari_face_monospace; /* monospace face */
extern char *option_atari_face_monospace_bold; /* monospace face */
extern char *option_atari_face_serif; /* serif face */
extern char *option_atari_face_serif_bold; /* bold serif face */
extern char *option_atari_face_cursive;
extern char *option_atari_face_fantasy;
#define EXTRA_OPTION_DEFINE \
char * option_atari_screen_driver = (char*)"vdi";\
char * option_atari_font_driver = (char*)"vdi";\
int option_atari_font_monochrom = 0;\
int option_atari_dither = 1;\
int option_atari_transparency = 1;\
char *option_atari_face_sans_serif; \
char *option_atari_face_sans_serif_bold; \
char *option_atari_face_sans_serif_italic; \
char *option_atari_face_sans_serif_italic_bold; \
char *option_atari_face_monospace; \
char *option_atari_face_monospace_bold; \
char *option_atari_face_serif; \
char *option_atari_face_serif_bold; \
char *option_atari_face_cursive; \
char *option_atari_face_fantasy;
#define EXTRA_OPTION_TABLE \
{ "atari_screen_driver", OPTION_STRING, &option_atari_screen_driver },\
{ "atari_font_driver", OPTION_STRING, &option_atari_font_driver },\
{ "atari_font_monochrom", OPTION_INTEGER, &option_atari_font_monochrom },\
{ "atari_transparency", OPTION_INTEGER, &option_atari_transparency },\
{ "atari_dither", OPTION_INTEGER, &option_atari_dither },\
{ "font_face_sans_serif", OPTION_STRING, &option_atari_face_sans_serif },\
{ "font_face_sans_serif_bold", OPTION_STRING, &option_atari_face_sans_serif_bold },\
{ "font_face_sans_serif_italic", OPTION_STRING, &option_atari_face_sans_serif_italic },\
{ "font_face_sans_serif_italic_bold", OPTION_STRING, &option_atari_face_sans_serif_italic_bold },\
{ "font_face_monospace", OPTION_STRING, &option_atari_face_monospace },\
{ "font_face_monospace_bold", OPTION_STRING, &option_atari_face_monospace_bold },\
{ "font_face_serif", OPTION_STRING, &option_atari_face_serif },\
{ "font_face_serif_bold", OPTION_STRING, &option_atari_face_serif_bold },\
{ "font_face_cursive", OPTION_STRING, &option_atari_face_cursive },\
{ "font_face_fantasy", OPTION_STRING, &option_atari_face_fantasy }
#endif

222
atari/plot.c Normal file
View File

@ -0,0 +1,222 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sys/types.h>
#include <stdint.h>
#include <string.h>
#include <limits.h>
#include <math.h>
#include <stdbool.h>
#include <windom.h>
#include "image/bitmap.h"
#include "utils/log.h"
#include "utils/utf8.h"
#include "utils/utils.h"
#include "desktop/gui.h"
#include "desktop/plotters.h"
#include "atari/bitmap.h"
#include "atari/gui.h"
#include "atari/plot.h"
#include "atari/options.h"
#include "desktop/options.h"
#include "atari/plot.h"
GEM_PLOTTER plotter = NULL;
GEM_FONT_PLOTTER fplotter = NULL;
extern APPvar * appv;
extern short vdih;
/*
Init screen and font driver objects.
Returns non-zero value > -1 when the objects could be succesfully created.
Returns value < 0 to indicate an error
*/
int atari_plotter_init( char* drvrname, char * fdrvrname )
{
GRECT loc_pos={0,0,420,420};
int err=0;
struct s_driver_table_entry * drvinfo;
int flags = 0;
if( option_atari_dither == 1)
flags |= PLOT_FLAG_DITHER;
if( option_atari_transparency == 1 )
flags |= PLOT_FLAG_TRANS;
vdih = app.graf.handle;
if( verbose_log ) {
dump_vdi_info( vdih ) ;
dump_plot_drivers();
dump_font_drivers();
}
drvinfo = get_screen_driver_entry( drvrname );
LOG(("using plotters: %s, %s", drvrname, fdrvrname));
fplotter = new_font_plotter(vdih, fdrvrname, 0, &err );
if(err)
die(("Unable to load font plotter %s -> %s", fdrvrname, plotter_err_str(err) ));
plotter = new_plotter( vdih, drvrname, &loc_pos, drvinfo->max_bpp,
flags, fplotter, &err );
if(err)
die(("Unable to load graphics plotter %s -> %s", drvrname, plotter_err_str(err) ));
return( err );
}
int atari_plotter_finalise( void )
{
delete_plotter( plotter );
delete_font_plotter( fplotter );
}
bool plot_rectangle( int x0, int y0, int x1, int y1,
const plot_style_t *style )
{
plotter->rectangle( plotter, x0, y0, x1, y1, style );
return ( true );
}
static bool plot_line( int x0, int y0, int x1, int y1,
const plot_style_t *style )
{
plotter->line( plotter, x0, y0, x1, y1, style );
return ( true );
}
static bool plot_polygon(const int *p, unsigned int n,
const plot_style_t *style)
{
plotter->polygon( plotter, p, n, style );
return ( true );
}
bool plot_clip(int x0, int y0, int x1, int y1)
{
plotter->clip( plotter, x0, y0, x1, y1 );
return ( true );
}
bool plot_get_clip(struct s_clipping * out){
out->x0 = plotter->clipping.x0;
out->y0 = plotter->clipping.y0;
out->x1 = plotter->clipping.x1;
out->y1 = plotter->clipping.y1;
return( true );
}
static bool plot_text(int x, int y, const char *text, size_t length, const plot_font_style_t *fstyle )
{
plotter->text( plotter, x, y, text, length, fstyle );
return ( true );
}
static bool plot_disc(int x, int y, int radius, const plot_style_t *style)
{
plotter->disc(plotter, x, y, radius, style );
return ( true );
}
static bool plot_arc(int x, int y, int radius, int angle1, int angle2,
const plot_style_t *style)
{
plotter->arc( plotter, x, y, radius, angle1, angle2, style );
return ( true );
}
static bool plot_bitmap(int x, int y, int width, int height,
struct bitmap *bitmap, colour bg,
bitmap_flags_t flags)
{
struct bitmap * bm = NULL;
bool repeat_x = (flags & BITMAPF_REPEAT_X);
bool repeat_y = (flags & BITMAPF_REPEAT_Y);
if( option_suppress_images != 0 ) {
return( true );
}
if( width != bitmap_get_width(bitmap) || height != bitmap_get_height( bitmap) ) {
assert( plotter->bitmap_resize(plotter, bitmap, width, height ) == 0);
bm = bitmap->resized;
} else {
bm = bitmap;
}
/* out of memory? */
if( bm == NULL )
return( true );
if (!(repeat_x || repeat_y)) {
plotter->bitmap( plotter, bm, x, y, bg, flags );
} else {
int xf,yf;
struct s_clipping clip;
plotter_get_clip( plotter, &clip );
int xoff = x;
int yoff = y;
/* for now, repeating just works in the rigth / down direction */
/*
if( repeat_x == true )
xoff = clip.x0;
if(repeat_y == true )
yoff = clip.y0;
*/
for( xf = xoff; xf < clip.x1; xf += width ) {
for( yf = yoff; yf < clip.y1; yf += height ) {
plotter->bitmap( plotter, bm, xf, yf, bg, flags );
if (!repeat_y)
break;
}
if (!repeat_x)
break;
}
}
return ( true );
}
static bool plot_path(const float *p, unsigned int n, colour fill, float width,
colour c, const float transform[6])
{
plotter->path( plotter, p, n, fill, width, c, transform );
return ( true );
}
struct plotter_table plot = {
.rectangle = plot_rectangle,
.line = plot_line,
.polygon = plot_polygon,
.clip = plot_clip,
.text = plot_text,
.disc = plot_disc,
.arc = plot_arc,
.bitmap = plot_bitmap,
.path = plot_path,
.flush = NULL,
.group_start = NULL,
.group_end = NULL,
/*.option_knockout = false */
.option_knockout = true
};

32
atari/plot.h Normal file
View File

@ -0,0 +1,32 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NS_ATARI_PLOT_H
#define NS_ATARI_PLOT_H
#include "desktop/plotters.h"
#include "atari/plot/plotter.h"
int atari_plotter_init( char*, char * );
int atari_plotter_finalise( void );
bool plot_get_clip(struct s_clipping * out);
bool plot_clip(int x0, int y0, int x1, int y1);
bool plot_rectangle( int x0, int y0, int x1, int y1,const plot_style_t *style );
#endif

54
atari/plot/eddi.h Normal file
View File

@ -0,0 +1,54 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2009 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#ifndef _atari_eddi_h
#define _atari_eddi_h
/*--- Defines ---*/
/* EdDI versions */
#define EDDI_10 (0x0100)
#define EDDI_11 (0x0110)
/* Screen format */
enum {
VDI_FORMAT_UNKNOWN=-1,
VDI_FORMAT_INTER=0, /* Interleaved bitplanes */
VDI_FORMAT_VDI=1, /* VDI independent */
VDI_FORMAT_PACK=2 /* Packed pixels */
};
/* CLUT types */
enum {
VDI_CLUT_NONE=0, /* Monochrome mode */
VDI_CLUT_HARDWARE, /* <256 colours mode */
VDI_CLUT_SOFTWARE /* True colour mode */
};
/*--- Functions ---*/
unsigned long EdDI_version(void *function_pointer);
#endif /* atari_eddi_s_h */

42
atari/plot/eddi.s Normal file
View File

@ -0,0 +1,42 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2009 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
/*
*Read EdDI version
*
*Patrice Mandin
*/
.text
.globl _EdDI_version
/*--- Vector installer ---*/
_EdDI_version:
movel sp@(4),a0 /* Value of EdDI cookie */
/* Call EdDI function #0 */
clrl d0
jsr (a0)
rts

512
atari/plot/font_freetype.c Normal file
View File

@ -0,0 +1,512 @@
/*
* Copyright 2005 James Bursa <bursa@users.sourceforge.net>
* 2008 Vincent Sanders <vince@simtec.co.uk>
* 2011 Ole Loots <ole@monochrom.net>
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <string.h>
#include <windom.h>
#include <ft2build.h>
#include FT_CACHE_H
#include "desktop/plot_style.h"
#include "image/bitmap.h"
#include "atari/bitmap.h"
#include "atari/plot/plotter.h"
#include "atari/plot/font_freetype.h"
#include "atari/gui.h"
#include "atari/font.h"
#include "atari/options.h"
#include "atari/findfile.h"
#include "utils/utf8.h"
#include "utils/log.h"
#define DEJAVU_PATH "/usr/share/fonts/truetype/ttf-dejavu/"
static FT_Library library;
static FTC_Manager ft_cmanager;
static FTC_CMapCache ft_cmap_cache ;
static FTC_ImageCache ft_image_cache;
int ft_load_type;
/* cache manager faceID data to create freetype faceid on demand */
typedef struct ftc_faceid_s {
char *fontfile; /* path to font */
int index; /* index of font */
int cidx; /* character map index for unicode */
} ftc_faceid_t;
static struct bitmap * fontbmp;
static ftc_faceid_t *font_faces[FONT_FACE_COUNT];
static int dtor( FONT_PLOTTER self );
static int str_width( FONT_PLOTTER self,const plot_font_style_t *fstyle,
const char * str, size_t length, int * width );
static int str_split( FONT_PLOTTER self, const plot_font_style_t *fstyle,
const char *string, size_t length,int x,
size_t *char_offset, int *actual_x );
static int pixel_position( FONT_PLOTTER self, const plot_font_style_t *fstyle,
const char *string, size_t length,int x,
size_t *char_offset, int *actual_x );
static int text( FONT_PLOTTER self, int x, int y, const char *text,
size_t length, const plot_font_style_t *fstyle );
static bool init = false;
/* map cache manager handle to face id */
static FT_Error ft_face_requester(FTC_FaceID face_id, FT_Library library, FT_Pointer request_data, FT_Face *face )
{
FT_Error error;
ftc_faceid_t *ft_face = (ftc_faceid_t *)face_id;
int cidx;
error = FT_New_Face(library, ft_face->fontfile, ft_face->index, face);
if (error) {
LOG(("Could not find font (code %d)\n", error));
} else {
error = FT_Select_Charmap(*face, FT_ENCODING_UNICODE);
if (error) {
LOG(("Could not select charmap (code %d)\n", error));
} else {
for (cidx = 0; cidx < (*face)->num_charmaps; cidx++) {
if ((*face)->charmap == (*face)->charmaps[cidx]) {
ft_face->cidx = cidx;
break;
}
}
}
}
LOG(("Loaded face from %s\n", ft_face->fontfile));
return error;
}
/* create new framebuffer face and cause it to be loaded to check its ok */
static ftc_faceid_t *
ft_new_face(const char *option, const char *resname, const char *fontfile)
{
ftc_faceid_t *newf;
FT_Error error;
FT_Face aface;
char buf[PATH_MAX];
char resname2[PATH_MAX];
newf = calloc(1, sizeof(ftc_faceid_t));
if (option != NULL) {
newf->fontfile = strdup(option);
} else {
atari_find_resource(buf, resname, fontfile);
newf->fontfile = strdup(buf);
}
error = FTC_Manager_LookupFace(ft_cmanager, (FTC_FaceID)newf, &aface);
if (error) {
LOG(("Could not find font face %s (code %d)\n", fontfile, error));
free(newf);
newf = font_faces[FONT_FACE_DEFAULT]; /* use default */
}
return newf;
}
static void ft_fill_scalar(const plot_font_style_t *fstyle, FTC_Scaler srec)
{
int selected_face = FONT_FACE_DEFAULT;
switch (fstyle->family) {
/*
case PLOT_FONT_FAMILY_CURSIVE:
break;
case PLOT_FONT_FAMILY_FANTASY:
break;
*/
case PLOT_FONT_FAMILY_SERIF:
if (fstyle->weight >= 700)
selected_face = FONT_FACE_SERIF_BOLD;
else
selected_face = FONT_FACE_SERIF;
break;
case PLOT_FONT_FAMILY_MONOSPACE:
selected_face = FONT_FACE_MONOSPACE;
break;
case PLOT_FONT_FAMILY_SANS_SERIF:
default:
if ((fstyle->flags & FONTF_ITALIC) || (fstyle->flags & FONTF_OBLIQUE)) {
if (fstyle->weight >= 700)
selected_face = FONT_FACE_SANS_SERIF_ITALIC_BOLD;
else
selected_face = FONT_FACE_SANS_SERIF_ITALIC;
} else {
if (fstyle->weight >= 700)
selected_face = FONT_FACE_SANS_SERIF_BOLD;
else
selected_face = FONT_FACE_SANS_SERIF;
}
}
srec->face_id = (FTC_FaceID)font_faces[selected_face];
srec->width = srec->height = (fstyle->size * 64) / FONT_SIZE_SCALE;
srec->pixel = 0;
srec->x_res = srec->y_res = 72;
}
static FT_Glyph ft_getglyph(const plot_font_style_t *fstyle, uint32_t ucs4)
{
FT_UInt glyph_index;
FTC_ScalerRec srec;
FT_Glyph glyph;
FT_Error error;
ftc_faceid_t *ft_face;
ft_fill_scalar(fstyle, &srec);
ft_face = (ftc_faceid_t *)srec.face_id;
glyph_index = FTC_CMapCache_Lookup(ft_cmap_cache, srec.face_id, ft_face->cidx, ucs4);
error = FTC_ImageCache_LookupScaler(ft_image_cache,
&srec,
FT_LOAD_RENDER |
FT_LOAD_FORCE_AUTOHINT |
ft_load_type,
glyph_index,
&glyph,
NULL);
return glyph;
}
/* initialise font handling */
static bool ft_font_init(void)
{
FT_Error error;
FT_ULong max_cache_size;
FT_UInt max_faces = 6;
/* freetype library initialise */
error = FT_Init_FreeType( &library );
if (error) {
LOG(("Freetype could not initialised (code %d)\n", error));
return false;
}
max_cache_size = 2 * 1024 *1024; /* 2MB should be enough */
/* cache manager initialise */
error = FTC_Manager_New(library,
max_faces,
0,
max_cache_size,
ft_face_requester,
NULL,
&ft_cmanager);
if (error) {
LOG(("Freetype could not initialise cache manager (code %d)\n", error));
FT_Done_FreeType(library);
return false;
}
error = FTC_CMapCache_New(ft_cmanager, &ft_cmap_cache);
error = FTC_ImageCache_New(ft_cmanager, &ft_image_cache);
font_faces[FONT_FACE_SANS_SERIF] = NULL;
font_faces[FONT_FACE_SANS_SERIF] = ft_new_face(
option_atari_face_sans_serif,
"fonts/ss.ttf",
DEJAVU_PATH"DejaVuSans.ttf"
);
if (font_faces[FONT_FACE_SANS_SERIF] == NULL) {
LOG(("Could not find default font (code %d)\n", error));
FTC_Manager_Done(ft_cmanager );
FT_Done_FreeType(library);
return false;
}
font_faces[FONT_FACE_SANS_SERIF_BOLD] =
ft_new_face(option_atari_face_sans_serif_bold,
"fonts/ssb.ttf",
DEJAVU_PATH"DejaVuSans-Bold.ttf");
font_faces[FONT_FACE_SANS_SERIF_ITALIC] =
ft_new_face(option_atari_face_sans_serif_italic,
"fonts/ssi.ttf",
DEJAVU_PATH"DejaVuSans-Oblique.ttf");
font_faces[FONT_FACE_SANS_SERIF_ITALIC_BOLD] =
ft_new_face(option_atari_face_sans_serif_italic_bold,
"fonts/ssib.ttf",
DEJAVU_PATH"DejaVuSans-BoldOblique.ttf");
font_faces[FONT_FACE_MONOSPACE] =
ft_new_face(option_atari_face_monospace,
"fonts/mono.ttf",
DEJAVU_PATH"DejaVuSansMono.ttf");
font_faces[FONT_FACE_MONOSPACE_BOLD] =
ft_new_face(option_atari_face_monospace_bold,
"fonts/monob.ttf",
DEJAVU_PATH"DejaVuSansMono-Bold.ttf");
font_faces[FONT_FACE_SERIF] =
ft_new_face(option_atari_face_serif,
"fonts/s.ttf",
DEJAVU_PATH"DejaVuSerif.ttf");
font_faces[FONT_FACE_SERIF_BOLD] =
ft_new_face(option_atari_face_serif_bold,
"fonts/sb.ttf",
DEJAVU_PATH"DejaVuSerif-Bold.ttf");
font_faces[FONT_FACE_CURSIVE] =
ft_new_face(option_atari_face_cursive,
"fonts/cursive.ttf",
DEJAVU_PATH"DejaVuSansMono-Oblique.ttf");
font_faces[FONT_FACE_FANTASY] =
ft_new_face(option_atari_face_fantasy,
"fonts/fantasy.ttf",
DEJAVU_PATH"DejaVuSerifCondensed-Bold.ttf");
/* set the default render mode */
if (option_atari_font_monochrom == true)
ft_load_type = FT_LOAD_MONOCHROME;
else
ft_load_type = 0;
return true;
}
static bool ft_font_finalise(void)
{
FTC_Manager_Done(ft_cmanager );
FT_Done_FreeType(library);
return true;
}
static int str_width( FONT_PLOTTER self,const plot_font_style_t *fstyle,
const char *string, size_t length,
int *width)
{
uint32_t ucs4;
size_t nxtchr = 0;
FT_Glyph glyph;
*width = 0;
while (nxtchr < length) {
ucs4 = utf8_to_ucs4(string + nxtchr, length - nxtchr);
nxtchr = utf8_next(string, length, nxtchr);
glyph = ft_getglyph(fstyle, ucs4);
if (glyph == NULL)
continue;
*width += glyph->advance.x >> 16;
}
return(1);
}
static int str_split( FONT_PLOTTER self, const plot_font_style_t *fstyle,
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x)
{
uint32_t ucs4;
size_t nxtchr = 0;
int last_space_x = 0;
int last_space_idx = 0;
FT_Glyph glyph;
*actual_x = 0;
while (nxtchr < length) {
ucs4 = utf8_to_ucs4(string + nxtchr, length - nxtchr);
glyph = ft_getglyph(fstyle, ucs4);
if (glyph == NULL)
continue;
if (ucs4 == 0x20) {
last_space_x = *actual_x;
last_space_idx = nxtchr;
}
*actual_x += glyph->advance.x >> 16;
if (*actual_x > x) {
/* string has exceeded available width return previous space*/
*actual_x = last_space_x;
*char_offset = last_space_idx;
return true;
}
nxtchr = utf8_next(string, length, nxtchr);
}
*char_offset = nxtchr;
return (1);
}
static int pixel_position( FONT_PLOTTER self, const plot_font_style_t *fstyle,
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x)
{
uint32_t ucs4;
size_t nxtchr = 0;
FT_Glyph glyph;
*actual_x = 0;
while (nxtchr < length) {
ucs4 = utf8_to_ucs4(string + nxtchr, length - nxtchr);
glyph = ft_getglyph(fstyle, ucs4);
if (glyph == NULL)
continue;
*actual_x += glyph->advance.x >> 16;
if (*actual_x > x)
break;
nxtchr = utf8_next(string, length, nxtchr);
}
*char_offset = nxtchr;
return ( 1 );
}
static void draw_glyph8(FONT_PLOTTER self, GRECT * loc, uint8_t * pixdata, int pitch, uint32_t colour)
{
GRECT clip;
uint32_t * linebuf;
uint32_t fontpix;
size_t bmpstride;
int xloop,yloop,xoff,yoff;
int x,y,w,h;
x = loc->g_x;
y = loc->g_y;
w = loc->g_w;
h = loc->g_h;
clip.g_x = self->plotter->clipping.x0;
clip.g_y = self->plotter->clipping.y0;
clip.g_w = self->plotter->clipping.x1 - self->plotter->clipping.x0;
clip.g_h = self->plotter->clipping.y1 - self->plotter->clipping.y0;
if( !rc_intersect( &clip, loc ) ){
return;
}
assert( loc->g_w > 0 );
assert( loc->g_h > 0 );
xoff = loc->g_x - x;
yoff = loc->g_y - y;
if (h > loc->g_h)
h = loc->g_h;
if (w > loc->g_w)
w = loc->g_w;
fontbmp = bitmap_realloc( w, h,
fontbmp->bpp, w * fontbmp->bpp,
BITMAP_GROW, fontbmp );
assert( fontbmp );
assert( fontbmp->pixdata );
bmpstride = bitmap_get_rowstride(fontbmp);
for( yloop = 0; yloop < h; yloop++) {
linebuf = (uint32_t *)(fontbmp->pixdata + (bmpstride * yloop));
for(xloop = 0; xloop < w; xloop++){
fontpix = (uint32_t)(pixdata[(( yoff + yloop ) * pitch) + xloop + xoff]);
linebuf[xloop] = (uint32_t)(colour | fontpix);
}
}
self->plotter->bitmap( self->plotter, fontbmp, loc->g_x, loc->g_y, 0, 0);
}
static int text( FONT_PLOTTER self, int x, int y, const char *text, size_t length,
const plot_font_style_t *fstyle )
{
uint32_t ucs4;
size_t nxtchr = 0;
FT_Glyph glyph;
FT_BitmapGlyph bglyph;
GRECT loc, clip;
uint32_t c = fstyle->foreground ;
/* in -> BGR */
/* out -> ARGB */
c = ABGR_TO_RGB(c);
clip.g_x = self->plotter->clipping.x0;
clip.g_y = self->plotter->clipping.y0;
clip.g_w = self->plotter->clipping.x1 - self->plotter->clipping.x0;
clip.g_h = self->plotter->clipping.y1 - self->plotter->clipping.y0;
while (nxtchr < length) {
ucs4 = utf8_to_ucs4(text + nxtchr, length - nxtchr);
nxtchr = utf8_next(text, length, nxtchr);
glyph = ft_getglyph(fstyle, ucs4);
if (glyph == NULL)
continue;
if (glyph->format == FT_GLYPH_FORMAT_BITMAP) {
bglyph = (FT_BitmapGlyph)glyph;
loc.g_x = x + bglyph->left;
loc.g_y = y - bglyph->top;
loc.g_w = bglyph->bitmap.width;
loc.g_h = bglyph->bitmap.rows;
if (bglyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {
assert( 1 == 0 );
} else {
if( loc.g_w > 0) {
draw_glyph8( self,
&loc,
bglyph->bitmap.buffer,
bglyph->bitmap.pitch,
c
);
}
}
}
x += glyph->advance.x >> 16;
}
return( 0 );
}
int ctor_font_plotter_freetype( FONT_PLOTTER self )
{
self->dtor = dtor;
self->str_width = str_width;
self->str_split = str_split;
self->pixel_position = pixel_position;
self->text = text;
LOG(("%s: %s\n", (char*)__FILE__, __FUNCTION__));
if( !init ) {
ft_font_init();
fontbmp = bitmap_create(48, 48, 0);
fontbmp->opaque = false;
init = true;
}
return( 1 );
}
static int dtor( FONT_PLOTTER self )
{
ft_font_finalise();
if( fontbmp == NULL )
bitmap_destroy( fontbmp );
return( 1 );
}

View File

@ -0,0 +1,51 @@
/*
* Copyright 2011 Ole Loots <ole@monochrom.net>
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef FONT_PLOTTER_FREETYPE
#define FONT_PLOTTER_FREETYPE
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include "utils/utf8.h"
/* defines for accesing the faces */
#define FONT_FACE_DEFAULT 0
#define FONT_FACE_SANS_SERIF 0
#define FONT_FACE_SANS_SERIF_BOLD 1
#define FONT_FACE_SANS_SERIF_ITALIC 2
#define FONT_FACE_SANS_SERIF_ITALIC_BOLD 3
#define FONT_FACE_MONOSPACE 4
#define FONT_FACE_MONOSPACE_BOLD 5
#define FONT_FACE_SERIF 6
#define FONT_FACE_SERIF_BOLD 7
#define FONT_FACE_CURSIVE 8
#define FONT_FACE_FANTASY 9
#define FONT_FACE_COUNT 10
struct font_desc {
const char *name;
int width, height;
const char *encoding;
};
/* extern int ft_load_type; */
int ctor_font_plotter_freetype( FONT_PLOTTER self );
#endif

216
atari/plot/font_vdi.c Normal file
View File

@ -0,0 +1,216 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <string.h>
#include <windom.h>
#include "desktop/plot_style.h"
#include "atari/bitmap.h"
#include "atari/plot/plotter.h"
#include "atari/plot/font_vdi.h"
#include "utils/utf8.h"
#include "utils/log.h"
static char * lstr = NULL;
static int dtor( FONT_PLOTTER self );
static int str_width( FONT_PLOTTER self,const plot_font_style_t *fstyle, const char * str, size_t length, int * width );
static int str_split( FONT_PLOTTER self, const plot_font_style_t *fstyle,const char *string,
size_t length,int x, size_t *char_offset, int *actual_x );
static int pixel_position( FONT_PLOTTER self, const plot_font_style_t *fstyle,const char *string,
size_t length,int x, size_t *char_offset, int *actual_x );
static int text( FONT_PLOTTER self, int x, int y, const char *text, size_t length, const plot_font_style_t *fstyle );
static bool init = false;
static int vdih;
int ctor_font_plotter_vdi( FONT_PLOTTER self )
{
self->dtor = dtor;
self->str_width = str_width;
self->str_split = str_split;
self->pixel_position = pixel_position;
self->text = text;
LOG(("%s: %s\n", (char*)__FILE__, __FUNCTION__));
if( !init ) {
vdih = self->vdi_handle;
}
init = true;
return( 1 );
}
static int dtor( FONT_PLOTTER self )
{
return( 1 );
}
static int str_width( FONT_PLOTTER self,const plot_font_style_t *fstyle, const char * str,
size_t length, int * width )
{
short cw, ch, cellw, cellh;
short pxsize;
short fx=0;
lstr = (char*)str;
utf8_to_enc(str, "ATARIST", length, &lstr );
assert( lstr != NULL );
int slen = strlen(lstr);
if( fstyle->flags & FONTF_ITALIC )
fx |= 4;
if( fstyle->flags & FONTF_OBLIQUE )
fx |= 16;
if( fstyle->weight > 450 )
fx |= 1;
vst_effects( self->vdi_handle, fx );
/* TODO: replace 90 with global dpi setting */
pxsize = ceil( (fstyle->size/FONT_SIZE_SCALE) * 90 / 72 );
vst_height( self->vdi_handle, pxsize ,&cw, &ch, &cellw, &cellh);
*width = slen * cellw;
free( (void*)lstr );
lstr = NULL;
return( 0 );
}
static int str_split( FONT_PLOTTER self, const plot_font_style_t * fstyle, const char *string,
size_t length,int x, size_t *char_offset, int *actual_x )
{
short cw, ch, cellw, cellh;
short pxsize;
short fx=0;
int i;
lstr = (char*)string;
int slen = 0;
int last_space_x = 0;
int last_space_idx = 0;
utf8_to_enc(string, "ATARIST", length, &lstr );
assert( lstr != NULL );
slen = strlen(lstr);
if( fstyle->flags & FONTF_ITALIC )
fx |= 4;
if( fstyle->flags & FONTF_OBLIQUE )
fx |= 16;
if( fstyle->weight > 450 )
fx |= 1;
vst_effects( self->vdi_handle, fx );
pxsize = ceil( (fstyle->size/FONT_SIZE_SCALE) * 90 / 72 );
vst_height( self->vdi_handle, pxsize ,&cw, &ch, &cellw, &cellh);
*actual_x = 0;
*char_offset = 0;
int cpos=0;
for( i=0; i<slen; i++) {
if( lstr[i] == ' ' ) {
last_space_x = *actual_x;
last_space_idx = cpos;
}
if( *actual_x > x ) {
*actual_x = last_space_x;
*char_offset = last_space_idx;
return true;
}
*actual_x += cellw;
cpos++;
}
*char_offset = cpos;
free( (void*)lstr );
lstr = NULL;
return( 0 );
}
static int pixel_position( FONT_PLOTTER self, const plot_font_style_t * fstyle,const char *string,
size_t length,int x, size_t *char_offset, int *actual_x )
{
short cw, ch, cellw, cellh;
short pxsize=0;
short fx=0;
lstr = (char*)string;
int i=0;
int curpx=0;
utf8_to_enc(string, "ATRIST", length, &lstr );
assert( lstr != NULL );
int slen = strlen(lstr);
if( fstyle->flags & FONTF_ITALIC )
fx |= 4;
if( fstyle->flags & FONTF_OBLIQUE )
fx |= 16;
if( fstyle->weight > 450 )
fx |= 1;
vst_effects( self->vdi_handle, fx );
pxsize = ceil( (fstyle->size/FONT_SIZE_SCALE) * 90 / 72 );
vst_height( self->vdi_handle, pxsize ,&cw, &ch, &cellw, &cellh);
*actual_x = 0;
*char_offset = 0;
for( i=0; i<slen; i++) {
*actual_x += cellw;
if( *actual_x > x) {
*actual_x -= cellw;
*char_offset = i;
break;
}
}
free( (void*)lstr );
lstr = NULL;
return( 0 );
}
static int text( FONT_PLOTTER self, int x, int y, const char *text, size_t length,
const plot_font_style_t *fstyle )
{
/* todo: either limit the string to max 80 chars, or use v_ftext instead of v_gtext */
short cw, ch, cellw, cellh;
short pxsize=8;
short fx=0;
lstr = (char*)text;
utf8_to_enc(text, "ATARIST", length, &lstr );
assert( lstr != NULL );
int slen = strlen(lstr);
size_t mylen = MIN(511, slen );
char textcpy[mylen+1];
textcpy[mylen] = 0;
strncpy((char*)&textcpy, lstr, mylen+1 );
if( fstyle != NULL){
if( fstyle->flags & FONTF_ITALIC )
fx |= 4;
if( fstyle->flags & FONTF_OBLIQUE )
fx |= 4;
if( fstyle->weight > 450 )
fx |= 1;
/* TODO: netsurf uses 90 as default dpi ( somewhere defined in libcss), use that value
pass it as arg, to reduce netsurf dependency */
pxsize = ceil( (fstyle->size/FONT_SIZE_SCALE) * 90 / 72 );
}
vst_effects( self->vdi_handle, fx );
vst_alignment(vdih, 0, 4, &cw, &ch );
vst_height( self->vdi_handle, pxsize ,&cw, &ch, &cellw, &cellh);
vswr_mode( self->vdi_handle, MD_TRANS );
vst_color( self->vdi_handle, RGB_TO_VDI(fstyle->foreground) );
x += CURFB(self->plotter).x;
y += CURFB(self->plotter).y;
v_ftext( self->vdi_handle, x, y, (char*)&textcpy );
free( lstr );
return( 0 );
}

23
atari/plot/font_vdi.h Normal file
View File

@ -0,0 +1,23 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef FONT_PLOTTER_VDI
#define FONT_PLOTTER_VDI
int ctor_font_plotter_vdi( FONT_PLOTTER self );
#endif

723
atari/plot/plotter.c Normal file
View File

@ -0,0 +1,723 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <windom.h>
#include <assert.h>
#include <mint/osbind.h>
#include <mint/cookie.h>
#include <Hermes/Hermes.h>
#include "desktop/plot_style.h"
#include "atari/bitmap.h"
#include "image/bitmap.h"
#include "atari/plot/eddi.h"
#include "atari/plot/plotter.h"
#include "atari/plot/plotter_vdi.h"
#include "atari/plot/font_vdi.h"
#include "atari/plot/font_freetype.h"
#include "utils/log.h"
unsigned char rgb_web_pal[216][3] = {
{0x00,0x00,0x00}, {0x33,0x00,0x00}, {0x66,0x00,0x00}, {0x99,0x00,0x00}, {0xcc,0x00,0x00}, {0xff,0x00,0x00},
{0x00,0x33,0x00}, {0x33,0x33,0x00}, {0x66,0x33,0x00}, {0x99,0x33,0x00}, {0xcc,0x33,0x00}, {0xff,0x33,0x00},
{0x00,0x66,0x00}, {0x33,0x66,0x00}, {0x66,0x66,0x00}, {0x99,0x66,0x00}, {0xcc,0x66,0x00}, {0xff,0x66,0x00},
{0x00,0x99,0x00}, {0x33,0x99,0x00}, {0x66,0x99,0x00}, {0x99,0x99,0x00}, {0xcc,0x99,0x00}, {0xff,0x99,0x00},
{0x00,0xcc,0x00}, {0x33,0xcc,0x00}, {0x66,0xcc,0x00}, {0x99,0xcc,0x00}, {0xcc,0xcc,0x00}, {0xff,0xcc,0x00},
{0x00,0xff,0x00}, {0x33,0xff,0x00}, {0x66,0xff,0x00}, {0x99,0xff,0x00}, {0xcc,0xff,0x00}, {0xff,0xff,0x00},
{0x00,0x00,0x33}, {0x33,0x00,0x33}, {0x66,0x00,0x33}, {0x99,0x00,0x33}, {0xcc,0x00,0x33}, {0xff,0x00,0x33},
{0x00,0x33,0x33}, {0x33,0x33,0x33}, {0x66,0x33,0x33}, {0x99,0x33,0x33}, {0xcc,0x33,0x33}, {0xff,0x33,0x33},
{0x00,0x66,0x33}, {0x33,0x66,0x33}, {0x66,0x66,0x33}, {0x99,0x66,0x33}, {0xcc,0x66,0x33}, {0xff,0x66,0x33},
{0x00,0x99,0x33}, {0x33,0x99,0x33}, {0x66,0x99,0x33}, {0x99,0x99,0x33}, {0xcc,0x99,0x33}, {0xff,0x99,0x33},
{0x00,0xcc,0x33}, {0x33,0xcc,0x33}, {0x66,0xcc,0x33}, {0x99,0xcc,0x33}, {0xcc,0xcc,0x33}, {0xff,0xcc,0x33},
{0x00,0xff,0x33}, {0x33,0xff,0x33}, {0x66,0xff,0x33}, {0x99,0xff,0x33}, {0xcc,0xff,0x33}, {0xff,0xff,0x33},
{0x00,0x00,0x66}, {0x33,0x00,0x66}, {0x66,0x00,0x66}, {0x99,0x00,0x66}, {0xcc,0x00,0x66}, {0xff,0x00,0x66},
{0x00,0x33,0x66}, {0x33,0x33,0x66}, {0x66,0x33,0x66}, {0x99,0x33,0x66}, {0xcc,0x33,0x66}, {0xff,0x33,0x66},
{0x00,0x66,0x66}, {0x33,0x66,0x66}, {0x66,0x66,0x66}, {0x99,0x66,0x66}, {0xcc,0x66,0x66}, {0xff,0x66,0x66},
{0x00,0x99,0x66}, {0x33,0x99,0x66}, {0x66,0x99,0x66}, {0x99,0x99,0x66}, {0xcc,0x99,0x66}, {0xff,0x99,0x66},
{0x00,0xcc,0x66}, {0x33,0xcc,0x66}, {0x66,0xcc,0x66}, {0x99,0xcc,0x66}, {0xcc,0xcc,0x66}, {0xff,0xcc,0x66},
{0x00,0xff,0x66}, {0x33,0xff,0x66}, {0x66,0xff,0x66}, {0x99,0xff,0x66}, {0xcc,0xff,0x66}, {0xff,0xff,0x66},
{0x00,0x00,0x99}, {0x33,0x00,0x99}, {0x66,0x00,0x99}, {0x99,0x00,0x99}, {0xcc,0x00,0x99}, {0xff,0x00,0x99},
{0x00,0x33,0x99}, {0x33,0x33,0x99}, {0x66,0x33,0x99}, {0x99,0x33,0x99}, {0xcc,0x33,0x99}, {0xff,0x33,0x99},
{0x00,0x66,0x99}, {0x33,0x66,0x99}, {0x66,0x66,0x99}, {0x99,0x66,0x99}, {0xcc,0x66,0x99}, {0xff,0x66,0x99},
{0x00,0x99,0x99}, {0x33,0x99,0x99}, {0x66,0x99,0x99}, {0x99,0x99,0x99}, {0xcc,0x99,0x99}, {0xff,0x99,0x99},
{0x00,0xcc,0x99}, {0x33,0xcc,0x99}, {0x66,0xcc,0x99}, {0x99,0xcc,0x99}, {0xcc,0xcc,0x99}, {0xff,0xcc,0x99},
{0x00,0xff,0x99}, {0x33,0xff,0x99}, {0x66,0xff,0x99}, {0x99,0xff,0x99}, {0xcc,0xff,0x99}, {0xff,0xff,0x99},
{0x00,0x00,0xcc}, {0x33,0x00,0xcc}, {0x66,0x00,0xcc}, {0x99,0x00,0xcc}, {0xcc,0x00,0xcc}, {0xff,0x00,0xcc},
{0x00,0x33,0xcc}, {0x33,0x33,0xcc}, {0x66,0x33,0xcc}, {0x99,0x33,0xcc}, {0xcc,0x33,0xcc}, {0xff,0x33,0xcc},
{0x00,0x66,0xcc}, {0x33,0x66,0xcc}, {0x66,0x66,0xcc}, {0x99,0x66,0xcc}, {0xcc,0x66,0xcc}, {0xff,0x66,0xcc},
{0x00,0x99,0xcc}, {0x33,0x99,0xcc}, {0x66,0x99,0xcc}, {0x99,0x99,0xcc}, {0xcc,0x99,0xcc}, {0xff,0x99,0xcc},
{0x00,0xcc,0xcc}, {0x33,0xcc,0xcc}, {0x66,0xcc,0xcc}, {0x99,0xcc,0xcc}, {0xcc,0xcc,0xcc}, {0xff,0xcc,0xcc},
{0x00,0xff,0xcc}, {0x33,0xff,0xcc}, {0x66,0xff,0xcc}, {0x99,0xff,0xcc}, {0xcc,0xff,0xcc}, {0xff,0xff,0xcc},
{0x00,0x00,0xff}, {0x33,0x00,0xff}, {0x66,0x00,0xff}, {0x99,0x00,0xff}, {0xcc,0x00,0xff}, {0xff,0x00,0xff},
{0x00,0x33,0xff}, {0x33,0x33,0xff}, {0x66,0x33,0xff}, {0x99,0x33,0xff}, {0xcc,0x33,0xff}, {0xff,0x33,0xff},
{0x00,0x66,0xff}, {0x33,0x66,0xff}, {0x66,0x66,0xff}, {0x99,0x66,0xff}, {0xcc,0x66,0xff}, {0xff,0x66,0xff},
{0x00,0x99,0xff}, {0x33,0x99,0xff}, {0x66,0x99,0xff}, {0x99,0x99,0xff}, {0xcc,0x99,0xff}, {0xff,0x99,0xff},
{0x00,0xcc,0xff}, {0x33,0xcc,0xff}, {0x66,0xcc,0xff}, {0x99,0xcc,0xff}, {0xcc,0xcc,0xff}, {0xff,0xcc,0xff},
{0x00,0xff,0xff}, {0x33,0xff,0xff}, {0x66,0xff,0xff}, {0x99,0xff,0xff}, {0xcc,0xff,0xff}, {0xff,0xff,0xff}
};
unsigned short vdi_web_pal[216][3] = {
{0x000,0x000,0x000}, {0x0c8,0x000,0x000}, {0x190,0x000,0x000}, {0x258,0x000,0x000}, {0x320,0x000,0x000}, {0x3e8,0x000,0x000},
{0x000,0x0c8,0x000}, {0x0c8,0x0c8,0x000}, {0x190,0x0c8,0x000}, {0x258,0x0c8,0x000}, {0x320,0x0c8,0x000}, {0x3e8,0x0c8,0x000},
{0x000,0x190,0x000}, {0x0c8,0x190,0x000}, {0x190,0x190,0x000}, {0x258,0x190,0x000}, {0x320,0x190,0x000}, {0x3e8,0x190,0x000},
{0x000,0x258,0x000}, {0x0c8,0x258,0x000}, {0x190,0x258,0x000}, {0x258,0x258,0x000}, {0x320,0x258,0x000}, {0x3e8,0x258,0x000},
{0x000,0x320,0x000}, {0x0c8,0x320,0x000}, {0x190,0x320,0x000}, {0x258,0x320,0x000}, {0x320,0x320,0x000}, {0x3e8,0x320,0x000},
{0x000,0x3e8,0x000}, {0x0c8,0x3e8,0x000}, {0x190,0x3e8,0x000}, {0x258,0x3e8,0x000}, {0x320,0x3e8,0x000}, {0x3e8,0x3e8,0x000},
{0x000,0x000,0x0c8}, {0x0c8,0x000,0x0c8}, {0x190,0x000,0x0c8}, {0x258,0x000,0x0c8}, {0x320,0x000,0x0c8}, {0x3e8,0x000,0x0c8},
{0x000,0x0c8,0x0c8}, {0x0c8,0x0c8,0x0c8}, {0x190,0x0c8,0x0c8}, {0x258,0x0c8,0x0c8}, {0x320,0x0c8,0x0c8}, {0x3e8,0x0c8,0x0c8},
{0x000,0x190,0x0c8}, {0x0c8,0x190,0x0c8}, {0x190,0x190,0x0c8}, {0x258,0x190,0x0c8}, {0x320,0x190,0x0c8}, {0x3e8,0x190,0x0c8},
{0x000,0x258,0x0c8}, {0x0c8,0x258,0x0c8}, {0x190,0x258,0x0c8}, {0x258,0x258,0x0c8}, {0x320,0x258,0x0c8}, {0x3e8,0x258,0x0c8},
{0x000,0x320,0x0c8}, {0x0c8,0x320,0x0c8}, {0x190,0x320,0x0c8}, {0x258,0x320,0x0c8}, {0x320,0x320,0x0c8}, {0x3e8,0x320,0x0c8},
{0x000,0x3e8,0x0c8}, {0x0c8,0x3e8,0x0c8}, {0x190,0x3e8,0x0c8}, {0x258,0x3e8,0x0c8}, {0x320,0x3e8,0x0c8}, {0x3e8,0x3e8,0x0c8},
{0x000,0x000,0x190}, {0x0c8,0x000,0x190}, {0x190,0x000,0x190}, {0x258,0x000,0x190}, {0x320,0x000,0x190}, {0x3e8,0x000,0x190},
{0x000,0x0c8,0x190}, {0x0c8,0x0c8,0x190}, {0x190,0x0c8,0x190}, {0x258,0x0c8,0x190}, {0x320,0x0c8,0x190}, {0x3e8,0x0c8,0x190},
{0x000,0x190,0x190}, {0x0c8,0x190,0x190}, {0x190,0x190,0x190}, {0x258,0x190,0x190}, {0x320,0x190,0x190}, {0x3e8,0x190,0x190},
{0x000,0x258,0x190}, {0x0c8,0x258,0x190}, {0x190,0x258,0x190}, {0x258,0x258,0x190}, {0x320,0x258,0x190}, {0x3e8,0x258,0x190},
{0x000,0x320,0x190}, {0x0c8,0x320,0x190}, {0x190,0x320,0x190}, {0x258,0x320,0x190}, {0x320,0x320,0x190}, {0x3e8,0x320,0x190},
{0x000,0x3e8,0x190}, {0x0c8,0x3e8,0x190}, {0x190,0x3e8,0x190}, {0x258,0x3e8,0x190}, {0x320,0x3e8,0x190}, {0x3e8,0x3e8,0x190},
{0x000,0x000,0x258}, {0x0c8,0x000,0x258}, {0x190,0x000,0x258}, {0x258,0x000,0x258}, {0x320,0x000,0x258}, {0x3e8,0x000,0x258},
{0x000,0x0c8,0x258}, {0x0c8,0x0c8,0x258}, {0x190,0x0c8,0x258}, {0x258,0x0c8,0x258}, {0x320,0x0c8,0x258}, {0x3e8,0x0c8,0x258},
{0x000,0x190,0x258}, {0x0c8,0x190,0x258}, {0x190,0x190,0x258}, {0x258,0x190,0x258}, {0x320,0x190,0x258}, {0x3e8,0x190,0x258},
{0x000,0x258,0x258}, {0x0c8,0x258,0x258}, {0x190,0x258,0x258}, {0x258,0x258,0x258}, {0x320,0x258,0x258}, {0x3e8,0x258,0x258},
{0x000,0x320,0x258}, {0x0c8,0x320,0x258}, {0x190,0x320,0x258}, {0x258,0x320,0x258}, {0x320,0x320,0x258}, {0x3e8,0x320,0x258},
{0x000,0x3e8,0x258}, {0x0c8,0x3e8,0x258}, {0x190,0x3e8,0x258}, {0x258,0x3e8,0x258}, {0x320,0x3e8,0x258}, {0x3e8,0x3e8,0x258},
{0x000,0x000,0x320}, {0x0c8,0x000,0x320}, {0x190,0x000,0x320}, {0x258,0x000,0x320}, {0x320,0x000,0x320}, {0x3e8,0x000,0x320},
{0x000,0x0c8,0x320}, {0x0c8,0x0c8,0x320}, {0x190,0x0c8,0x320}, {0x258,0x0c8,0x320}, {0x320,0x0c8,0x320}, {0x3e8,0x0c8,0x320},
{0x000,0x190,0x320}, {0x0c8,0x190,0x320}, {0x190,0x190,0x320}, {0x258,0x190,0x320}, {0x320,0x190,0x320}, {0x3e8,0x190,0x320},
{0x000,0x258,0x320}, {0x0c8,0x258,0x320}, {0x190,0x258,0x320}, {0x258,0x258,0x320}, {0x320,0x258,0x320}, {0x3e8,0x258,0x320},
{0x000,0x320,0x320}, {0x0c8,0x320,0x320}, {0x190,0x320,0x320}, {0x258,0x320,0x320}, {0x320,0x320,0x320}, {0x3e8,0x320,0x320},
{0x000,0x3e8,0x320}, {0x0c8,0x3e8,0x320}, {0x190,0x3e8,0x320}, {0x258,0x3e8,0x320}, {0x320,0x3e8,0x320}, {0x3e8,0x3e8,0x320},
{0x000,0x000,0x3e8}, {0x0c8,0x000,0x3e8}, {0x190,0x000,0x3e8}, {0x258,0x000,0x3e8}, {0x320,0x000,0x3e8}, {0x3e8,0x000,0x3e8},
{0x000,0x0c8,0x3e8}, {0x0c8,0x0c8,0x3e8}, {0x190,0x0c8,0x3e8}, {0x258,0x0c8,0x3e8}, {0x320,0x0c8,0x3e8}, {0x3e8,0x0c8,0x3e8},
{0x000,0x190,0x3e8}, {0x0c8,0x190,0x3e8}, {0x190,0x190,0x3e8}, {0x258,0x190,0x3e8}, {0x320,0x190,0x3e8}, {0x3e8,0x190,0x3e8},
{0x000,0x258,0x3e8}, {0x0c8,0x258,0x3e8}, {0x190,0x258,0x3e8}, {0x258,0x258,0x3e8}, {0x320,0x258,0x3e8}, {0x3e8,0x258,0x3e8},
{0x000,0x320,0x3e8}, {0x0c8,0x320,0x3e8}, {0x190,0x320,0x3e8}, {0x258,0x320,0x3e8}, {0x320,0x320,0x3e8}, {0x3e8,0x320,0x3e8},
{0x000,0x3e8,0x3e8}, {0x0c8,0x3e8,0x3e8}, {0x190,0x3e8,0x3e8}, {0x258,0x3e8,0x3e8}, {0x320,0x3e8,0x3e8}, {0x3e8,0x3e8,0x3e8}
};
static short prev_vdi_clip[4];
struct s_vdi_sysinfo vdi_sysinfo;
struct s_driver_table_entry screen_driver_table[] =
{
{(char*)"vdi", ctor_plotter_vdi, 0, 32},
{(char*)"screen.ldg", ctor_plotter_vdi, PLOT_FLAG_OFFSCREEN, 32 },
{(char*)"vdi_offscreen", ctor_plotter_vdi, PLOT_FLAG_OFFSCREEN, 32},
{(char*)NULL, NULL, 0, 0 }
};
const struct s_font_driver_table_entry font_driver_table[] =
{
{(char*)"vdi", ctor_font_plotter_vdi, 0},
{(char*)"freetype", ctor_font_plotter_freetype, 0},
{(char*)NULL, NULL, 0}
};
struct s_vdi_sysinfo * read_vdi_sysinfo( short vdih, struct s_vdi_sysinfo * info ) {
unsigned long cookie_EdDI=0;
short out[300];
memset( info, 0, sizeof(struct s_vdi_sysinfo) );
info->vdi_handle = vdih;
if ( Getcookie(C_EdDI, &cookie_EdDI) == C_NOTFOUND ) {
info->EdDiVersion = 0;
} else {
info->EdDiVersion = EdDI_version( (void *)cookie_EdDI );
}
memset( &out, 0, sizeof(short)*300 );
vq_extnd( vdih, 0, (short*)&out );
info->scr_w = out[0]+1;
info->scr_h = out[1]+1;
if( out[39] == 2 ) {
info->scr_bpp = 1;
info->colors = out[39];
} else {
info->colors = out[39];
}
memset( &out, 0, sizeof(short)*300 );
vq_extnd( vdih, 1, (short*)&out );
info->scr_bpp = out[4];
info->maxpolycoords = out[14];
info->maxintin = out[15];
if( out[30] & 1 ) {
info->rasterscale = true;
} else {
info->rasterscale = false;
}
switch( info->scr_bpp ) {
case 8:
info->pixelsize=1;
break;
case 15:
case 16:
info->pixelsize=2;
break;
case 24:
info->pixelsize=3;
break;
case 32:
info->pixelsize=4;
break;
case 64:
info->pixelsize=8;
break;
default:
info->pixelsize=0;
break;
}
info->pitch = info->scr_w * info->pixelsize;
info->vdiformat = ( (info->scr_bpp <= 8) ? VDI_FORMAT_INTER : VDI_FORMAT_PACK);
info->screensize = ( info->scr_w * info->pixelsize ) * info->scr_h;
if( info->EdDiVersion >= EDDI_10 ) {
memset( &out, 0, sizeof(short)*300 );
vq_scrninfo(vdih, (short*)&out);
info->vdiformat = out[0];
info->clut = out[1];
info->scr_bpp = out[2];
info->hicolors = *((unsigned long*) &out[3]);
if( info->EdDiVersion >= EDDI_11 ) {
info->pitch = out[5];
info->screen = (void *) *((unsigned long *) &out[6]);
}
switch( info->clut ) {
case VDI_CLUT_HARDWARE:
{
int i;
unsigned short *tmp_p;
/* it's possible to store the vdi painters:
tmp_p = (unsigned short *)&work_out[16];
for (i=0;i<256;i++) {
vdi_index[*tmp_p++] = i;
}
*/
}
break;
case VDI_CLUT_SOFTWARE:
{
int component; /* red, green, blue, alpha, overlay */
int num_bit;
unsigned short *tmp_p;
/* We can build masks with info here */
tmp_p = (unsigned short *) &out[16];
for (component=0;component<5;component++) {
for (num_bit=0;num_bit<16;num_bit++) {
unsigned short val;
val = *tmp_p++;
if (val == 0xffff) {
continue;
}
switch(component) {
case 0:
info->mask_r |= 1<< val;
break;
case 1:
info->mask_g |= 1<< val;
break;
case 2:
info->mask_b |= 1<< val;
break;
case 3:
info->mask_a |= 1<< val;
break;
}
}
}
}
/* Remove lower green bits for Intel endian screen */
if ((info->mask_g == ((7<<13)|3)) || (info->mask_g == ((7<<13)|7))) {
info->mask_g &= ~(7<<13);
}
break;
case VDI_CLUT_NONE:
break;
}
}
}
/*
lookup an plotter ID by name
*/
static int drvrname_idx( char * name )
{
int i;
for( i = 0; ; i++) {
if( screen_driver_table[i].name == NULL ) {
return( -1 );
}
else {
if( strcmp(name, screen_driver_table[i].name) == 0 ) {
return( i );
}
}
}
}
/*
lookup of font plotter ID by name
*/
static int font_drvrname_idx( char * name )
{
int i;
for( i = 0; ; i++) {
if( font_driver_table[i].name == NULL ) {
return( -1 );
}
else {
if( strcmp(name, font_driver_table[i].name) == 0 ) {
return( i );
}
}
}
}
/*
Get an plotter info entry, the entry contains an pointer to ctor
*/
struct s_driver_table_entry * get_screen_driver_entry( char * name )
{
int idx = drvrname_idx( name );
if( idx < 0 )
return( 0 );
else
return( &screen_driver_table[idx] );
}
/*
Get an font plotter info entry, the entry contains an pointer to ctor.
*/
struct s_font_driver_table_entry * get_font_driver_entry( char * name )
{
int idx = font_drvrname_idx( name );
if( idx < 0 )
return( 0 );
else
return( (struct s_font_driver_table_entry *)&font_driver_table[idx] );
}
/*
Create an new text plotter object
*/
FONT_PLOTTER new_font_plotter( int vdihandle, char * name, unsigned long flags, int * error)
{
int i=0;
int res = 0-ERR_PLOTTER_NOT_AVAILABLE;
FONT_PLOTTER fplotter = (FONT_PLOTTER)malloc( sizeof(struct s_font_plotter) );
if( fplotter == NULL ) {
*error = 0-ERR_NO_MEM;
return( NULL );
}
fplotter->vdi_handle = vdihandle;
fplotter->name = name;
fplotter->flags |= flags;
for( i = 0; ; i++) {
if( font_driver_table[i].name == NULL ) {
res = 0-ERR_PLOTTER_NOT_AVAILABLE;
break;
} else {
if( strcmp(name, font_driver_table[i].name) == 0 ) {
if( font_driver_table[i].ctor ) {
res = font_driver_table[i].ctor( fplotter );
*error = 0;
} else {
res = 0-ERR_PLOTTER_NOT_AVAILABLE;
*error = res;
return (NULL);
}
break;
}
}
}
if( res < 0 ) {
free( fplotter );
*error = res;
return( NULL );
}
fplotter->plotter = NULL;
return( fplotter );
}
static bool init=false;
static int inst=0;
/*
Create an new plotter object
*/
GEM_PLOTTER new_plotter(int vdihandle, char * name, GRECT * loc_size,
int virt_bpp, unsigned long flags, FONT_PLOTTER fplotter, int * error )
{
int res = 0-ERR_PLOTTER_NOT_AVAILABLE;
int i;
assert( fplotter != NULL );
GEM_PLOTTER gemplotter = (GEM_PLOTTER)malloc( sizeof(struct s_gem_plotter) );
if( !gemplotter ) {
*error = 0-ERR_NO_MEM;
return( NULL );
}
memset( gemplotter, 0, sizeof(struct s_gem_plotter));
gemplotter->name = name;
gemplotter->vdi_handle = vdihandle;
gemplotter->flags |= flags;
gemplotter->font_plotter = fplotter;
gemplotter->bpp_virt = virt_bpp;
gemplotter->cfbi = 0;
memset(&gemplotter->fbuf, 0, sizeof(struct s_frame_buf) * MAX_FRAMEBUFS );
gemplotter->fbuf[0].x = loc_size->g_x;
gemplotter->fbuf[0].y = loc_size->g_y;
gemplotter->fbuf[0].w = loc_size->g_w;
gemplotter->fbuf[0].h = loc_size->g_h;
/* request vdi info once, so every plotter is able to access the info */
if( !init ) {
/* vdi_sysinfo */
read_vdi_sysinfo( vdihandle, &vdi_sysinfo );
init = true;
}
for( i = 0; ; i++) {
if( screen_driver_table[i].name == NULL ) {
res = 0-ERR_PLOTTER_NOT_AVAILABLE;
break;
}
else {
if( strcmp(name, screen_driver_table[i].name) == 0 ) {
if( screen_driver_table[i].ctor ) {
gemplotter->flags |= screen_driver_table[i].flags;
res = screen_driver_table[i].ctor( gemplotter );
*error = 0;
} else {
res = 0-ERR_PLOTTER_NOT_AVAILABLE;
*error = res;
return (NULL);
}
break;
}
}
}
if( res < 0 ) {
free( gemplotter );
*error = res;
return( NULL );
}
inst++;
gemplotter->font_plotter->plotter = gemplotter;
return( gemplotter );
}
/*
Free an plotter
*/
int delete_plotter( GEM_PLOTTER p )
{
if( p ) {
p->dtor( p );
free( p );
p = NULL;
inst--;
if( inst == 0 ){
}
}
else
return( -1 );
return( 0 );
}
/*
Free an font plotter
*/
int delete_font_plotter( FONT_PLOTTER p )
{
if( p ) {
p->dtor(p);
free( p );
p = NULL;
}
else
return( -1 );
return( 0 );
}
/*
x - x coord
y - y coord
stride - stride in bytes
bpp - bits per pixel
*/
int calc_chunked_buffer_size(int x, int y, int stride, int bpp)
{
return( (x * (bpp >> 3)) * y );
}
/*
x - x coord
y - y coord
stride - stride in bytes
bpp - bits per pixel
*/
int get_pixel_offset( int x, int y, int stride, int bpp )
{
LOG(("byte_pp: %d, pure: %d, result: %d\n",(bpp >> 3),(y * stride + x), (y * stride + x) * (bpp >> 3)));
return( ( (y * stride) + x) * (bpp >> 3) );
}
/*
1. calculate visible area of framebuffer in coords relative to framebuffer position
result:
this function should calc offsets into x,y coords of the framebuffer which
can be drawn. If the framebuffer coords do not fall within the screen region,
all values of visible region are set to zero.
*/
void update_visible_rect( GEM_PLOTTER p )
{
GRECT screen;
GRECT common;
GRECT frame;
screen.g_x = 0;
screen.g_y = 0;
screen.g_w = vdi_sysinfo.scr_w;
screen.g_h = vdi_sysinfo.scr_h;
common.g_x = frame.g_x = CURFB(p).x;
common.g_y = frame.g_y = CURFB(p).y;
common.g_w = frame.g_w = CURFB(p).w;
common.g_h = frame.g_h = CURFB(p).h;
if( rc_intersect( &screen, &common ) ) {
CURFB(p).vis_w = common.g_w;
CURFB(p).vis_h = common.g_h;
if( CURFB(p).x < screen.g_x )
CURFB(p).vis_x = frame.g_w - common.g_w;
else
CURFB(p).vis_x = 0;
if( CURFB(p).y <screen.g_y )
CURFB(p).vis_y = frame.g_h - common.g_h;
else
CURFB(p).vis_y = 0;
} else {
CURFB(p).vis_w = CURFB(p).vis_h = 0;
CURFB(p).vis_x = CURFB(p).vis_y = 0;
}
}
/*
Returns the visible parts of the box (relative coords within framebuffer),
relative to screen coords (normally starting at 0,0 )
*/
bool fbrect_to_screen( GEM_PLOTTER self, GRECT box, GRECT * ret )
{
GRECT out, vis, screen;
screen.g_x = 0;
screen.g_y = 0;
screen.g_w = vdi_sysinfo.scr_w;
screen.g_h = vdi_sysinfo.scr_h;
/* get visible region: */
vis.g_x = CURFB(self).x;
vis.g_y = CURFB(self).y;
vis.g_w = CURFB(self).w;
vis.g_h = CURFB(self).h;
if ( !rc_intersect( &screen, &vis ) ) {
return( false );
}
vis.g_x = CURFB(self).w - vis.g_w;
vis.g_y = CURFB(self).h - vis.g_h;
/* clip box to visible region: */
if( !rc_intersect(&vis, &box) ) {
return( false );
}
out.g_x = box.g_x + CURFB(self).x;
out.g_y = box.g_y + CURFB(self).y;
out.g_w = box.g_w;
out.g_h = box.g_h;
*ret = out;
return ( true );
}
const char* plotter_err_str(int i) { return(plot_error_codes[abs(i)]); }
void dump_vdi_info( short vdih )
{
struct s_vdi_sysinfo temp;
read_vdi_sysinfo( vdih, &temp );
printf("struct s_vdi_sysinfo {\n");
printf(" short vdi_handle: %d\n", temp.vdi_handle);
printf(" short scr_w: %d \n", temp.scr_w);
printf(" short scr_h: %d\n", temp.scr_h);
printf(" short scr_bpp: %d\n", temp.scr_bpp);
printf(" int colors: %d\n", temp.colors);
printf(" ulong hicolors: %d\n", temp.hicolors);
printf(" short pixelsize: %d\n", temp.pixelsize);
printf(" unsigned short pitch: %d\n", temp.pitch);
printf(" unsigned short vdiformat: %d\n", temp.vdiformat);
printf(" unsigned short clut: %d\n", temp.clut);
printf(" void * screen: 0x0%p\n", temp.screen);
printf(" unsigned long screensize: %d\n", temp.screensize);
printf(" unsigned long mask_r: 0x0%08x\n", temp.mask_r);
printf(" unsigned long mask_g: 0x0%08x\n", temp.mask_g);
printf(" unsigned long mask_b: 0x0%08x\n", temp.mask_b);
printf(" unsigned long mask_a: 0x0%08x\n", temp.mask_a);
printf(" short maxintin: %d\n", temp.maxintin);
printf(" short maxpolycoords: %d\n", temp.maxpolycoords);
printf(" unsigned long EdDiVersion: 0x0%03x\n", temp.EdDiVersion);
printf(" unsigned short rasterscale: 0x%2x\n", temp.rasterscale);
printf("};\n");
}
void dump_plot_drivers(void)
{
int i = 0;
while( screen_driver_table[i].name != NULL ) {
printf("%s -> max_bpp: %d, flags: %d\n",
screen_driver_table[i].name,
screen_driver_table[i].max_bpp,
screen_driver_table[i].flags
);
i++;
}
}
void dump_font_drivers(void)
{
int i = 0;
while( font_driver_table[i].name != NULL ) {
printf("%s -> flags: %d\n",
font_driver_table[i].name,
font_driver_table[i].flags
);
i++;
}
}
/*
Convert an RGB color to an VDI Color
*/
void rgb_to_vdi1000( unsigned char * in, unsigned short * out )
{
double r = ((double)in[0]/255); /* prozentsatz red */
double g = ((double)in[1]/255); /* prozentsatz green */
double b = ((double)in[2]/255); /* prozentsatz blue */
out[0] = 1000 * r + 0.5;
out[1] = 1000 * g + 0.5;
out[2] = 1000 * b + 0.5;
return;
}
static short web_std_colors[6] = {0, 51, 102, 153, 204, 255};
/*
Convert an RGB color into an index into the 216 colors web pallette
*/
short rgb_to_666_index(unsigned char r, unsigned char g, unsigned char b)
{
short ret = 0;
short i;
unsigned char rgb[3] = {r,g,b};
unsigned char tval[3];
/* convert each 8bit color to 6bit web color: */
for( i=0; i<3; i++) {
if(0 == rgb[i] % web_std_colors[1] ) {
tval[i] = rgb[i] / web_std_colors[1];
}
else {
int pos = ((short)rgb[i] / web_std_colors[1]);
if( abs(rgb[i] - web_std_colors[pos]) > abs(rgb[i] - web_std_colors[pos+1]) )
tval[i] = pos+1;
else
tval[i] = pos;
}
}
return( tval[2]*36+tval[1]*6+tval[0] );
}
/* Shared (static in object oriented slang) plotter functions: */
int plotter_get_clip( GEM_PLOTTER self, struct s_clipping * out )
{
out->x0 = self->clipping.x0;
out->y0 = self->clipping.y0;
out->x1 = self->clipping.x1;
out->y1 = self->clipping.y1;
return( 1 );
}
int plotter_std_clip(GEM_PLOTTER self,int x0, int y0, int x1, int y1)
{
self->clipping.x0 = x0;
self->clipping.y0 = y0;
self->clipping.x1 = x1;
self->clipping.y1 = y1;
return ( 1 );
}
/* this converts framebuffer clipping to vdi clipping and sets it */
void plotter_vdi_clip( GEM_PLOTTER self, bool set)
{
return;
if( set == true ) {
struct s_clipping * c = &self->clipping;
short vdiflags[58];
short newclip[4];
vq_extnd( self->vdi_handle, 1, (short*)&vdiflags);
prev_vdi_clip[0] = vdiflags[45];
prev_vdi_clip[1] = vdiflags[46];
prev_vdi_clip[2] = vdiflags[47];
prev_vdi_clip[3] = vdiflags[48];
newclip[0] = CURFB(self).x + MAX(c->x0, 0);
newclip[1] = CURFB(self).y + MAX(c->y0, 0);
newclip[2] = CURFB(self).x + MIN(CURFB(self).vis_w, c->x1 - c->x0)-1;
newclip[3] = CURFB(self).y + MIN(CURFB(self).vis_h, c->y1 - c->y0)-1;
vs_clip( self->vdi_handle, 1, (short*)&newclip );
} else {
short set = 1;
vs_clip( self->vdi_handle, set, (short *)&prev_vdi_clip );
}
}

293
atari/plot/plotter.h Normal file
View File

@ -0,0 +1,293 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GEM_PLOTTER_API_H_
#define _GEM_PLOTTER_API_H_
#include <windom.h>
#ifndef ceilf
#define ceilf(x) (float)ceil((double)x)
#endif
#ifdef TEST_PLOTTER
#define verbose_log 1
#define LOG(x) do { if (verbose_log) (printf(__FILE__ " %s %i: ", __PRETTY_FUNCTION__, __LINE__), printf x, fputc('\n', stdout)); } while (0)
#endif
#define MAX_FRAMEBUFS 0x010
#define C2P (1<<0) /* C2P convert buffer 1 to buffer 2 */
/* TODO: implement offscreen buffer switch */
/* Plotter Flags: */
#define PLOT_FLAG_OFFSCREEN 0x01
#define PLOT_FLAG_LOCKED 0x02
#define PLOT_FLAG_DITHER 0x04
#define PLOT_FLAG_TRANS 0x08
/* Error codes: */
#define ERR_BUFFERSIZE_EXCEEDS_SCREEN 1
#define ERR_NO_MEM 2
#define ERR_PLOTTER_NOT_AVAILABLE 3
static const char * plot_error_codes[] =
{
"None",
"ERR_BUFFERSIZE_EXCEEDS_SCREEN",
"ERR_NO_MEM",
"ERR_PLOTTER_NOT_AVAILABLE"
};
/* Grapics & Font Plotter Objects: */
typedef struct s_font_plotter * FONT_PLOTTER;
typedef struct s_gem_plotter * GEM_PLOTTER;
typedef struct s_font_plotter * GEM_FONT_PLOTTER; /* for public use ... */
struct s_font_plotter
{
char * name;
int flags;
int vdi_handle;
void * priv_data;
GEM_PLOTTER plotter;
bool (*str_width)(FONT_PLOTTER self, const plot_font_style_t *fstyle,
const char * str, size_t length, int * width);
bool (*str_split)(FONT_PLOTTER self, const plot_font_style_t *fstyle,
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x);
bool (*pixel_position)(FONT_PLOTTER self, const plot_font_style_t *fstyle,
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x);
void (*text)(FONT_PLOTTER self, int x, int y, const char *text, size_t length, const plot_font_style_t *fstyle);
void (*dtor)(FONT_PLOTTER self );
};
struct s_clipping {
short x0;
short y0;
short x1;
short y1;
};
struct s_vdi_sysinfo {
short vdi_handle; /* vdi handle */
short scr_w; /* resolution horz. */
short scr_h; /* resolution vert. */
short scr_bpp; /* bits per pixel */
int colors; /* 0=hiclor, 2=mono */
unsigned long hicolors; /* if colors = 0 */
short pixelsize; /* bytes per pixel */
unsigned short pitch; /* row pitch */
unsigned short vdiformat; /* pixel format */
unsigned short clut; /* type of clut support */
void * screen; /* pointer to screen, or NULL */
unsigned long screensize; /* size of screen (in bytes) */
unsigned long mask_r; /* color masks */
unsigned long mask_g;
unsigned long mask_b;
unsigned long mask_a;
short maxintin; /* maximum pxy items */
short maxpolycoords; /* max coords for p_line etc. */
unsigned long EdDiVersion; /* EdDi Version or 0 */
bool rasterscale; /* raster scaling support */
};
struct s_frame_buf
{
short x;
short y;
short w;
short h;
short vis_x; /* visible rectangle of the screen buffer */
short vis_y; /* coords are relative to framebuffer location */
short vis_w;
short vis_h;
int size;
bool swapped;
void * mem;
};
struct s_gem_plotter
{
char * name; /* name that identifies the Plotter */
unsigned long flags;
int vdi_handle;
struct s_vdi_sysinfo * scr;
void * priv_data;
int bpp_virt; /* bit depth of framebuffer */
struct s_clipping clipping;
struct s_frame_buf fbuf[MAX_FRAMEBUFS];
int cfbi; /* current framebuffer index */
FONT_PLOTTER font_plotter;
int (*dtor)(GEM_PLOTTER self);
int (*resize)(GEM_PLOTTER self, int w, int h);
int (*move)(GEM_PLOTTER self, short x, short y );
void * (*lock)(GEM_PLOTTER self);
void * (*create_framebuffer)(GEM_PLOTTER self);
void * (*switch_to_framebuffer)(GEM_PLOTTER self);
int (*unlock)(GEM_PLOTTER self);
int (*update_region)(GEM_PLOTTER self, GRECT region);
int (*update_screen_region)( GEM_PLOTTER self, GRECT region );
int (*update_screen)(GEM_PLOTTER self);
int (*put_pixel)(GEM_PLOTTER self, int x, int y, int color );
int (*copy_rect)(GEM_PLOTTER self, GRECT src, GRECT dst );
int (*clip)(GEM_PLOTTER self, int x0, int y0, int x1, int y1);
int (*arc)(GEM_PLOTTER self, int x, int y, int radius, int angle1, int angle2, const plot_style_t * pstyle);
int (*disc)(GEM_PLOTTER self, int x, int y, int radius, const plot_style_t * pstyle);
int (*line)(GEM_PLOTTER self, int x0, int y0, int x1, int y1, const plot_style_t * pstyle);
int (*rectangle)(GEM_PLOTTER self, int x0, int y0, int x1, int y1, const plot_style_t * pstyle);
int (*polygon)(GEM_PLOTTER self, const int *p, unsigned int n, const plot_style_t * pstyle);
int (*path)(GEM_PLOTTER self, const float *p, unsigned int n, int fill, float width, int c, const float transform[6]);
int (*bitmap_resize) ( GEM_PLOTTER self, struct bitmap * bm, int nw, int nh );
int (*bitmap)(GEM_PLOTTER self, struct bitmap * bmp, int x, int y,
unsigned long bg, unsigned long flags );
int (*text)(GEM_PLOTTER self, int x, int y, const char *text, size_t length, const plot_font_style_t *fstyle);
};
struct s_driver_table_entry
{
char * name;
int (*ctor)( GEM_PLOTTER self );
int flags;
int max_bpp;
};
struct s_font_driver_table_entry
{
char * name;
int (*ctor)( FONT_PLOTTER self );
int flags;
};
typedef struct s_driver_table_entry * PLOTTER_INFO;
typedef struct s_font_driver_table_entry * FONT_PLOTTER_INFO;
/* get index to driver in driver list by name */
static int drvrname_idx( char * name );
/* get s_driver_table_entry from driver table */
struct s_driver_table_entry * get_screen_driver_entry(char * name);
/* get s_font_driver_table_entry from driver table */
struct s_font_driver_table_entry * get_font_driver_entry(char * name);
/* fill screen / sys info */
struct s_vdi_sysinfo * read_vdi_sysinfo(short vdih, struct s_vdi_sysinfo * info );
/*
Create an new plotter object
Error Values:
-1 no mem
-2 error configuring plotter
-3 Plotter not available
*/
GEM_PLOTTER new_plotter(int vdihandle, char * name,
GRECT *, int virt_bpp, unsigned long flags, FONT_PLOTTER font_renderer,
int * error);
/*
Create an new font plotter object
Error Values:
-1 no mem
-2 error configuring font plotter
-3 Font Plotter not available
*/
FONT_PLOTTER new_font_plotter(int vdihandle, char * name, unsigned long flags, int * error );
/* free the plotter resources */
int delete_plotter( GEM_PLOTTER p );
int delete_font_plotter( FONT_PLOTTER p );
/* calculate size of intermediate buffer */
int calc_chunked_buffer_size(int x, int y, int stride, int bpp);
/* calculates the pixel offset from x,y pos */
int get_pixel_offset( int x, int y, int stride, int bpp );
/* Recalculate visible parts of the framebuffer */
void update_visible_rect( GEM_PLOTTER p );
/* resolve possible visible parts of the framebuffer in screen coords */
bool fbrect_to_screen( GEM_PLOTTER self, GRECT box, GRECT * ret );
/* translate an error number */
const char* plotter_err_str(int i) ;
void dump_font_drivers(void);
void dump_plot_drivers(void);
void dump_vdi_info(short);
/* convert an rgb color to vdi1000 color */
void rgb_to_vdi1000( unsigned char * in, unsigned short * out );
/* convert an rgb color to an index into the web palette */
short rgb_to_666_index(unsigned char r, unsigned char g, unsigned char b);
/* shared / static methods ... */
int plotter_get_clip( GEM_PLOTTER self, struct s_clipping * out );
int plotter_std_clip(GEM_PLOTTER self,int x0, int y0, int x1, int y1);
void plotter_vdi_clip( GEM_PLOTTER self, bool set);
#define PLOTTER_IS_LOCKED(plotter) ( plotter->private_flags & PLOTTER_FLAG_LOCKED )
#define FILL_PLOTTER_VTAB( p ) \
p->dtor = dtor;\
p->resize= resize;\
p->move = move;\
p->lock = lock;\
p->unlock = unlock;\
p->update_region = update_region;\
p->update_screen_region = update_screen_region;\
p->update_screen = update_screen;\
p->put_pixel = put_pixel;\
p->copy_rect = copy_rect; \
p->clip = clip;\
p->arc = arc;\
p->disc = disc;\
p->line = line;\
p->rectangle = rectangle;\
p->polygon = polygon;\
p->path = path;\
p->bitmap = bitmap;\
p->text = text;\
#define FILL_FONT_PLOTTER_VTAB( p ) \
p->dtor = dtor;\
p->str_width = str_width;\
p->str_split = str_split;\
p->pixel_position = pixel_position;\
p->text = text;\
#define CURFB( p ) \
p->fbuf[p->cfbi]
#define FIRSTFB( p ) \
p->fbuf[0]
#define OFFSET_WEB_PAL 16
#define OFFSET_FONT_PAL 232
#define RGB_TO_VDI(c) rgb_to_666_index( (c&0xFF),(c&0xFF00)>>8,(c&0xFF0000)>>16)+OFFSET_WEB_PAL
#define ABGR_TO_RGB(c) ( ((c&0xFF)<<16) | (c&0xFF00) | ((c&0xFF0000)>>16) ) << 8
#endif

998
atari/plot/plotter_vdi.c Normal file
View File

@ -0,0 +1,998 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include <windom.h>
#include <Hermes/Hermes.h>
#include "desktop/plot_style.h"
#include "image/bitmap.h"
#include "atari/bitmap.h"
#include "atari/plot/eddi.h"
#include "atari/plot/plotter.h"
#include "atari/plot/plotter_vdi.h"
#include "atari/plot/font_vdi.h"
#include "atari/bitmap.h"
#include "utils/log.h"
/* assign vdi line style to dst ( netsurf type ) */
#define NSLT2VDI(dst, src) \
switch( src->stroke_type ) {\
case PLOT_OP_TYPE_DOT: \
dst = 3; \
break;\
case PLOT_OP_TYPE_DASH:\
dst = 4; \
break;\
case PLOT_OP_TYPE_SOLID:\
case PLOT_OP_TYPE_NONE:\
default:\
dst = 1;\
break;\
}\
static int dtor( GEM_PLOTTER self );
static int resize( GEM_PLOTTER self, int w, int h );
static int move( GEM_PLOTTER self, short x, short y );
static void * lock( GEM_PLOTTER self );
static int unlock( GEM_PLOTTER self );
static int update_region( GEM_PLOTTER self, GRECT region );
static int update_screen_region( GEM_PLOTTER self, GRECT region );
static int update_screen( GEM_PLOTTER self );
static int put_pixel(GEM_PLOTTER self, int x, int y, int color );
static int copy_rect( GEM_PLOTTER self, GRECT src, GRECT dst );
static int arc(GEM_PLOTTER self,int x, int y, int radius, int angle1, int angle2, const plot_style_t * pstyle);
static int disc(GEM_PLOTTER self,int x, int y, int radius, const plot_style_t * pstyle);
static int line(GEM_PLOTTER self,int x0, int y0, int x1, int y1, const plot_style_t * pstyle);
static int rectangle(GEM_PLOTTER self,int x0, int y0, int x1, int y1, const plot_style_t * pstyle);
static int polygon(GEM_PLOTTER self,const int *p, unsigned int n, const plot_style_t * pstyle);
static int path(GEM_PLOTTER self,const float *p, unsigned int n, int fill, float width, int c, const float transform[6]);
static int bitmap_resize( GEM_PLOTTER self, struct bitmap * img, int nw, int nh );
static int bitmap( GEM_PLOTTER self, struct bitmap * bmp, int x, int y,
unsigned long bg, unsigned long flags );
static int text(GEM_PLOTTER self, int x, int y, const char *text,size_t length, const plot_font_style_t *fstyle);
static unsigned short sys_pal[256][3]; /*RGB*/
static unsigned short pal[256][3]; /*RGB*/
extern unsigned char rgb_web_pal[126][3];
extern unsigned short vdi_web_pal[126][3];
extern struct s_vdi_sysinfo vdi_sysinfo;
static HermesHandle hermes_pal_h; /* hermes palette handle */
static HermesHandle hermes_cnv_h; /* hermes converter instance handle */
static HermesHandle hermes_res_h;
int32 * hermes_pal_p;
int ctor_plotter_vdi(GEM_PLOTTER self )
{
int retval = 0;
int i;
self->dtor = dtor;
self->resize= resize;
self->move = move;
self->lock = lock;
self->unlock = unlock;
self->update_region = update_region;
self->update_screen_region = update_screen_region;
self->update_screen = update_screen;
self->put_pixel = put_pixel;
self->copy_rect = copy_rect;
self->clip = plotter_std_clip;
self->arc = arc;
self->disc = disc;
self->line = line;
self->rectangle = rectangle;
self->polygon = polygon;
self->path = path;
self->bitmap = bitmap;
self->bitmap_resize = bitmap_resize;
self->text = text;
LOG(("Screen: x: %d, y: %d\n", vdi_sysinfo.scr_w, vdi_sysinfo.scr_h));
self->priv_data = malloc( sizeof(struct s_vdi_priv_data) );
if( self->priv_data == NULL )
return( 0-ERR_NO_MEM );
memset( self->priv_data, 0, sizeof(struct s_vdi_priv_data) );
DUMMY_PRIV(self)->bufops = 0;
DUMMY_PRIV(self)->size_buf_packed = 0;
DUMMY_PRIV(self)->size_buf_planar = 0;
DUMMY_PRIV(self)->buf_packed = NULL;
DUMMY_PRIV(self)->buf_planar = NULL;
if( vdi_sysinfo.vdiformat == VDI_FORMAT_PACK ) {
self->bpp_virt = vdi_sysinfo.scr_bpp;
} else {
DUMMY_PRIV(self)->bufops = C2P;
self->bpp_virt = 8;
}
if( FIRSTFB(self).w > vdi_sysinfo.scr_w || FIRSTFB(self).h > vdi_sysinfo.scr_h )
return( 0-ERR_BUFFERSIZE_EXCEEDS_SCREEN );
FIRSTFB(self).size = calc_chunked_buffer_size( FIRSTFB(self).w, FIRSTFB(self).h, FIRSTFB(self).w, self->bpp_virt );
/* offscreen: FIRSTFB(self).mem = malloc( FIRSTFB(self).size ); */
FIRSTFB(self).mem = NULL;
update_visible_rect( self );
self->clip( self, 0, 0, FIRSTFB(self).w, FIRSTFB(self).h );
/* store system palette & setup the new (web) palette: */
i = 0;
for( i=0; i<=255; i++ ) {
vq_color(self->vdi_handle, i, 1, (unsigned short*)&sys_pal[i][0] );
if( i<OFFSET_WEB_PAL ) {
pal[i][0] = sys_pal[i][0];
pal[i][1] = sys_pal[i][1];
pal[i][2] = sys_pal[i][2];
} else {
if ( i < OFFSET_FONT_PAL ){
pal[i][0] = vdi_web_pal[i-OFFSET_WEB_PAL][0];
pal[i][1] = vdi_web_pal[i-OFFSET_WEB_PAL][1];
pal[i][2] = vdi_web_pal[i-OFFSET_WEB_PAL][2];
}
if( i >= OFFSET_FONT_PAL ) {
/* here we could define some additional colors... */
/* rgb_to_vdi1000( &rgb_font_pal[i-OFFSET_FONT_PAL], &pal[i] ); */
}
vs_color( self->vdi_handle, i, &pal[i][0] );
}
}
unsigned char * col;
assert( Hermes_Init() );
hermes_pal_h = Hermes_PaletteInstance();
hermes_pal_p = Hermes_PaletteGet(hermes_pal_h);
assert(hermes_pal_p);
for( i = 0; i<OFFSET_FONT_PAL; i++) {
col = (unsigned char *)(hermes_pal_p+i);
if( i < OFFSET_WEB_PAL ) {
col[0] = sys_pal[i][0];
col[1] = sys_pal[i][1];
col[2] = sys_pal[i][2];
}
if( i >= OFFSET_WEB_PAL ) {
col[0] = rgb_web_pal[i-OFFSET_WEB_PAL][0];
col[1] = rgb_web_pal[i-OFFSET_WEB_PAL][1];
col[2] = rgb_web_pal[i-OFFSET_WEB_PAL][2];
}
/* font colors missing */
col[3] = 0;
}
Hermes_PaletteInvalidateCache(hermes_pal_h);
unsigned long flags = ( self->flags & PLOT_FLAG_DITHER ) ? HERMES_CONVERT_DITHER : 0;
hermes_cnv_h = Hermes_ConverterInstance( flags );
assert( hermes_cnv_h );
hermes_res_h = Hermes_ConverterInstance( flags );
assert( hermes_res_h );
/* set up the src & dst format: */
/* netsurf uses RGBA ... */
DUMMY_PRIV(self)->nsfmt.a = 0xFFUL;
DUMMY_PRIV(self)->nsfmt.b = 0x0FF00UL;
DUMMY_PRIV(self)->nsfmt.g = 0x0FF0000UL;
DUMMY_PRIV(self)->nsfmt.r = 0x0FF000000UL;
DUMMY_PRIV(self)->nsfmt.bits = 32;
DUMMY_PRIV(self)->nsfmt.indexed = false;
DUMMY_PRIV(self)->nsfmt.has_colorkey = false;
DUMMY_PRIV(self)->vfmt.r = vdi_sysinfo.mask_r;
DUMMY_PRIV(self)->vfmt.g = vdi_sysinfo.mask_g;
DUMMY_PRIV(self)->vfmt.b = vdi_sysinfo.mask_b;
DUMMY_PRIV(self)->vfmt.a = vdi_sysinfo.mask_a;
DUMMY_PRIV(self)->vfmt.bits = self->bpp_virt;
DUMMY_PRIV(self)->vfmt.indexed = false;
DUMMY_PRIV(self)->vfmt.has_colorkey = false;
return( 1 );
}
static int dtor( GEM_PLOTTER self )
{
int i=0;
LOG(("%s: %s\n", (char*)__FILE__, __FUNCTION__));
for( i=0; i<MAX_FRAMEBUFS; i++) {
if( self->fbuf[i].mem != NULL )
free( self->fbuf[i].mem );
}
/* restore system palette */
for( i=0; i<=255; i++ ) {
vs_color( self->vdi_handle, i, &sys_pal[i][0] );
}
/* close Hermes stuff: */
Hermes_ConverterReturn( hermes_cnv_h );
Hermes_PaletteReturn( hermes_pal_h );
Hermes_Done();
if( self->priv_data != NULL ){
if( DUMMY_PRIV(self)->buf_packed )
free( DUMMY_PRIV(self)->buf_packed );
if( DUMMY_PRIV(self)->buf_planar )
free( DUMMY_PRIV(self)->buf_planar );
free( self->priv_data );
}
return( 1 );
}
static int resize( GEM_PLOTTER self, int w, int h )
{
if( w == CURFB(self).w && h == CURFB(self).h )
return( 1 );
int newsize = calc_chunked_buffer_size( w, h, w, self->bpp_virt );
LOG(("%s: %s, oldsize: %d\n", (char*)__FILE__, __FUNCTION__, CURFB(self).size ));
/* todo: needed when using offscreen buffers...
if( newsize > self->screen_buffer_size ) {
self->screen_buffer_size = newsize;
self->screen_buffer =realloc( self->screen_buffer , self->screen_buffer_size );
}
*/
CURFB(self).w = w;
CURFB(self).h = h;
update_visible_rect( self );
LOG(("%s: %s, newsize: %d\n", (char*)__FILE__, (char*)__FUNCTION__, CURFB(self).size ));
return( 1 );
}
static int move( GEM_PLOTTER self,short x, short y )
{
bool upd;
if(x == CURFB(self).x && y == CURFB(self).y ){
return 1;
}
LOG(("%s: x: %d, y: %d\n",(char*)__FUNCTION__, x, y));
CURFB(self).x = x;
CURFB(self).y = y;
update_visible_rect( self );
/*
for offscreen plotters:
copy current contents to new pos?
we could also copy content of our own screen buffer,
but only when it's unlocked
...nono, the user must do this manually. Because window move will already be handled by the OS
*/
/*update_screen( self );*/
return( 1 );
}
static void * lock( GEM_PLOTTER self )
{
LOG(("%s: %s\n", (char*)__FILE__, __FUNCTION__));
self->flags |= PLOT_FLAG_LOCKED;
wind_update(BEG_UPDATE);
wind_update(BEG_MCTRL);
return( NULL );
}
static int unlock( GEM_PLOTTER self )
{
LOG(("%s: %s\n", (char*)__FILE__, __FUNCTION__));
self->flags &= ~PLOT_FLAG_LOCKED;
wind_update(END_MCTRL);
wind_update(END_UPDATE);
return( 1 );
}
/*
region specifies an rectangle within the framebuffer
calculation of screen coords is done automatically.
*/
static int update_region( GEM_PLOTTER self, GRECT region )
{
int src_offs;
GRECT screen_area, tmp, visible;
short pxy[10];
visible.g_x = CURFB(self).vis_x;
visible.g_y = CURFB(self).vis_y;
visible.g_w = CURFB(self).vis_w;
visible.g_h = CURFB(self).vis_h;
/*
LOG(("%s: %s %d\n", (char*)__FILE__, __FUNCTION__, __LINE__));
LOG(("region: x:%d, y:%d, w:%d, h:%d\n", region.g_x, region.g_y, region.g_w, region.g_h ));
LOG(("visible: x:%d, y:%d, w:%d, h:%d\n", visible.g_x, visible.g_y, visible.g_w, visible.g_h ));
*/
/* sanitize region: */
tmp = region;
if( !rc_intersect(&visible, &tmp) )
return( 0 );
/*
region is partially out of bottom or left:
if( region.g_x < self->visible.g_x )
{
region.g_w = self->visible.g_x - region.g_x;
region.g_x = self->visible.g_x;
}
if( region.g_y < self->visible.g_y )
{
region.g_h = self->visible.g_y - region.g_y;
region.g_y = self->visible.g_y;
}
region is partially out of top or right:
if( region.g_x + region.g_w > self->visible.g_x + self->visible.g_w )
{
region.g_w = self->visible.g_w - region.g_x;
}
if( region.g_y + region.g_h > self->visible.g_y + self->visible.g_h )
{
region.g_h = self->visible.g_h - region.g_y;
}
now region contains coords of framebuffer that needs redraw.
*/
if( fbrect_to_screen( self, tmp, &screen_area) ) {
pxy[0] = screen_area.g_x;
pxy[1] = screen_area.g_y;
pxy[2] = screen_area.g_x + screen_area.g_w;
pxy[3] = screen_area.g_y;
pxy[4] = screen_area.g_x + screen_area.g_w;
pxy[5] = screen_area.g_y + screen_area.g_h;
pxy[6] = screen_area.g_x;
pxy[7] = screen_area.g_y + screen_area.g_h;
pxy[8] = screen_area.g_x;
pxy[9] = screen_area.g_y;
}
return( 1 );
}
/*
region specifies an rectangle within the screen,
calculation of framebuffer coords is done automatically.
*/
static int update_screen_region( GEM_PLOTTER self, GRECT region )
{
LOG(("%s: %s\n", (char*)__FILE__, __FUNCTION__));
return( 1 );
}
/* Updates all visible parts of the framebuffer */
static int update_screen( GEM_PLOTTER self )
{
GRECT target, src;
int src_offset;
int i,x;
LOG(("%s: %s\n", (char*)__FILE__, __FUNCTION__));
if( !(PLOT_FLAG_OFFSCREEN & self->flags) )
return( 0 );
target.g_x = src.g_x = 0;
target.g_y = src.g_y = 0;
target.g_w = src.g_w = CURFB(self).w;
target.g_h = src.g_h = CURFB(self).h;
if( !fbrect_to_screen( self, target, &target ) )
return( -1 );
src_offset = get_pixel_offset( CURFB(self).vis_x, CURFB(self).vis_y, CURFB(self).w, self->bpp_virt );
LOG(("area: x:%d ,y:%d ,w:%d ,h:%d, from: %p (offset: %d) \n",
target.g_x, target.g_y,
target.g_w, target.g_h,
((char*)CURFB(self).mem)+src_offset, src_offset
));
return( 1 );
}
static int put_pixel(GEM_PLOTTER self, int x, int y, int color )
{
LOG(("%s: %s\n", (char*)__FILE__, __FUNCTION__));
return( 1 );
}
static int copy_rect( GEM_PLOTTER self, GRECT src, GRECT dst )
{
MFDB devmf;
MFDB scrmf;
short pxy[8];
GRECT vis;
/* clip to visible rect, only needed for onscreen renderer: */
vis.g_x = CURFB(self).vis_x;
vis.g_y = CURFB(self).vis_y;
vis.g_w = CURFB(self).vis_w;
vis.g_h = CURFB(self).vis_h;
if( !rc_intersect(&vis, &src) )
return 1;
if( !rc_intersect(&vis, &dst) )
return 1;
src.g_x = CURFB(self).x + src.g_x;
src.g_y = CURFB(self).y + src.g_y;
dst.g_x = CURFB(self).x + dst.g_x;
dst.g_y = CURFB(self).y + dst.g_y;
devmf.fd_addr = NULL;
devmf.fd_w = src.g_w;
devmf.fd_h = src.g_h;
devmf.fd_wdwidth = 0;
devmf.fd_stand = 0;
devmf.fd_nplanes = 0;
devmf.fd_r1 = devmf.fd_r2 = devmf.fd_r3 = 0;
scrmf.fd_addr = NULL;
scrmf.fd_w = dst.g_w;
scrmf.fd_h = dst.g_h;
scrmf.fd_wdwidth = 0 ;
scrmf.fd_stand = 0;
scrmf.fd_nplanes = 0;
scrmf.fd_r1 = scrmf.fd_r2 = scrmf.fd_r3 = 0;
pxy[0] = src.g_x;
pxy[1] = src.g_y;
pxy[2] = pxy[0] + src.g_w-1;
pxy[3] = pxy[1] + src.g_h-1;
pxy[4] = dst.g_x;
pxy[5] = dst.g_y;
pxy[6] = pxy[4] + dst.g_w-1;
pxy[7] = pxy[5] + dst.g_h-1;
self->lock( self );
vro_cpyfm( self->vdi_handle, S_ONLY, (short*)&pxy, &devmf, &scrmf);
self->unlock( self );
return( 1 );
}
static int arc(GEM_PLOTTER self,int x, int y, int radius, int angle1, int angle2, const plot_style_t * pstyle)
{
plotter_vdi_clip( self, 1);
vswr_mode( self->vdi_handle, MD_REPLACE );
if( pstyle->fill_type == PLOT_OP_TYPE_NONE )
return 1;
if( pstyle->fill_type != PLOT_OP_TYPE_SOLID) {
vsl_color( self->vdi_handle, RGB_TO_VDI(pstyle->stroke_colour) );
vsf_perimeter( self->vdi_handle, 1);
vsf_interior( self->vdi_handle, 1 );
v_arc( self->vdi_handle, CURFB(self).x + x, CURFB(self).y + y, radius, angle1*10, angle2*10 );
} else {
vsl_color( self->vdi_handle, RGB_TO_VDI(pstyle->fill_colour) );
vsl_width( self->vdi_handle, 1 );
vsf_perimeter( self->vdi_handle, 1);
v_arc( self->vdi_handle, CURFB(self).x + x, CURFB(self).y + y, radius, angle1*10, angle2*10 );
}
plotter_vdi_clip( self, 0);
return ( 1 );
}
static int disc(GEM_PLOTTER self,int x, int y, int radius, const plot_style_t * pstyle)
{
plotter_vdi_clip( self, 1);
if( pstyle->fill_type != PLOT_OP_TYPE_SOLID) {
vsf_color( self->vdi_handle, RGB_TO_VDI(pstyle->stroke_colour) );
vsf_perimeter( self->vdi_handle, 1);
vsf_interior( self->vdi_handle, 0 );
v_circle( self->vdi_handle, CURFB(self).x + x, CURFB(self).y + y, radius );
} else {
vsf_color( self->vdi_handle, RGB_TO_VDI(pstyle->fill_colour) );
vsf_perimeter( self->vdi_handle, 0);
vsf_interior( self->vdi_handle, FIS_SOLID );
v_circle( self->vdi_handle, CURFB(self).x + x, CURFB(self).y + y, radius );
}
plotter_vdi_clip( self, 0);
return ( 1 );
}
static int line(GEM_PLOTTER self,int x0, int y0, int x1, int y1, const plot_style_t * pstyle)
{
short pxy[4];
short lt;
int sw = pstyle->stroke_width;
pxy[0] = CURFB(self).x + x0;
pxy[1] = CURFB(self).y + y0;
pxy[2] = CURFB(self).x + x1;
pxy[3] = CURFB(self).y + y1;
/* plotter_vdi_clip( self, 1); */
if( sw == 0)
sw = 1;
NSLT2VDI(lt, pstyle)
vsl_type( self->vdi_handle, lt );
vsl_width( self->vdi_handle, (short)sw );
vsl_color( self->vdi_handle, RGB_TO_VDI(pstyle->stroke_colour) );
v_pline(self->vdi_handle, 2, (short *)&pxy );
/* plotter_vdi_clip( self, 0); */
return ( 1 );
}
static int rectangle(GEM_PLOTTER self,int x0, int y0, int x1, int y1, const plot_style_t * pstyle)
{
short pxy[10];
GRECT r, rclip, sclip;
/* plotter_vdi_clip( self, 1); */
rclip.g_x = self->clipping.x0;
rclip.g_y = self->clipping.y0;
rclip.g_w = self->clipping.x1 - self->clipping.x0;
rclip.g_h = self->clipping.y1 - self->clipping.y0;
sclip.g_x = rclip.g_x;
sclip.g_y = rclip.g_y;
sclip.g_w = CURFB(self).vis_w;
sclip.g_h = CURFB(self).vis_h;
rc_intersect(&sclip, &rclip);
r.g_x = x0;
r.g_y = y0;
r.g_w = x1 - x0;
r.g_h = y1 - y0;
if( !rc_intersect( &rclip, &r ) ) {
return( 1 );
}
vsf_color( self->vdi_handle, RGB_TO_VDI(pstyle->fill_colour) );
vsf_perimeter( self->vdi_handle, 0);
vsf_interior( self->vdi_handle, FIS_SOLID );
pxy[0] = CURFB(self).x + r.g_x;
pxy[1] = CURFB(self).y + r.g_y;
pxy[2] = CURFB(self).x + r.g_x + r.g_w -1;
pxy[3] = CURFB(self).y + r.g_y + r.g_h -1;
vsf_style( self->vdi_handle, 1);
v_bar( self->vdi_handle, (short*)&pxy );
/* plotter_vdi_clip( self, 0); */
return ( 1 );
}
static int polygon(GEM_PLOTTER self,const int *p, unsigned int n, const plot_style_t * pstyle)
{
short pxy[n+2];
unsigned int i=0;
short d[4];
if( vdi_sysinfo.maxpolycoords > 0 )
assert( n < vdi_sysinfo.maxpolycoords );
/*
Does this double check make sense?
else
assert( n < vdi_sysinfo.maxintin );
*/
/* test this: */
/* plotter_vdi_clip( self, 1); */
vsf_interior( self->vdi_handle, FIS_SOLID );
vsf_style( self->vdi_handle, 1);
for( i = 0; i<n*2; i=i+2 ) {
pxy[i] = (short)CURFB(self).x+p[i];
pxy[i+1] = (short)CURFB(self).y+p[i+1];
}
if( pstyle->fill_type == PLOT_OP_TYPE_SOLID){
vsf_color( self->vdi_handle, BLACK);
v_fillarea(self->vdi_handle, n, (short*)&pxy);
} else {
pxy[n*2]=pxy[0];
pxy[n*2+1]=pxy[1];
vsl_color( self->vdi_handle, BLACK );
v_pline(self->vdi_handle, n+1, (short *)&pxy );
}
/* plotter_vdi_clip( self, 0); */
return ( 1 );
}
static int path(GEM_PLOTTER self,const float *p, unsigned int n, int fill, float width,
int c, const float transform[6])
{
LOG(("%s: %s\n", (char*)__FILE__, __FUNCTION__));
return ( 1 );
}
static inline uint32_t ablend(uint32_t pixel, uint32_t scrpixel)
{
int opacity = pixel & 0xFF;
int transp = 0x100 - opacity;
uint32_t rb, g;
rb = ((pixel & 0xFF00FF00UL) * opacity +
(scrpixel & 0xFF00FF00UL) * transp) >> 8;
g = ((pixel & 0x00FF0000UL) * opacity +
(scrpixel & 0x00FF0000UL) * transp) >> 8;
return (rb & 0xFF00FF00) | (g & 0x00FF0000);
}
static int bitmap_resize( GEM_PLOTTER self, struct bitmap * img, int nw, int nh )
{
HermesFormat fmt;
short bpp = bitmap_get_bpp( img );
int stride = bitmap_get_rowstride( img );
int err;
if( img->resized != NULL ) {
if( img->resized->width != nw || img->resized->height != nh ) {
bitmap_destroy( img->resized );
img->resized = NULL;
} else {
return( 0 );
}
}
/* allocate the mem for resized bitmap */
img->resized = bitmap_create_ex( nw, nh, bpp, nw*bpp, 0, NULL );
if( img->resized == NULL ) {
assert( img->resized );
return ( -ERR_NO_MEM );
}
/* allocate an converter, only for resizing */
err = Hermes_ConverterRequest( hermes_res_h,
&DUMMY_PRIV(self)->nsfmt,
&DUMMY_PRIV(self)->nsfmt
);
if( err == 0 ) {
return( -ERR_PLOTTER_NOT_AVAILABLE );
}
err = Hermes_ConverterCopy( hermes_res_h,
img->pixdata,
0, /* x src coord of top left in pixel coords */
0, /* y src coord of top left in pixel coords */
bitmap_get_width( img ), bitmap_get_height( img ),
stride, /* stride as bytes */
img->resized->pixdata,
0, /* x dst coord of top left in pixel coords */
0, /* y dst coord of top left in pixel coords */
nw, nh,
bitmap_get_rowstride( img->resized ) /* stride as bytes */
);
if( err == 0 ) {
bitmap_destroy( img->resized );
img->resized = NULL;
return( -2 );
}
return( 0 );
}
/*
fuellt ein mfdb, wenn bpp==null wird angenommen das ein MFDB f<EFBFBD>r
den Bildschirm initialisiert werden soll, der Speicher fuer das Bild
wird daher nicht alloziert ( fd_addr == 0 )
*/
static int init_mfdb(int bpp, int w, int h, MFDB * out )
{
int pxsize = bpp >> 3;
int dststride;
dststride = MFDB_STRIDE( w );
if( bpp > 0 ) {
out->fd_addr = malloc( dststride * pxsize * h );
out->fd_stand = 0;
out->fd_nplanes = (short)bpp;
out->fd_r1 = out->fd_r2 = out->fd_r3 = 0;
} else {
memset( out, 0, sizeof(MFDB) );
}
out->fd_w = dststride;
out->fd_h = h;
out->fd_wdwidth = dststride >> 4;
return( 1 );
}
/*
* Capture the screen at x,y location
* param self instance
* param x absolute screen coords
* param y absolute screen coords
* param w width
* param h height
*/
static struct bitmap * snapshot_create(GEM_PLOTTER self, int x, int y, int w, int h)
{
MFDB scr;
short pxy[8];
int err;
/* make sure the screen format is pixel packed... */
/* no method to convert planar screen to pixel packed ... right now */
assert( vdi_sysinfo.vdiformat == VDI_FORMAT_PACK );
{
int pxsize = vdi_sysinfo.scr_bpp >> 3;
int scr_stride = MFDB_STRIDE( w );
int scr_size = scr_stride * pxsize * h;
if( DUMMY_PRIV(self)->size_buf_scr == 0 ){
/* init screen mfdb */
DUMMY_PRIV(self)->buf_scr.fd_addr = malloc( scr_size );
DUMMY_PRIV(self)->size_buf_scr = scr_size;
} else {
if( scr_size > DUMMY_PRIV(self)->size_buf_scr ) {
DUMMY_PRIV(self)->buf_scr.fd_addr = realloc(
DUMMY_PRIV(self)->buf_scr.fd_addr, scr_size
);
DUMMY_PRIV(self)->size_buf_scr = scr_size;
}
}
if( DUMMY_PRIV(self)->buf_scr.fd_addr == NULL ) {
DUMMY_PRIV(self)->size_buf_scr = 0;
return( NULL );
}
DUMMY_PRIV(self)->buf_scr.fd_nplanes = vdi_sysinfo.scr_bpp;
DUMMY_PRIV(self)->buf_scr.fd_w = scr_stride;
DUMMY_PRIV(self)->buf_scr.fd_h = h;
DUMMY_PRIV(self)->buf_scr.fd_wdwidth = scr_stride >> 4;
assert( DUMMY_PRIV(self)->buf_scr.fd_addr != NULL );
}
init_mfdb( 0, w, h, &scr );
pxy[0] = x;
pxy[1] = y;
pxy[2] = pxy[0] + w-1;
pxy[3] = pxy[1] + h-1;
pxy[4] = 0;
pxy[5] = 0;
pxy[6] = pxy[2];
pxy[7] = pxy[3];
vro_cpyfm( self->vdi_handle, S_ONLY, (short*)&pxy,
&scr, &DUMMY_PRIV(self)->buf_scr
);
/* convert screen buffer to ns format: */
if( DUMMY_PRIV(self)->buf_scr_compat == NULL ) {
DUMMY_PRIV(self)->buf_scr_compat = bitmap_create(w, h, 0);
} else {
DUMMY_PRIV(self)->buf_scr_compat = bitmap_realloc( w, h,
DUMMY_PRIV(self)->buf_scr_compat->bpp,
w * DUMMY_PRIV(self)->buf_scr_compat->bpp,
BITMAP_GROW,
DUMMY_PRIV(self)->buf_scr_compat );
}
err = Hermes_ConverterRequest( hermes_cnv_h,
&DUMMY_PRIV(self)->vfmt,
&DUMMY_PRIV(self)->nsfmt
);
assert( err != 0 );
err = Hermes_ConverterCopy( hermes_cnv_h,
DUMMY_PRIV(self)->buf_scr.fd_addr,
0, /* x src coord of top left in pixel coords */
0, /* y src coord of top left in pixel coords */
w, h,
DUMMY_PRIV(self)->buf_scr.fd_w * vdi_sysinfo.pixelsize, /* stride as bytes */
DUMMY_PRIV(self)->buf_scr_compat->pixdata,
0, /* x dst coord of top left in pixel coords */
0, /* y dst coord of top left in pixel coords */
w, h,
bitmap_get_rowstride(DUMMY_PRIV(self)->buf_scr_compat) /* stride as bytes */
);
assert( err != 0 );
return( (struct bitmap * )DUMMY_PRIV(self)->buf_scr_compat );
}
static void snapshot_suspend(GEM_PLOTTER self )
{
if( DUMMY_PRIV(self)->size_buf_scr > CONV_KEEP_LIMIT ) {
DUMMY_PRIV(self)->buf_scr.fd_addr = realloc(
DUMMY_PRIV(self)->buf_scr.fd_addr, CONV_KEEP_LIMIT
);
if( DUMMY_PRIV(self)->buf_scr.fd_addr != NULL ) {
DUMMY_PRIV(self)->size_buf_scr = CONV_KEEP_LIMIT;
} else {
DUMMY_PRIV(self)->size_buf_scr = 0;
}
}
if( bitmap_buffer_size( DUMMY_PRIV(self)->buf_scr_compat ) > CONV_KEEP_LIMIT ) {
int w = 0;
int h = 1;
w = (CONV_KEEP_LIMIT / DUMMY_PRIV(self)->buf_scr_compat->bpp);
assert( CONV_KEEP_LIMIT == w*DUMMY_PRIV(self)->buf_scr_compat->bpp );
DUMMY_PRIV(self)->buf_scr_compat = bitmap_realloc( w, h,
DUMMY_PRIV(self)->buf_scr_compat->bpp,
CONV_KEEP_LIMIT, BITMAP_SHRINK, DUMMY_PRIV(self)->buf_scr_compat
);
}
}
static void snapshot_destroy( GEM_PLOTTER self )
{
if( DUMMY_PRIV(self)->buf_scr.fd_addr ) {
free( DUMMY_PRIV(self)->buf_scr.fd_addr );
DUMMY_PRIV(self)->buf_scr.fd_addr = NULL;
}
if( DUMMY_PRIV(self)->buf_scr_compat ) {
bitmap_destroy( DUMMY_PRIV(self)->buf_scr_compat );
DUMMY_PRIV(self)->buf_scr_compat = NULL;
}
}
/* convert bitmap to framebuffer format */
static int convert_bitmap( GEM_PLOTTER self,
struct bitmap * img,
int x,
int y,
GRECT * clip,
uint32_t bg,
MFDB *out )
{
short vpxsize = self->bpp_virt >> 3; /* / 8 */
int dststride; /* stride of dest. image */
int dstsize; /* size of dest. in byte */
int err;
int bw;
struct bitmap * scrbuf = NULL;
struct bitmap * bm;
assert( clip->g_h > 0 );
assert( clip->g_w > 0 );
bm = img;
bw = bitmap_get_width( img );
/* rem. if eddi xy is installed, we could directly access the screen! */
/* apply transparency to the image: */
if( (img->opaque == false)
&& ((self->flags & PLOT_FLAG_TRANS) != 0)
&& (vdi_sysinfo.vdiformat == VDI_FORMAT_PACK ) ) {
uint32_t * imgpixel;
uint32_t * screenpixel;
int img_x, img_y; /* points into old bitmap */
int screen_x, screen_y; /* pointers into new bitmap */
/* copy the screen to an temp buffer: */
scrbuf = snapshot_create(self, x, y, clip->g_w, clip->g_h );
if( scrbuf != NULL ) {
/* copy blended pixels the new buffer (which contains screen content): */
int img_stride = bitmap_get_rowstride(bm);
int screen_stride = bitmap_get_rowstride(scrbuf);
for( img_y = clip->g_y, screen_y = 0; screen_y < clip->g_h; screen_y++, img_y++) {
imgpixel = (uint32_t *)(bm->pixdata + (img_stride * img_y));
screenpixel = (uint32_t *)(scrbuf->pixdata + (screen_stride * screen_y));
for( img_x = clip->g_x, screen_x = 0; screen_x < clip->g_w; screen_x++, img_x++ ) {
if( (imgpixel[img_x] & 0xFF) != 0xFF ) {
if( (imgpixel[img_x] & 0x0FF) != 0 ) {
screenpixel[screen_x] = ablend( imgpixel[img_x], screenpixel[screen_x]);
}
} else {
screenpixel[screen_x] = imgpixel[img_x];
}
}
}
clip->g_x = 0;
clip->g_y = 0;
bm = scrbuf;
}
}
/* (re)allocate buffer for framebuffer image: */
dststride = MFDB_STRIDE( clip->g_w );
dstsize = dststride * vpxsize * clip->g_h;
if( dstsize > DUMMY_PRIV(self)->size_buf_packed) {
int blocks = (dstsize / (CONV_BLOCK_SIZE-1))+1;
if( DUMMY_PRIV(self)->buf_packed == NULL )
DUMMY_PRIV(self)->buf_packed =(void*)malloc( blocks * CONV_BLOCK_SIZE );
else
DUMMY_PRIV(self)->buf_packed =(void*)realloc(
DUMMY_PRIV(self)->buf_packed,
blocks * CONV_BLOCK_SIZE
);
assert( DUMMY_PRIV(self)->buf_packed );
if( DUMMY_PRIV(self)->buf_packed == NULL ) {
if( scrbuf != NULL )
bitmap_destroy( scrbuf );
return( 0-ERR_NO_MEM );
}
DUMMY_PRIV(self)->size_buf_packed = blocks * CONV_BLOCK_SIZE;
}
out->fd_addr = DUMMY_PRIV(self)->buf_packed;
out->fd_w = dststride;
out->fd_h = clip->g_h;
out->fd_wdwidth = dststride >> 4;
out->fd_stand = 0;
out->fd_nplanes = (short)self->bpp_virt;
out->fd_r1 = out->fd_r2 = out->fd_r3 = 0;
err = Hermes_ConverterRequest(
hermes_cnv_h,
&DUMMY_PRIV(self)->nsfmt,
&DUMMY_PRIV(self)->vfmt
);
assert( err != 0 );
/* convert image to virtual format: */
err = Hermes_ConverterCopy( hermes_cnv_h,
bm->pixdata,
clip->g_x, /* x src coord of top left in pixel coords */
clip->g_y, /* y src coord of top left in pixel coords */
clip->g_w, clip->g_h,
bm->rowstride, /* stride as bytes */
out->fd_addr,
0, /* x dst coord of top left in pixel coords */
0, /* y dst coord of top left in pixel coords */
clip->g_w, clip->g_h,
dststride * vpxsize /* stride as bytes */
);
assert( err != 0 );
return( 0 );
}
static void convert_bitmap_done( GEM_PLOTTER self )
{
if( DUMMY_PRIV(self)->size_buf_packed > CONV_KEEP_LIMIT ) {
/* free the mem if it was an large allocation ... */
DUMMY_PRIV(self)->buf_packed = realloc( DUMMY_PRIV(self)->buf_packed, CONV_KEEP_LIMIT );
DUMMY_PRIV(self)->size_buf_packed = CONV_KEEP_LIMIT;
}
snapshot_suspend( self );
}
static int bitmap( GEM_PLOTTER self, struct bitmap * bmp, int x, int y,
unsigned long bg, unsigned long flags )
{
MFDB src_mf;
MFDB scrmf;
short pxy[8];
GRECT off, clip, loc, vis;
src_mf.fd_addr = NULL;
scrmf.fd_addr = NULL;
off.g_x = x;
off.g_y = y;
off.g_h = bmp->height;
off.g_w = bmp->width;
clip.g_x = self->clipping.x0;
clip.g_y = self->clipping.y0;
clip.g_w = self->clipping.x1 - self->clipping.x0;
clip.g_h = self->clipping.y1 - self->clipping.y0;
if( !rc_intersect( &clip, &off) ) {
return( true );
}
vis.g_x = CURFB(self).vis_x;
vis.g_y = CURFB(self).vis_y;
vis.g_w = CURFB(self).vis_w;
vis.g_h = CURFB(self).vis_h;
if( !rc_intersect( &vis, &off) ) {
return( true );
}
loc = off;
off.g_x = MAX(0, off.g_x - x);
off.g_y = MAX(0, off.g_y - y);
loc.g_x = MAX(0, loc.g_x);
loc.g_y = MAX(0, loc.g_y);
pxy[0] = 0;
pxy[1] = 0;
pxy[2] = off.g_w-1;
pxy[3] = off.g_h-1;
pxy[4] = CURFB(self).x + loc.g_x;
pxy[5] = CURFB(self).y + loc.g_y;
pxy[6] = CURFB(self).x + loc.g_x + off.g_w-1;
pxy[7] = CURFB(self).y + loc.g_y + off.g_h-1;
if( convert_bitmap( self, bmp, pxy[4], pxy[5], &off, bg, &src_mf) != 0 ) {
return( true );
}
vro_cpyfm( self->vdi_handle, S_ONLY, (short*)&pxy, &src_mf, &scrmf);
convert_bitmap_done( self );
return( true );
}
static int text(GEM_PLOTTER self, int x, int y, const char *text, size_t length, const plot_font_style_t *fstyle)
{
self->font_plotter->text( self->font_plotter,
x,
y,
text, length,
fstyle
);
return ( 1 );
}

48
atari/plot/plotter_vdi.h Normal file
View File

@ -0,0 +1,48 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GEM_PLOTTER_DUMMY_H_INCLUDED
#define GEM_PLOTTER_DUMMY_H_INCLUDED
#include "plotter.h"
#include <Hermes/Hermes.h>
struct s_vdi_priv_data {
short bufops;
void * buf_packed; /* temp buffer for bitmap conversion */
int size_buf_packed;
void * buf_planar; /* temp buffer for bitmap conversion */
int size_buf_planar;
MFDB buf_scr; /* buffer for native screen capture */
int size_buf_scr;
struct bitmap * buf_scr_compat;
HermesFormat vfmt; /* framebuffer format */
/* no screen format here, hermes may not suitable for it */
HermesFormat nsfmt; /* netsurf bitmap format */
};
#define CONV_KEEP_LIMIT 512000 /* how much memory should be kept allocated for temp. conversion bitmaps? */
#define CONV_BLOCK_SIZE 32000 /* how much memory to allocate if some is needed */
#define DUMMY_PRIV(self) ((struct s_vdi_priv_data*)self->priv_data)
/* Each driver must export 1 method to create the plotter object: */
int ctor_plotter_vdi( GEM_PLOTTER p );
static struct bitmap * snapshot_create(GEM_PLOTTER self, int x, int y, int w, int h);
static void snapshot_suspend(GEM_PLOTTER self );
static void snapshot_destroy( GEM_PLOTTER self );
#endif

97
atari/res/netsurf.rsh Normal file
View File

@ -0,0 +1,97 @@
/* Resource C-Header-File v1.97 f<>r ResourceMaster ab v2.06 by ARDISOFT */
#define MAINMENU 0 /* menu */
#define MAINMENU_T_FILE 4 /* TITLE in tree MAINMENU */
#define MAINMENU_T_EDIT 5 /* TITLE in tree MAINMENU */
#define MAINMENU_T_VIEW 6 /* TITLE in tree MAINMENU */
#define MAINMENU_T_NAVIGATE 7 /* TITLE in tree MAINMENU */
#define MAINMENU_T_UTIL 8 /* TITLE in tree MAINMENU */
#define MAINMENU_T_HELP 9 /* TITLE in tree MAINMENU */
#define MAINMENU_M_ABOUT 12 /* STRING in tree MAINMENU */
#define MAINMENU_M_NEWWIN 21 /* STRING in tree MAINMENU */
#define MAINMENU_M_OPENURL 22 /* STRING in tree MAINMENU */
#define MAINMENU_M_OPENFILE 23 /* STRING in tree MAINMENU */
#define MAINMENU_M_CLOSEWIN 24 /* STRING in tree MAINMENU */
#define MAINMENU_SEP0 25 /* STRING in tree MAINMENU */
#define MAINMENU_M_SAVEPAGE 26 /* STRING in tree MAINMENU */
#define MAINMENU_SEP1 27 /* STRING in tree MAINMENU */
#define MAINMENU_M_QUIT 28 /* STRING in tree MAINMENU */
#define MAINMENU_M_CUT 30 /* STRING in tree MAINMENU */
#define MAINMENU_M_COPY 31 /* STRING in tree MAINMENU */
#define MAINMENU_M_PASTE 32 /* STRING in tree MAINMENU */
#define MAINMENU_SEP3 33 /* STRING in tree MAINMENU */
#define MAINMENU_M_FIND 34 /* STRING in tree MAINMENU */
#define MAINMENU_M_STOP 36 /* STRING in tree MAINMENU */
#define MAINMENU_M_RELOAD 37 /* STRING in tree MAINMENU */
#define MAINMENU_M_SCALE 39 /* STRING in tree MAINMENU */
#define MAINMENU_M_TOOLBARS 41 /* STRING in tree MAINMENU */
#define MAINMENU_M_SAVEWIN 43 /* STRING in tree MAINMENU */
#define MAINMENU_M_DEBUG_RENDER 44 /* STRING in tree MAINMENU */
#define MAINMENU_M_BACK 46 /* STRING in tree MAINMENU */
#define MAINMENU_M_FORWARD 47 /* STRING in tree MAINMENU */
#define MAINMENU_M_HOME 48 /* STRING in tree MAINMENU */
#define MAINMENU_M_LHISTORY 50 /* STRING in tree MAINMENU */
#define MAINMENU_M_GHISTORY 51 /* STRING in tree MAINMENU */
#define MAINMENU_M_ADD_BOOKMARK 53 /* STRING in tree MAINMENU */
#define MAINMENU_M_BOOKMARKS 54 /* STRING in tree MAINMENU */
#define MAINMENU_M_CHOICES 56 /* STRING in tree MAINMENU */
#define MAINMENU_M_HELP_CONTENT 58 /* STRING in tree MAINMENU */
#define TOOLBAR 1 /* form/dial */
#define TOOLBAR_BT_BACK 2 /* CICON in tree TOOLBAR */
#define TOOLBAR_BT_HOME 3 /* CICON in tree TOOLBAR */
#define TOOLBAR_BT_FORWARD 4 /* CICON in tree TOOLBAR */
#define TOOLBAR_BT_RELOAD 5 /* CICON in tree TOOLBAR */
#define TOOLBAR_BT_STOP 6 /* CICON in tree TOOLBAR */
#define ICONIFY 2 /* form/dial */
#define ICONIFY_GLOBE 1 /* CICON in tree ICONIFY */
#define FAVICON 3 /* form/dial */
#define CURSOR 4 /* form/dial */
#define CURSOR_HELP 1 /* ICON in tree CURSOR */
#define CURSOR_NODROP 2 /* ICON in tree CURSOR */
#define CURSOR_APPSTART 3 /* ICON in tree CURSOR */
#define CURSOR_DENY 4 /* ICON in tree CURSOR */
#define CURSOR_SIZEWE 5 /* ICON in tree CURSOR */
#define CURSOR_SIZENS 6 /* ICON in tree CURSOR */
#define CURSOR_MENU 7 /* ICON in tree CURSOR */
#define LOGIN 5 /* form/dial */
#define LOGIN_TB_USER 2 /* FTEXT in tree LOGIN */
#define LOGIN_TB_PASSWORD 4 /* FTEXT in tree LOGIN */
#define LOGIN_BT_LOGIN 5 /* BUTTON in tree LOGIN */
#define LOGIN_BT_ABORT 6 /* BUTTON in tree LOGIN */
#define VERIFY 6 /* form/dial */
#define VERIFY_LBL_HOST 3 /* TEXT in tree VERIFY */
#define VERIFY_BT_ACCEPT 4 /* BUTTON in tree VERIFY */
#define VERIFY_BT_REJECT 5 /* BUTTON in tree VERIFY */
#define VERIFY_BT_NEXT_CERT 7 /* BUTTON in tree VERIFY */
#define VERIFY_BOX_DETAILS 8 /* BOX in tree VERIFY */
#define VERIFY_BOX_H 9 /* BOX in tree VERIFY */
#define VERIFY_BT_SCROLL_R 10 /* BOXCHAR in tree VERIFY */
#define VERIFY_BT_SCROLL_L 11 /* BOXCHAR in tree VERIFY */
#define VERIFY_BOX_MOVER_H 12 /* BOX in tree VERIFY */
#define VERIFY_BT_SCROLL_U 13 /* BOXCHAR in tree VERIFY */
#define VERIFY_BT_SCROLL_D 14 /* BOXCHAR in tree VERIFY */
#define VERIFY_BOX_V 15 /* BOX in tree VERIFY */
#define VERIFY_MOVER_V 16 /* BOX in tree VERIFY */
#define THROBBER 7 /* form/dial */
#define SLIDER 8 /* form/dial */
#define SLIDER_BT_SCROLL_L 1 /* BOXCHAR in tree SLIDER */
#define SLIDER_BOX_H 2 /* BOX in tree SLIDER */
#define SLIDER_BOX_MOVER_H 3 /* BOX in tree SLIDER */
#define SLIDER_BT_SCROLL_R 4 /* BOXCHAR in tree SLIDER */
#define SLIDER_BT_SCROLL_U 5 /* BOXCHAR in tree SLIDER */
#define SLIDER_BOX_V 6 /* BOX in tree SLIDER */
#define SLIDER_MOVER_V 8 /* BOX in tree SLIDER */
#define SLIDER_BT_SCROLL_D 7 /* BOXCHAR in tree SLIDER */
#define TOOLBAR_HOTLIST 9 /* form/dial */
#define TOOLBAR_HOTLIST_CREATE_FOLDER 1 /* BUTTON in tree TOOLBAR_HOTLIST */
#define TOOLBAR_HOTLIST_ADD 2 /* BUTTON in tree TOOLBAR_HOTLIST */
#define TOOLBAR_HOTLIST_DELETE 3 /* BUTTON in tree TOOLBAR_HOTLIST */

94
atari/res/netsurf.rsm Normal file
View File

@ -0,0 +1,94 @@
ResourceMaster v3.65
#C 10@0@0@0@
#N 99@32@AZAaza___ _@AZAaza090___ _@@_@
#FoC-Header@rsm2out@C-Header@rsh@@@[C-Header@0@
#R 0@0@1@1@1@1@
#M 20010100@17741@7728@533@
#T 0@1@MAINMENU@@59@@
#O 4@32@T_FILE@@
#O 5@32@T_EDIT@@
#O 6@32@T_VIEW@@
#O 7@32@T_NAVIGATE@@
#O 8@32@T_UTIL@@
#O 9@32@T_HELP@@
#O 12@28@M_ABOUT@@
#O 21@28@M_NEWWIN@@
#O 22@28@M_OPENURL@@
#O 23@28@M_OPENFILE@@
#O 24@28@M_CLOSEWIN@@
#O 25@28@SEP0@@
#O 26@28@M_SAVEPAGE@@
#O 27@28@SEP1@@
#O 28@28@M_QUIT@@
#O 30@28@M_CUT@@
#O 31@28@M_COPY@@
#O 32@28@M_PASTE@@
#O 33@28@SEP3@@
#O 34@28@M_FIND@@
#O 36@28@M_STOP@@
#O 37@28@M_RELOAD@@
#O 39@28@M_SCALE@@
#O 41@28@M_TOOLBARS@@
#O 43@28@M_SAVEWIN@@
#O 44@28@M_DEBUG_RENDER@@
#O 46@28@M_BACK@@
#O 47@28@M_FORWARD@@
#O 48@28@M_HOME@@
#O 50@28@M_LHISTORY@@
#O 51@28@M_GHISTORY@@
#O 53@28@M_ADD_BOOKMARK@@
#O 54@28@M_BOOKMARKS@@
#O 56@28@M_CHOICES@@
#O 58@28@M_HELP_CONTENT@@
#T 1@2@TOOLBAR@@7@@
#O 2@33@BT_BACK@@
#O 3@33@BT_HOME@@
#O 4@33@BT_FORWARD@@
#O 5@33@BT_RELOAD@@
#O 6@33@BT_STOP@@
#T 2@2@ICONIFY@@3@@
#O 1@33@GLOBE@@
#T 3@2@FAVICON@@2@@
#T 4@2@CURSOR@@8@@
#O 1@31@HELP@@
#O 2@31@NODROP@@
#O 3@31@APPSTART@@
#O 4@31@DENY@@
#O 5@31@SIZEWE@@
#O 6@31@SIZENS@@
#O 7@31@MENU@@
#T 5@2@LOGIN@@7@@
#O 2@29@TB_USER@@
#O 4@29@TB_PASSWORD@@
#O 5@26@BT_LOGIN@@
#O 6@26@BT_ABORT@@
#T 6@2@VERIFY@@17@@
#O 0@20@@VERT SLIDER SIND HIDDEN!@
#O 3@21@LBL_HOST@@
#O 4@26@BT_ACCEPT@@
#O 5@26@BT_REJECT@@
#O 7@26@BT_NEXT_CERT@@
#O 8@20@BOX_DETAILS@@
#O 9@20@BOX_H@@
#O 10@27@BT_SCROLL_R@@
#O 11@27@BT_SCROLL_L@@
#O 12@20@BOX_MOVER_H@@
#O 13@27@BT_SCROLL_U@@
#O 14@27@BT_SCROLL_D@@
#O 15@20@BOX_V@@
#O 16@20@MOVER_V@@
#T 7@2@THROBBER@@9@@
#T 8@2@SLIDER@@9@@
#O 1@27@BT_SCROLL_L@@
#O 2@20@BOX_H@@
#O 3@20@BOX_MOVER_H@@
#O 4@27@BT_SCROLL_R@@
#O 5@27@BT_SCROLL_U@@
#O 6@20@BOX_V@@
#O 8@20@MOVER_V@@
#O 7@27@BT_SCROLL_D@@
#T 9@2@TOOLBAR_HOTLIST@@4@@
#O 1@26@CREATE_FOLDER@@
#O 2@26@ADD@@
#O 3@26@DELETE@@
#c 1564@

223
atari/schedule.c Normal file
View File

@ -0,0 +1,223 @@
/*
* Copyright 2008 Vincent Sanders <vince@simtec.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sys/time.h>
#include <time.h>
#include "desktop/browser.h"
#include "atari/schedule.h"
#include "utils/log.h"
/* linked list of scheduled callbacks */
static struct nscallback *schedule_list = NULL;
/**
* scheduled callback.
*/
struct nscallback
{
struct nscallback *next;
struct timeval tv;
void (*callback)(void *p);
void *p;
};
/**
* Schedule a callback.
*
* \param tival interval before the callback should be made / cs
* \param callback callback function
* \param p user parameter, passed to callback function
*
* The callback function will be called as soon as possible after t cs have
* passed.
*/
void schedule(int cs_ival, void (*callback)(void *p), void *p)
{
struct nscallback *nscb;
struct timeval tv;
tv.tv_sec = cs_ival / 100; /* cs to seconds */
tv.tv_usec = (cs_ival % 100) * 10000; /* remainder to microseconds */
nscb = calloc(1, sizeof(struct nscallback));
LOG(("adding callback %p for %p(%p) at %d cs", nscb, callback, p, cs_ival));
gettimeofday(&nscb->tv, NULL);
timeradd(&nscb->tv, &tv, &nscb->tv);
nscb->callback = callback;
nscb->p = p;
/* add to list front */
nscb->next = schedule_list;
schedule_list = nscb;
}
/**
* Unschedule a callback.
*
* \param callback callback function
* \param p user parameter, passed to callback function
*
* All scheduled callbacks matching both callback and p are removed.
*/
void schedule_remove(void (*callback)(void *p), void *p)
{
struct nscallback *cur_nscb;
struct nscallback *prev_nscb;
struct nscallback *unlnk_nscb;
if (schedule_list == NULL)
return;
LOG(("removing %p, %p", callback, p));
cur_nscb = schedule_list;
prev_nscb = NULL;
while (cur_nscb != NULL) {
if ((cur_nscb->callback == callback) &&
(cur_nscb->p == p)) {
/* item to remove */
LOG(("callback entry %p removing %p(%p)",
cur_nscb, cur_nscb->callback, cur_nscb->p));
/* remove callback */
unlnk_nscb = cur_nscb;
cur_nscb = unlnk_nscb->next;
if (prev_nscb == NULL) {
schedule_list = cur_nscb;
} else {
prev_nscb->next = cur_nscb;
}
free (unlnk_nscb);
} else {
/* move to next element */
prev_nscb = cur_nscb;
cur_nscb = prev_nscb->next;
}
}
}
/**
* Process events up to current time.
*/
int
schedule_run(void)
{
struct timeval tv;
struct timeval nexttime;
struct timeval rettime;
struct nscallback *cur_nscb;
struct nscallback *prev_nscb;
struct nscallback *unlnk_nscb;
if (schedule_list == NULL)
return -1;
/* reset enumeration to the start of the list */
cur_nscb = schedule_list;
prev_nscb = NULL;
nexttime = cur_nscb->tv;
gettimeofday(&tv, NULL);
while (cur_nscb != NULL) {
if (timercmp(&tv, &cur_nscb->tv, >)) {
/* scheduled time */
/* remove callback */
unlnk_nscb = cur_nscb;
if (prev_nscb == NULL) {
schedule_list = unlnk_nscb->next;
} else {
prev_nscb->next = unlnk_nscb->next;
}
LOG(("callback entry %p running %p(%p)",
unlnk_nscb, unlnk_nscb->callback, unlnk_nscb->p));
/* call callback */
unlnk_nscb->callback(unlnk_nscb->p);
free(unlnk_nscb);
/* need to deal with callback modifying the list. */
if (schedule_list == NULL) {
LOG(("schedule_list == NULL"));
return -1; /* no more callbacks scheduled */
}
/* reset enumeration to the start of the list */
cur_nscb = schedule_list;
prev_nscb = NULL;
nexttime = cur_nscb->tv;
} else {
/* if the time to the event is sooner than the
* currently recorded soonest event record it
*/
if (timercmp(&nexttime, &cur_nscb->tv, >)) {
nexttime = cur_nscb->tv;
}
/* move to next element */
prev_nscb = cur_nscb;
cur_nscb = prev_nscb->next;
}
}
/* make rettime relative to now */
timersub(&nexttime, &tv, &rettime);
LOG(("returning time to next event as %ldms",(rettime.tv_sec * 1000) + (rettime.tv_usec / 1000)));
/*return next event time in milliseconds (24days max wait) */
return (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000);
}
void list_schedule(void)
{
struct timeval tv;
struct nscallback *cur_nscb;
gettimeofday(&tv, NULL);
LOG(("schedule list at %ld:%ld", tv.tv_sec, tv.tv_usec));
cur_nscb = schedule_list;
while (cur_nscb != NULL) {
LOG(("Schedule %p at %ld:%ld",
cur_nscb, cur_nscb->tv.tv_sec, cur_nscb->tv.tv_usec));
cur_nscb = cur_nscb->next;
}
}
/*
* Local Variables:
* c-basic-offset:8
* End:
*/

25
atari/schedule.h Normal file
View File

@ -0,0 +1,25 @@
/*
* Copyright 2008 Vincent Sanders <vince@simtec.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NS_SCHEDULE_H
#define NS_SCHEDULE_H
void list_schedule(void);
int schedule_run(void);
#endif

223
atari/scripts/mkpkg.sh Normal file
View File

@ -0,0 +1,223 @@
#!/bin/bash
# this is an small build script to create an package for nsgem
# invoke: mkpkg.sh [-s,-d,-8,-fonts]
#
# Parameters:
#
# -8
# Description: The package will be build for 8.3 filesystems
# This also defines the -fonts parameter
#
# -fonts
# Description: The package will include the DejaVu fonts package
# ( 8.3 compatible names )
#
# -fpath
# Description: Set path to dejavu Fonts
#
# -s (srcpath)
# Description: use it like: -s "path to netsurf root" to configure from which
# directory the package files are taken.
# The Path must have trailing slash!
#
# -d (dstpath)
# Description: use it like: -d "path to dir where the package will be placed"
# to configure the output path of this script.
# The path mus have trailing slash!
#
# config variable, set default values
src="/f/netsurf/netsurf/"
dst=$src"atari/pkg/"
shortfs=0
inc_short_fonts=0
font_src="/usr/share/fonts/truetype/ttf-dejavu/"
framebuffer=0
while [ "$1" != "" ] # When there are arguments...
do # Process the next one
case $1 # Look at $1
in
-8)
shortfs="1"
shift
;;
-fonts)
inc_short_fonts="1"
shift
;;
-fpath)
shift
font_src=$1
shift
;;
-d)
shift
dst=$1
shift
;;
-s)
shift
src=$1
shift
;;
*) echo "Option [$1] not one of [-8,-fonts,-d,-s,-fpath]";
exit;;
esac
done
echo "Building from: "$src
echo "Building in: "$dst
echo "Building for short fs: "$shortfs
if [ "$shortfs" = "1" ]
then
inc_short_fonts=1
fi
if [ -d "$font_src" ]
then
echo "Found fonts in $font_src"
else
echo "Error: TTF Fonts not found ($font_src)!"
exit 0
fi
set -o verbose
rm $dst -r
mkdir $dst
cp $src"ns.prg" $dst
chmod +x $dst"ns.prg"
strip $dst"ns.prg"
cp $src"atari/res/" $dst -rL
cp $src"\!NetSurf/Resources/AdBlock,f79" $dst"res/adblock.css" -rL
cp $src"\!NetSurf/Resources/CSS,f79" $dst"res/default.css" -rL
cp $src"\!NetSurf/Resources/CSS,f79" $dst"res/quirks.css" -rL
cp $src"\!NetSurf/Resources/SearchEngines" $dst"res/search" -rL
cp $src"\!NetSurf/Resources/ca-bundle" $dst"res/cabundle" -rL
cp $src"\!NetSurf/Resources/en/Messages" $dst"res/messages" -rL
#remove uneeded files:
rm $dst"res/netsurf.rsm"
rm $dst"res/netsurf.rsh"
if [ "$inc_short_fonts" = "1" ]
then
mkdir $dst"res/fonts"
cp $font_src"DejaVuSans.ttf" $dst"res/fonts/ss.ttf"
cp $font_src"DejaVuSans-Bold.ttf" $dst"res/fonts/ssb.ttf"
cp $font_src"DejaVuSans-Oblique.ttf" $dst"res/fonts/ssi.ttf"
cp $font_src"DejaVuSans-BoldOblique.ttf" $dst"res/fonts/ssib.ttf"
cp $font_src"DejaVuSansMono.ttf" $dst"res/fonts/mono.ttf"
cp $font_src"DejaVuSansMono-Bold.ttf" $dst"res/fonts/monob.ttf"
cp $font_src"DejaVuSansMono-Oblique.ttf" $dst"res/fonts/cursive.ttf"
cp $font_src"DejaVuSerif.ttf" $dst"res/fonts/s.ttf"
cp $font_src"DejaVuSerifCondensed-Bold.ttf" $dst"res/fonts/fantasy.ttf"
fi
#rename long filenames for short mode:
if [ "$shortfs" = "1" ]
then
mv $dst"res/SearchEngines" $dst"res/Search"
mv $dst"res/ca-bundle" $dst"res/ca"
fi
#create an simple startup script:
if [ "$framebuffer" = "1" ]
then
echo "NETSURFRES=./res/
export NETSURFRES
./nsfb.prg -v file:///f/" > $dst"ns.sh"
chmod +x $dst"ns.sh"
fi
echo "
atari_screen_driver:vdi
atari_font_driver:freetype
homepage_url:file:///./
http_proxy:0
http_proxy_host:
http_proxy_port:8123
http_proxy_auth:0
http_proxy_auth_user:
http_proxy_auth_pass:
suppress_curl_debug:1
font_size:120
font_min_size:80
#font_sans:Sans
#font_serif:Serif
#font_mono:Monospace
#font_cursive:Serif
#font_fantasy:Serif
accept_language:
accept_charset:
memory_cache_size:204800
disc_cache_age:28
block_advertisements:0
minimum_gif_delay:0
send_referer:1
animate_images:1
expire_url:28
#font_default:1
ca_bundle:./res/cabundle
ca_path:./res/certs
cookie_file:./res/Cookies
cookie_jar:./res/Cookies
search_url_bar:0
search_provider:0
url_suggestion:1
window_x:0
window_y:0
window_width:0
window_height:0
window_screen_width:0
window_screen_height:0
scale:100
incremental_reflow:1
min_reflow_period:25
tree_icons_dir:./res/icons
core_select_menu:1
max_fetchers:16
max_fetchers_per_host:2
max_cached_fetch_handles:6
target_blank:1
margin_top:10
margin_bottom:10
margin_left:10
margin_right:10
export_scale:70
suppress_images:0
remove_backgrounds:0
enable_loosening:1
enable_PDF_compression:1
enable_PDF_password:0
render_resample:0
downloads_clear:0
request_overwrite:1
downloads_directory:./
url_file:./res/URLs
button_type:2
disable_popups:0
disable_plugins:0
history_age:0
hover_urls:0
focus_new:0
new_blank:0
hotlist_path:./res/Hotlist
current_theme:0
" > $dst"Choices"
cd $dst
tar cvf - ./* | gzip -c > ns.tar.gz
echo
exit 0

131
atari/slider.c Normal file
View File

@ -0,0 +1,131 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "atari/slider.h"
long inline slider_pages( long content_dim, long workarea_dim )
{
long ret;
ret = (long)ceil( (float)content_dim / (float)workarea_dim );
if( ret <= 0 )
ret = 1;
return( ret );
}
float inline slider_pages_dec( long content_dim, long workarea_dim )
{
float ret;
ret = (float)content_dim / (float)workarea_dim );
if( ret <= 0 )
ret = 1;
return( ret );
}
int slider_gem_size( long content_dim, long workarea_dim )
{
int ret;
int pages = slider_pages(content_dim, workarea_dim);
if( pages <= 0 )
return 1;
ret = 1000 / pages;
if( ret <= 0 )
ret = 1;
return( ret );
}
int slider_pos_to_gem_pos( long content_dim, long workarea_dim, long slider_pos )
{
int ret;
int spos = slider_max_pos( content_dim, workarea_dim );
if( spos < 1 )
return( 0 );
float x = (float)1000 / spos;
if(content_dim >= 1000)
ret = (int)( x * slider_pos );
else
ret = (int)ceilf( (float)x * slider_pos );
return( max(0, ret) );
}
long slider_gem_pos_to_pos( long content_dim, long workarea_dim, int slider_pos )
{
long ret;
int nmax = slider_max_pos( content_dim, workarea_dim );
float x = (float)1000 / nmax;
if(content_dim >= 1000)
ret = (int) ( (float) slider_pos * x);
else
ret = (int) ceilf( (float)slider_pos * x );
return( max(0, ret) );
}
long inline slider_gem_size_to_res( long workarea_dim, int gem_size )
{
/* subtract [<-] and [->] buttons (16*2) from workarea: */
int factor = 1000 / (workarea_dim - 16*2);
return( max(1, gem_size / factor) );
}
long slider_gem_pos_to_res( long content_dim, long workarea_dim, int gem_pos )
{
/* subtract size of boxchar: */
int room = workarea_dim - 16 * 2 - slider_gem_size_to_res(workarea_dim, slider_gem_sz );
/*
1. Berechnen welchem Prozentsatz die GEM Position entspricht:
1000 = Grundwert
gem_pos = Prozentwert
Prozentsatz = ?
Rechnung: Prozentwert * 100 / 1000
Gekürzt: Prozentwert / 10
p_calc = der Prozentsatz / 100 -> fuer vereinfachte nutzung
*/
/* float p_gem = (float)gem_pos / 10; */
float p_calc = (float)gem_pos / 1000;
/*
2. Berechnen welchem Pixel der Prozentsatz entspricht
room = Grundwert
p_gem = Prozentsatz
Prozentwert = ?
Rechnung = G * p / 100
Anmerkung: es wird p_calc verwendet, da praktischer...
*/
int pixel = (float)((float)room * p_calc)+0.5;
return( pixel );
}
/*
Not implemented
long slider_pos_to_res( long content_dim, long workarea_dim, int pos )
{
long max_pos = slider_max_pos( content_dim, workarea_dim );
return( -1 );
}
*/

57
atari/slider.h Normal file
View File

@ -0,0 +1,57 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NS_SLIDER_H_INCLUDED
#define NS_SLIDER_H_INCLUDED
/* -------------------------------------------------------------------------- */
/* Slider Interface: */
/* -------------------------------------------------------------------------- */
#define BR_SCROLLBAR_SZ 16
/* Calculate how many pixel an specific page of the content contains */
#define SLIDER_PIXELS_ON_PAGE( long content_dim, long workarea_dim, long page )\
min( workarea_dim, content_dim - page * workarea_dim)
/* Returns max internal slider pos, counting from zero */
#define SLIDER_MAX_POS(content_dim, workarea_dim) max( 0, content_dim - workarea_dim)
/* Calculate the number of content-"pages" for window size */
long inline slider_pages( long content_dim, long workarea_dim );
float inline slider_pages_dec( long content_dim, long workarea_dim )
/* Convert content size into gem slider size ( 0 - 1000 ) */
int inline slider_gem_size( long content_dim, long workarea_dim );
/* convert internal slider position to gem slider position */
int slider_pos_to_gem_pos( long content_dim, long workarea_dim, long slider_pos );
/* convert gem slider pos to "internal" pos system */
long slider_gem_pos_to_pos( long content_dim, long workarea_dim, int slider_pos );
/* Calculate the gem slider mover size into pixel size */
long slider_gem_size_to_res( long workarea_dim, int gem_size );
/* Convert the gem Slider pos to an pixel value */
long slider_gem_pos_to_res( long content_dim, long workarea_dim, int gem_pos );
#endif

178
atari/statusbar.c Normal file
View File

@ -0,0 +1,178 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <windom.h>
#include <assert.h>
#include <math.h>
#include "utils/log.h"
#include "desktop/gui.h"
#include "desktop/history_core.h"
#include "desktop/netsurf.h"
#include "desktop/browser.h"
#include "desktop/mouse.h"
#include "desktop/plotters.h"
#include "atari/gui.h"
#include "atari/statusbar.h"
#include "atari/browser_win.h"
#include "atari/misc.h"
#include "atari/global_evnt.h"
#include "atari/res/netsurf.rsh"
#include "atari/plot/plotter.h"
extern short vdih;
static
void __CDECL evnt_sb_redraw( COMPONENT *c, long buff[8] )
{
struct gui_window * gw = (struct gui_window *)mt_CompDataSearch(&app, c, CDT_OWNER);
CMP_STATUSBAR sb = gw->root->statusbar;
LGRECT work, lclip;
short pxy[8], d, pxyclip[4];
mt_CompGetLGrect(&app, sb->comp, WF_WORKXYWH, &work);
lclip = work;
if ( !rc_lintersect( (LGRECT*)&buff[4], &lclip ) ) return;
vsf_interior( vdih, FIS_SOLID );
vsl_color( vdih, BLACK );
vsl_type( vdih, 1);
vsl_width( vdih, 1 );
vst_color(vdih, BLACK);
vst_height( vdih, 10, &pxy[0], &pxy[1], &pxy[2], &pxy[3] );
vst_arbpt( vdih, 9, &pxy[0], &pxy[1], &pxy[2], &pxy[3] );
vst_alignment(vdih, 0, 5, &d, &d );
vst_effects( vdih, 0 );
pxyclip[0] = lclip.g_x;
pxyclip[1] = lclip.g_y;
pxyclip[2] = lclip.g_x + lclip.g_w;
pxyclip[3] = lclip.g_y + lclip.g_h;
vs_clip(vdih, 1, (short*)&pxyclip );
vswr_mode( vdih, MD_REPLACE );
if( lclip.g_y <= work.g_y ) {
pxy[0] = work.g_x;
pxy[1] = work.g_y;
pxy[2] = MIN( work.g_x + work.g_w, lclip.g_x + lclip.g_w );
pxy[3] = work.g_y;
v_pline( vdih, 2, (short*)&pxy );
}
vsf_color( vdih, LWHITE);
pxy[0] = work.g_x;
pxy[1] = work.g_y+1;
pxy[2] = work.g_x + work.g_w;
pxy[3] = work.g_y + work.g_h-1;
v_bar( vdih, pxy );
vswr_mode( vdih, MD_TRANS );
v_gtext( vdih, work.g_x + 2, work.g_y + 5, (char*)&sb->text );
vswr_mode( vdih, MD_REPLACE );
pxy[0] = work.g_x + work.g_w - MOVER_WH;
pxy[1] = work.g_y + 1;
pxy[2] = work.g_x + work.g_w;
pxy[3] = work.g_y + work.g_h-1;
v_bar( vdih, pxy );
pxy[0] = work.g_x + work.g_w - MOVER_WH;
pxy[1] = work.g_y + work.g_h;
pxy[2] = work.g_x + work.g_w - MOVER_WH;
pxy[3] = work.g_y + work.g_h - MOVER_WH;
v_pline( vdih, 2, (short*)&pxy );
vs_clip(vdih, 0, (short*)&pxyclip );
}
static void __CDECL evnt_sb_click( COMPONENT *c, long buff[8] )
{
short sbuff[8], mx, my;
LGRECT work;
mt_CompGetLGrect(&app, c, WF_WORKXYWH, &work);
if( evnt.mx >= work.g_x + (work.g_w - MOVER_WH) && evnt.mx <= work.g_x + work.g_w &&
evnt.my >= work.g_y + (work.g_h - MOVER_WH) && evnt.my <= work.g_y + work.g_h ) {
/* click into the mover region */
struct gui_window * g;
for( g = window_list; g; g=g->next ) {
if( g->root->statusbar->comp == c ) {
sbuff[0] = WM_SIZED;
sbuff[1] = (short)buff[0];
sbuff[2] = 0;
sbuff[3] = g->root->handle->handle;
sbuff[4] = g->root->loc.g_x;
sbuff[5] = g->root->loc.g_y;
sbuff[6] = g->root->loc.g_w;
sbuff[7] = g->root->loc.g_h;
evnt_window_resize( g->root->handle, sbuff );
}
}
}
}
CMP_STATUSBAR sb_create( struct gui_window * gw )
{
CMP_STATUSBAR s = malloc( sizeof(struct s_statusbar) );
s->comp = (COMPONENT*)mt_CompCreate(&app, CLT_HORIZONTAL, STATUSBAR_HEIGHT, 0);
s->comp->rect.g_h = STATUSBAR_HEIGHT;
s->comp->bounds.max_height = STATUSBAR_HEIGHT;
mt_CompDataAttach( &app, s->comp, CDT_OWNER, gw );
mt_CompEvntAttach( &app, s->comp, WM_REDRAW, evnt_sb_redraw );
mt_CompEvntAttach( &app, s->comp, WM_XBUTTON, evnt_sb_click );
strncpy( (char*)&s->text, "  ", 254 );
return( s );
}
void sb_destroy( CMP_STATUSBAR s )
{
LOG(("%s\n", __FUNCTION__ ));
if( s ) {
if( s->comp ){
mt_CompDelete( &app, s->comp );
}
free( s );
}
}
void sb_set_text( struct gui_window * gw , char * text )
{
if( gw->root == NULL )
return;
CMP_STATUSBAR sb = gw->root->statusbar;
LGRECT work;
if( sb == NULL || gw->browser->attached == false )
return;
strncpy( (char*)&sb->text, text, 254 );
mt_CompGetLGrect(&app, sb->comp, WF_WORKXYWH, &work);
ApplWrite( _AESapid, WM_REDRAW, gw->root->handle->handle,
work.g_x, work.g_y, work.g_w, work.g_h );
}

25
atari/statusbar.h Normal file
View File

@ -0,0 +1,25 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NS_ATARI_STATUSBAR
#define NS_ATARI_STATUSBAR
CMP_STATUSBAR sb_create( struct gui_window * gw );
void sb_destroy( CMP_STATUSBAR s );
void sb_set_text( struct gui_window * gw, char * text );
#endif

25
atari/thumbnail.c Normal file
View File

@ -0,0 +1,25 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "desktop/browser.h"
bool thumbnail_create(struct hlcache_handle *content, struct bitmap *bitmap,
const char *url)
{
return false;
}

772
atari/toolbar.c Normal file
View File

@ -0,0 +1,772 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <windom.h>
#include <cflib.h>
#include <assert.h>
#include <math.h>
#include "utils/log.h"
#include "desktop/gui.h"
#include "desktop/history_core.h"
#include "desktop/netsurf.h"
#include "desktop/browser.h"
#include "desktop/mouse.h"
#include "desktop/plotters.h"
#include "atari/clipboard.h"
#include "atari/gui.h"
#include "atari/toolbar.h"
#include "atari/browser_win.h"
#include "atari/clipboard.h"
#include "atari/misc.h"
#include "atari/global_evnt.h"
#include "atari/res/netsurf.rsh"
#include "atari/plot/plotter.h"
extern char * cfg_homepage_url;
extern short vdih;
extern void * h_gem_rsrc;
/* prototypes & order for button widgets: */
static struct s_tb_button tb_buttons[] =
{
{ TOOLBAR_BT_BACK, tb_back_click, NULL },
{ TOOLBAR_BT_HOME, tb_home_click, NULL },
{ TOOLBAR_BT_FORWARD, tb_forward_click, NULL },
{ TOOLBAR_BT_RELOAD, tb_reload_click, NULL },
{ TOOLBAR_BT_STOP, tb_stop_click, NULL },
{ 0, NULL, NULL }
};
static OBJECT * throbber_form = NULL;
static void __CDECL button_redraw( COMPONENT *c, long buff[8])
{
OBJECT *tree = (OBJECT*)mt_CompDataSearch( &app, c, CDT_OBJECT );
struct gui_window * gw = mt_CompDataSearch( &app, c, CDT_OWNER );
LGRECT work,clip;
short pxy[4];
mt_CompGetLGrect(&app, c, WF_WORKXYWH, &work);
clip = work;
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 );
tree->ob_x = work.g_x+1;
tree->ob_y = work.g_y+2;
tree->ob_width = work.g_w;
tree->ob_height = work.g_h;
vsf_interior( vdih , 1 );
vsf_color( vdih, LWHITE );
pxy[0] = (short)buff[4];
pxy[1] = (short)buff[5];
pxy[2] = (short)buff[4] + buff[6];
pxy[3] = MIN( (short)buff[5] + buff[7], work.g_y + work.g_h - 2);
vswr_mode( vdih, MD_REPLACE);
v_bar( vdih, (short*)&pxy );
mt_objc_draw( tree, 0, 8, clip.g_x, clip.g_y, clip.g_w, clip.g_h, app.aes_global );
if( gw->root->toolbar->buttons[0].comp == c && work.g_x == buff[4] ){
vsl_color( vdih, LWHITE );
pxy[0] = (short)buff[4];
pxy[1] = (short)buff[5];
pxy[2] = (short)buff[4];
pxy[3] = (short)buff[5] + buff[7];
v_pline( vdih, 2, (short*) pxy );
}
vs_clip( vdih, 0, (short*)&clip );
}
static void __CDECL button_enable( COMPONENT *c, long buff[8])
{
((OBJECT*)mt_CompDataSearch(&app, c, CDT_OBJECT))->ob_state &= ~OS_DISABLED;
}
static void __CDECL button_disable( COMPONENT *c, long buff[8])
{
((OBJECT*)mt_CompDataSearch(&app, c, CDT_OBJECT))->ob_state |= OS_DISABLED;
}
static void __CDECL button_click( COMPONENT *c, long buff[8])
{
int i = 0;
struct gui_window * gw = (struct gui_window *)mt_CompDataSearch(&app, c, CDT_OWNER);
assert( gw );
while( i < gw->root->toolbar->btcnt ) {
if(c == gw->root->toolbar->buttons[i].comp ) {
gw->root->toolbar->buttons[i].cb_click( gw );
break;
}
i++;
}
}
static struct s_tb_button * find_button( struct gui_window * gw, int rsc_id )
{
int i = 0;
while( i < gw->root->toolbar->btcnt ) {
if( gw->root->toolbar->buttons[i].rsc_id == rsc_id ) {
return( &gw->root->toolbar->buttons[i] );
}
i++;
}
}
static COMPONENT *button_create( OBJECT *o, short type, long size, short flex )
{
COMPONENT *c = mt_CompCreate( &app, type, size, flex );
OBJECT *oc = mt_ObjcNDup( &app, o, NULL, 1);
oc->ob_next = oc->ob_head = oc->ob_tail = -1;
mt_CompDataAttach( &app, c, CDT_OBJECT, oc );
mt_CompEvntAttach( &app, c, WM_REDRAW, button_redraw );
mt_CompEvntAttach( &app, c, WM_XBUTTON, button_click );
mt_CompEvntAttach( &app, c, CM_GETFOCUS, button_enable );
mt_CompEvntAttach( &app, c, CM_LOSEFOCUS, button_disable );
return c;
}
static
void __CDECL evnt_throbber_redraw( COMPONENT *c, long buff[8])
{
LGRECT work, clip;
int idx;
short pxy[4];
struct gui_window * gw = (struct gui_window *)mt_CompDataSearch(&app, c, CDT_OWNER);
idx = gw->root->toolbar->throbber.index+1;
mt_CompGetLGrect(&app, c, WF_WORKXYWH, &work);
clip = work;
if ( !rc_lintersect( (LGRECT*)&buff[4], &clip ) ) return;
vsf_interior( vdih , 1 );
vsf_color( vdih, LWHITE );
pxy[0] = (short)buff[4];
pxy[1] = (short)buff[5];
pxy[2] = (short)buff[4] + buff[6]-1;
pxy[3] = (short)buff[5] + buff[7]-2;
v_bar( vdih, (short*)&pxy );
if( throbber_form != NULL ) {
throbber_form[idx].ob_x = work.g_x+1;
throbber_form[idx].ob_y = work.g_y+4;
mt_objc_draw( throbber_form, idx, 8, clip.g_x, clip.g_y, clip.g_w, clip.g_h, app.aes_global );
}
}
static
void __CDECL evnt_url_redraw( COMPONENT *c, long buff[8] )
{
LGRECT work, clip;
short pxy[10];
short i,d;
short mchars, width, cs;
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 );
short start = gw->root->toolbar->url.scrollx;
mt_CompGetLGrect(&app, c, WF_WORKXYWH, &work);
clip = work;
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 );
width = work.g_w-6; /* subtract 6px -> 3px padding around text on each side */
cs = gw->root->toolbar->url.char_size;
mchars = (width / cs);
char textcpy[mchars+3];
memset(&textcpy, 0, mchars + 3 );
vswr_mode( vdih, MD_REPLACE);
vsf_perimeter( vdih, 0 );
vsf_interior( vdih , 1 );
vsf_color( vdih, LWHITE );
vst_arbpt( vdih, 10, &pxy[0], &pxy[1], &pxy[2], &pxy[3] );
vst_alignment(vdih, 0, 5, &d, &d );
vst_effects( vdih, 0 );
/* gray the whole component: */
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( strlen(gw->root->toolbar->url.text) > 0 )
strncpy( (char*)&textcpy, (char*)&gw->root->toolbar->url.text[start], mchars );
else
strcpy( (char*)&textcpy, " " );
vst_color( vdih, BLACK );
v_gtext( vdih, work.g_x + 3, work.g_y + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2) + 2, (char*)&textcpy );
if( window_url_widget_has_focus( gw ) ) {
/* draw caret: */
pxy[0] = 3 + work.g_x + ((gw->root->toolbar->url.caret_pos - gw->root->toolbar->url.scrollx) * cs);
pxy[1] = pxy[1] + 1;
pxy[2] = 3 + work.g_x + ((gw->root->toolbar->url.caret_pos - gw->root->toolbar->url.scrollx) * cs);
pxy[3] = pxy[3] - 1 ;
v_pline( vdih, 2, pxy );
/* draw selection: */
if( gw->root->toolbar->url.selection_len != 0 ) {
vswr_mode( vdih, MD_XOR);
vsl_color( vdih, BLACK);
pxy[0] = 3 + work.g_x + ((gw->root->toolbar->url.caret_pos - gw->root->toolbar->url.scrollx) * cs);
pxy[2] = pxy[0] + ( gw->root->toolbar->url.selection_len * cs);
v_bar( vdih, pxy );
vswr_mode( vdih, MD_REPLACE );
}
}
vs_clip( vdih, 0, (short*)&pxy );
}
static
void __CDECL evnt_url_click( COMPONENT *c, long buff[8] )
{
LGRECT work;
short pxy[4];
short mx, my, mb, kstat;
int old;
graf_mkstate( &mx, &my, &mb, &kstat );
struct gui_window * gw = (struct gui_window *)mt_CompDataSearch(&app, c, CDT_OWNER);
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;
/* 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 );
} 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;
} 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);
}
}
ApplWrite( _AESapid, WM_REDRAW, gw->root->handle->handle,
work.g_x, work.g_y, work.g_w, work.g_h );
}
static void __CDECL evnt_toolbar_redraw( COMPONENT *c, long buff[8], void *data )
{
LGRECT work, clip;
short pxy[4];
mt_CompGetLGrect(&app, c, WF_WORKXYWH, &work);
clip = work;
if( !rc_lintersect( (LGRECT*)&buff[4], &clip ) ) return;
if( work.g_y + work.g_h != clip.g_y + clip.g_h ) return;
vswr_mode( vdih, MD_REPLACE );
vsl_color( vdih, BLACK );
vsl_type( vdih, 1 );
vsl_width( vdih, 1 );
pxy[0] = clip.g_x;
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 );
}
CMP_TOOLBAR tb_create( struct gui_window * gw )
{
int i;
OBJECT * tbut;
CMP_TOOLBAR t = malloc( sizeof(struct s_toolbar) );
if( t == NULL )
return( NULL );
t->owner = gw;
/* create the root component: */
t->comp = (COMPONENT*)mt_CompCreate(&app, CLT_HORIZONTAL, TOOLBAR_HEIGHT, 0);
t->comp->rect.g_h = TOOLBAR_HEIGHT;
t->comp->bounds.max_height = TOOLBAR_HEIGHT;
mt_CompEvntDataAdd(&app, t->comp, WM_REDRAW, evnt_toolbar_redraw, NULL, EV_BOT);
/* count buttons and add them as components: */
RsrcGaddr( h_gem_rsrc, R_TREE, TOOLBAR , &tbut );
t->btdim.g_x = 0;
t->btdim.g_y = 1;
t->btdim.g_w = 0;
t->btdim.g_h = TB_BUTTON_HEIGHT+1;
i = 0;
while( tb_buttons[i].rsc_id > 0 ) {
i++;
}
t->btcnt = i;
t->buttons = malloc( sizeof(struct s_tb_button) * t->btcnt );
for( i=0; i < t->btcnt; i++ ) {
t->buttons[i].rsc_id = tb_buttons[i].rsc_id;
t->buttons[i].cb_click = tb_buttons[i].cb_click;
t->buttons[i].comp = button_create( &tbut[t->buttons[i].rsc_id] , CLT_VERTICAL, TB_BUTTON_WIDTH+1, 0);
mt_CompDataAttach( &app, t->buttons[i].comp, CDT_OWNER, gw );
t->buttons[i].comp->bounds.max_width = TB_BUTTON_WIDTH+1;
mt_CompAttach( &app, t->comp, t->buttons[i].comp );
t->btdim.g_w += TB_BUTTON_WIDTH+1;
}
/* 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.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 );
mt_CompDataAttach( &app, t->url.comp, CDT_OWNER, gw );
mt_CompAttach( &app, t->comp, t->url.comp );
/* create the throbber widget: */
if( throbber_form == NULL ) {
RsrcGaddr( h_gem_rsrc, R_TREE, THROBBER , &throbber_form );
throbber_form->ob_x = 0;
throbber_form->ob_y = 0;
}
t->throbber.comp = (COMPONENT*)mt_CompCreate(&app, CLT_HORIZONTAL, TOOLBAR_HEIGHT, 0);
t->throbber.comp->rect.g_h = TOOLBAR_HEIGHT;
t->throbber.comp->rect.g_w = 32;
t->throbber.comp->bounds.max_height = TOOLBAR_HEIGHT;
t->throbber.comp->bounds.max_width = 32;
t->throbber.index = 0;
t->throbber.max_index = 7;
t->throbber.running = false;
mt_CompEvntAttach( &app, t->throbber.comp, WM_REDRAW, evnt_throbber_redraw );
mt_CompDataAttach( &app, t->throbber.comp, CDT_OWNER, gw );
mt_CompAttach( &app, t->comp, t->throbber.comp );
return( t );
}
void tb_destroy( CMP_TOOLBAR tb )
{
int i=0;
while( i < tb->btcnt ) {
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 );
mt_CompDelete( &app, tb->comp);
free( tb );
}
struct gui_window * tb_gui_window( CMP_TOOLBAR tb )
{
struct gui_window * gw;
gw = window_list;
while( gw != NULL ) {
if( gw->root->toolbar == tb ) {
LOG(("found tb gw: %p (tb: %p) for tb: %p", gw, gw->root->toolbar, tb ));
return( gw );
}
else
gw = gw->next;
}
return( NULL );
}
void tb_update_buttons( struct gui_window * gw )
{
struct s_tb_button * bt;
return; /* not working correctly, buttons disabled, even if it shouldn't */
bt = find_button( gw, TOOLBAR_BT_BACK );
if( browser_window_back_available(gw->browser->bw) ) {
((OBJECT*)mt_CompDataSearch(&app, bt->comp, CDT_OBJECT))->ob_state |= OS_DISABLED;
} else {
((OBJECT*)mt_CompDataSearch(&app, bt->comp, CDT_OBJECT))->ob_state &= ~OS_DISABLED;
}
mt_CompEvntRedraw( &app, bt->comp );
bt = find_button( gw, TOOLBAR_BT_FORWARD );
if( browser_window_forward_available(gw->browser->bw) ) {
((OBJECT*)mt_CompDataSearch(&app, bt->comp, CDT_OBJECT))->ob_state |= OS_DISABLED;
} else {
((OBJECT*)mt_CompDataSearch(&app, bt->comp, CDT_OBJECT))->ob_state &= ~OS_DISABLED;
}
mt_CompEvntRedraw( &app, bt->comp );
bt = find_button( gw, TOOLBAR_BT_RELOAD );
if( browser_window_reload_available(gw->browser->bw) ) {
((OBJECT*)mt_CompDataSearch(&app, bt->comp, CDT_OBJECT))->ob_state |= OS_DISABLED;
} else {
((OBJECT*)mt_CompDataSearch(&app, bt->comp, CDT_OBJECT))->ob_state &= ~OS_DISABLED;
}
mt_CompEvntRedraw( &app, bt->comp );
bt = find_button( gw, TOOLBAR_BT_STOP );
if( browser_window_stop_available(gw->browser->bw) ) {
((OBJECT*)mt_CompDataSearch(&app, bt->comp, CDT_OBJECT))->ob_state |= OS_DISABLED;
} else {
((OBJECT*)mt_CompDataSearch(&app, bt->comp, CDT_OBJECT))->ob_state &= ~OS_DISABLED;
}
mt_CompEvntRedraw( &app, bt->comp );
}
void tb_url_set( struct gui_window * gw, char * text )
{
LGRECT work;
int len = strlen(text);
char * newtext;
int newsize;
if( gw->root->toolbar == NULL )
return;
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;
}
/* -------------------------------------------------------------------------- */
/* Public Module event handlers: */
/* -------------------------------------------------------------------------- */
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);
assert( gw != NULL );
/* make sure we navigate within the root window on enter: */
assert( gw->parent == NULL );
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; i<l; i++) {
tb_url_input( gw, clip[i] );
}
free( clip );
ret = true;
}
}
else if( (code == NK_DEL) && tb->url.text[tb->url.caret_pos] != 0) {
if( 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 {
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 );
}
void tb_back_click( struct gui_window * gw )
{
struct browser_window *bw = gw->browser->bw;
if( history_back_available(bw->history) )
history_back(bw, bw->history);
tb_update_buttons(gw);
}
void tb_reload_click( struct gui_window * gw )
{
browser_window_reload( gw->browser->bw, true );
}
void tb_forward_click( struct gui_window * gw )
{
struct browser_window *bw = gw->browser->bw;
if (history_forward_available(bw->history))
history_forward(bw, bw->history);
tb_update_buttons(gw);
}
void tb_home_click( struct gui_window * gw )
{
browser_window_go(gw->browser->bw, cfg_homepage_url, 0, true);
tb_update_buttons(gw);
}
void tb_stop_click( struct gui_window * gw )
{
browser_window_stop( gw->browser->bw );
}

51
atari/toolbar.h Normal file
View File

@ -0,0 +1,51 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NS_ATARI_TOOLBAR_H
#define NS_ATARI_TOOLBAR_H
CMP_TOOLBAR tb_create( struct gui_window * gw );
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 );
/* 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 );
void tb_reload_click( struct gui_window * gw );
void tb_forward_click( struct gui_window * gw );
void tb_home_click( struct gui_window * gw );
void tb_stop_click( struct gui_window * gw );
/* enable / disable buttons etc. */
void tb_update_buttons( struct gui_window * gw );
/* handles clicks on url widget: */
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 );
struct gui_window * tb_gui_window( CMP_TOOLBAR tb );
#endif

220
atari/treeview.c Normal file
View File

@ -0,0 +1,220 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <windom.h>
#include "content/urldb.h"
#include "desktop/browser.h"
#include "desktop/plotters.h"
#include "desktop/textinput.h"
#include "desktop/tree.h"
#include "desktop/tree_url_node.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/utils.h"
#include "atari/gui.h"
#include "atari/treeview.h"
const char tree_directory_icon_name[] = "directory.png";
const char tree_content_icon_name[] = "content.png";
static void atari_treeview_request_redraw(int x,int y,int w,int h,void *pw);
static void atari_treeview_resized(struct tree *tree,int w,int h,void *pw);
static void atari_treeview_scroll_visible(int y, int h, void *pw);
static void atari_treeview_get_dimensions(int *width, int *height,void *pw);
static const struct treeview_table atari_tree_callbacks = {
atari_treeview_request_redraw,
atari_treeview_resized,
atari_treeview_scroll_visible,
atari_treeview_get_dimensions
};
NSTREEVIEW atari_treeview_create( uint32_t flags, WINDOW *win )
{
LOG(("flags: %d", flags));
NSTREEVIEW new = malloc(sizeof(struct atari_treeview));
if (new == NULL)
return NULL;
memset( new, 0, sizeof(struct atari_treeview));
new->tree = tree_create(flags, &atari_tree_callbacks, new);
if (new->tree == NULL) {
free(new);
return NULL;
}
new->window = win;
return(new);
}
void atari_treeview_open( NSTREEVIEW tv )
{
LOG(("tree: %p", tv));
if( tv->window != NULL ) {
}
}
void atari_treeview_close( NSTREEVIEW tv )
{
if( tv->window != NULL ) {
}
}
void atari_treeview_destroy( NSTREEVIEW tv )
{
LOG(("tree: %p", tv));
if( tv->tree != NULL ) {
tree_delete(tv->tree);
tv->tree = NULL;
}
}
struct tree * atari_treeview_get_tree( NSTREEVIEW tv )
{
return( tv->tree );
}
WINDOW * atari_tree_get_window( NSTREEVIEW tv )
{
return( tv->window );
}
/**
* Callback to force a redraw of part of the treeview window.
*
* \param x Min X Coordinate of area to be redrawn.
* \param y Min Y Coordinate of area to be redrawn.
* \param width Width of area to be redrawn.
* \param height Height of area to be redrawn.
* \param pw The treeview object to be redrawn.
*/
void atari_treeview_request_redraw(int x, int y, int w, int h, void *pw)
{
LOG(("tree: %p", pw));
if (pw != NULL) {
NSTREEVIEW tv = (NSTREEVIEW) pw;
tv->redraw.required = true;
}
}
/**
* Callback to notify us of a new overall tree size.
*
* \param tree The tree being resized.
* \param width The new width of the window.
* \param height The new height of the window.
* \param *pw The treeview object to be resized.
*/
void atari_treeview_resized(struct tree *tree, int width, int height, void *pw)
{
LOG(("tree: %p", pw));
if (pw != NULL) {
NSTREEVIEW tv = (NSTREEVIEW) pw;
}
}
/**
* Callback to request that a section of the tree is scrolled into view.
*
* \param y The Y coordinate of top of the area in NS units.
* \param height The height of the area in NS units.
* \param *pw The treeview object affected.
*/
void atari_treeview_scroll_visible(int y, int height, void *pw)
{
LOG(("tree: %p", pw));
if (pw != NULL) {
NSTREEVIEW tv = (NSTREEVIEW) pw;
}
}
/**
* Callback to return the tree window dimensions to the treeview system.
*
* \param *width Return the window width.
* \param *height Return the window height.
* \param *pw The treeview object to use.
*/
void atari_treeview_get_dimensions(int *width, int *height,
void *pw)
{
LOG(("tree: %p", pw));
if (pw != NULL && (width != NULL || height != NULL)) {
NSTREEVIEW tv = (NSTREEVIEW) pw;
}
}
/**
* Translates a content_type to the name of a respective icon
*
* \param content_type content type
* \param buffer buffer for the icon name
*/
void tree_icon_name_from_content_type(char *buffer, content_type type)
{
switch (type) {
case CONTENT_HTML:
case CONTENT_TEXTPLAIN:
case CONTENT_CSS:
#if defined(WITH_MNG) || defined(WITH_PNG)
case CONTENT_PNG:
#endif
#ifdef WITH_MNG
case CONTENT_JNG:
case CONTENT_MNG:
#endif
#ifdef WITH_JPEG
case CONTENT_JPEG:
#endif
#ifdef WITH_GIF
case CONTENT_GIF:
#endif
#ifdef WITH_BMP
case CONTENT_BMP:
case CONTENT_ICO:
#endif
#ifdef WITH_SPRITE
case CONTENT_SPRITE:
#endif
#ifdef WITH_DRAW
case CONTENT_DRAW:
#endif
#ifdef WITH_ARTWORKS
case CONTENT_ARTWORKS:
#endif
#ifdef WITH_NS_SVG
case CONTENT_SVG:
#endif
default:
sprintf(buffer, tree_content_icon_name);
break;
}
}

51
atari/treeview.h Normal file
View File

@ -0,0 +1,51 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NS_ATARI_TREEVIEW_H
#define NS_ATARI_TREEVIEW_H
#include <stdbool.h>
#include <windom.h>
#include "desktop/tree.h"
#include "atari/gui.h"
/* defined in front end code */
/*
extern const char tree_directory_icon_name[];
extern const char tree_content_icon_name[];
*/
struct atari_treeview
{
struct tree * tree;
WINDOW * window;
struct s_browser_redrw_info redraw;
/*tree_drag_type drag;*/
};
typedef struct atari_treeview * NSTREEVIEW;
NSTREEVIEW atari_treeview_create( uint32_t flags, WINDOW * win ) ;
void atari_treeview_destroy( NSTREEVIEW tv );
void atari_treeview_open( NSTREEVIEW tv );
void atari_treeview_close( NSTREEVIEW tv );
struct tree * atari_treeview_get_tree( NSTREEVIEW tv );
WINDOW * atari_tree_get_window( NSTREEVIEW tv );
#endif

272
atari/verify_ssl.c Normal file
View File

@ -0,0 +1,272 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <windom.h>
#include "utils/errors.h"
#include "utils/utils.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "content/urldb.h"
#include "content/fetch.h"
#include "atari/res/netsurf.rsh"
#include "atari/verify_ssl.h"
/*
todo: this file need to use the treeview api - complete rework,
current implementation is not used in any way.
*/
extern void * h_gem_rsrc;
extern short vdih;
#define CERT_INF_LINES 8
static struct ssl_info_draw_param
{
struct ssl_cert_info * cert_infos_n;
unsigned long num_certs;
int current;
int scrollx;
int cols;
int scrolly;
int rows; /* assumed to be 8 */
OBJECT * tree;
} dp;
static int cert_display_width( struct ssl_cert_info * cert_info )
{
int l1, l2;
int max=0;
int i;
int add = 16; /* strlen("Issuer: "); */
l1 = strlen(cert_info->issuer) + add;
l2 = strlen(cert_info->subject) + add;
return( MAX(l1, l2) );
}
static void __CDECL cert_info_draw( WINDOW * win, short buf[8], void * data)
{
struct ssl_info_draw_param * dp = (struct ssl_info_draw_param *)data;
GRECT work;
short pxy[4];
int maxchars;
short d, cbh, cbw;
int i = 0;
short x,y,w,h;
int px_ypos, px_xpos;
char * line = malloc(512);
if( line == NULL )
return;
LOG(("Cert info draw, win: %p, data: %p, scrollx: %d", win, data, dp->scrollx ));
WindGet( win, WF_WORKXYWH, &x, &y, &w, &h );
/*using static values here, as RsrcUserDraw has mem leaks & a very small stack */
pxy[0] = work.g_x = x + 8;
pxy[1] = work.g_y = y + 80;
pxy[2] = x + 8 + 272;
pxy[3] = y + 80 + 176;
work.g_w = 272;
work.g_h = 176;
maxchars = (work.g_w / 8)+1;
vs_clip( vdih, 1,(short*) &pxy );
vswr_mode( vdih, MD_REPLACE );
vsf_interior( vdih, 1 );
vsf_color( vdih, LWHITE );
v_bar( vdih, (short*)&pxy );
vst_height( vdih, 16, &d, &d, &cbw, &cbh );
vst_alignment(vdih, 0, 5, &d, &d );
vst_color( vdih, BLACK );
vst_effects( vdih, 0 );
px_ypos = px_xpos = 0;
for(i=0; i<CERT_INF_LINES; i++ ) {
switch( i ) {
case 0:
sprintf(line, "Cert Version: %d", dp->cert_infos_n[dp->current].version );
break;
case 1:
sprintf(line, "Invalid before: %s", &dp->cert_infos_n[dp->current].not_before );
break;
case 2:
sprintf(line, "Invalid after: %s", &dp->cert_infos_n[dp->current].not_after );
break;
case 3:
sprintf(line, "Signature type: %d", dp->cert_infos_n[dp->current].sig_type );
break;
case 4:
sprintf(line, "Serial: %d", dp->cert_infos_n[dp->current].serial );
break;
case 5:
sprintf(line, "Issuer: %s", &dp->cert_infos_n[dp->current].issuer );
break;
case 6:
sprintf(line, "Subject: %s", &dp->cert_infos_n[dp->current].subject );
break;
case 7:
sprintf(line, "Cert type: %d", dp->cert_infos_n[dp->current].cert_type );
break;
default:
break;
}
if( (int)strlen(line) > dp->scrollx ) {
if( dp->scrollx + maxchars < 511 && ( (signed int)strlen(line) - dp->scrollx) > maxchars )
line[dp->scrollx + maxchars] = 0;
v_gtext(vdih, work.g_x + 1, work.g_y + px_ypos, &line[dp->scrollx]);
}
px_ypos += cbh;
}
vst_alignment(vdih, 0, 0, &d, &d );
vs_clip( vdih, 0, (short*)&pxy );
free( line );
}
static void do_popup( WINDOW *win, int index, int mode, void *data)
{
struct ssl_info_draw_param * dp = (struct ssl_info_draw_param *)data;
char * items[dp->num_certs];
short x, y;
unsigned int i;
int dispw;
LOG(("do_popup: num certs: %d", dp->num_certs));
for( i = 0; i<dp->num_certs; i++) {
items[i] = malloc( 48 );
strncpy(items[i], (char*)&dp->cert_infos_n[i].issuer, 46 );
}
objc_offset( FORM(win), index, &x, &y );
dp->current = MenuPopUp( items, x, y,
dp->num_certs, MIN( 3, dp->num_certs), 0,
P_LIST + P_WNDW + P_CHCK );
ObjcChange( OC_FORM, win, index, NORMAL, TRUE );
dp->cols = cert_display_width( &dp->cert_infos_n[dp->current] );
dp->rows = 8;
dp->scrollx = 0;
dp->scrolly = 0;
/* Send (!) redraw ( OC_MSG ) */
ObjcDrawParent( OC_FORM, FORM(win), VERIFY_BOX_DETAILS, 1, 7 | OC_MSG );
for( i = 0; i<dp->num_certs; i++) {
free( items[i] );
}
}
bool verify_ssl_form_do( const char * url, const struct ssl_cert_info * cert_infos_n ,
unsigned long num_certs )
{
OBJECT *tree;
WINDOW * form;
bool bres = false;
bool cont = true;
int res = 0;
dp.cert_infos_n = (struct ssl_cert_info *)cert_infos_n;
dp.num_certs = num_certs;
dp.scrollx = 0;
dp.scrolly = 0;
dp.current = 0;
dp.cols = cert_display_width( &dp.cert_infos_n[dp.current] );
dp.rows = 8;
dp.tree = tree;
RsrcGaddr (h_gem_rsrc , R_TREE, VERIFY, &tree);
ObjcString( tree, VERIFY_LBL_HOST, (char*)url );
ObjcChange( OC_OBJC, tree, VERIFY_BT_ACCEPT, 0, 0 );
ObjcChange( OC_OBJC, tree, VERIFY_BT_REJECT, 0, 0 );
form = FormWindBegin( tree, (char*)"SSL Verify failed" );
EvntDataAdd( form, WM_REDRAW, cert_info_draw, (void*)&dp, EV_BOT );
/* this results in some extended objects which can not be freed: :( */
/* RsrcUserDraw( OC_FORM, tree, VERIFY_BOX_DETAILS, cert_info_draw,(void*)&dp ) ; */
ObjcAttachFormFunc( form, VERIFY_BT_NEXT_CERT, do_popup, &dp );
/*
ObjcAttachFormFunc( form, VERIFY_BT_NEXT_CERT, do_popup, &dp );
ObjcAttachFormFunc( form, VERIFY_BT_NEXT_CERT, do_popup, &dp );
*/
while( cont ) {
res = FormWindDo( MU_MESAG );
cont = false;
switch( res ){
case VERIFY_BT_ACCEPT:
bres = true;
break;
case VERIFY_BT_NEXT_CERT:
/* select box clicked or dragged... */
cont = true;
break;
case VERIFY_BT_REJECT:
bres = false;
break;
case VERIFY_BT_SCROLL_D:
cont = true;
dp.scrolly += 1;
ObjcDrawParent( OC_FORM, form, VERIFY_BOX_DETAILS, 1, 7 | OC_MSG );
break;
case VERIFY_BT_SCROLL_U:
cont = true;
dp.scrolly -= 1;
ObjcDrawParent( OC_FORM, form, VERIFY_BOX_DETAILS, 1, 7 | OC_MSG );
break;
case VERIFY_BT_SCROLL_R:
LOG(( "scroll r!" ));
cont = true;
dp.scrollx += 1;
if( dp.scrollx > (dp.cols - (272 / 8 )) )
dp.scrollx -= 1;
ObjcDrawParent( OC_FORM, form, VERIFY_BOX_DETAILS, 1, 7 | OC_MSG);
break;
case VERIFY_BT_SCROLL_L:
cont = true;
dp.scrollx -= 1;
if( dp.scrollx < 0 )
dp.scrollx = 0;
ObjcDrawParent( OC_FORM, form, VERIFY_BOX_DETAILS, 1, 7 | OC_MSG );
break;
default:
break;
}
}
FormWindEnd( );
return( bres );
}

24
atari/verify_ssl.h Normal file
View File

@ -0,0 +1,24 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NS_VERIFY_SSL_H_INCLUDED
#define NS_VERIFY_SSL_H_INCLUDED
bool verify_ssl_form_do( const char * url, const struct ssl_cert_info * cert_infos_n , unsigned long num_certs );
#endif

View File

@ -47,6 +47,8 @@
#include "amiga/options.h"
#elif defined(nsframebuffer)
#include "framebuffer/options.h"
#elif defined(nsatari)
#include "atari/options.h"
#else
#define EXTRA_OPTION_DEFINE
#define EXTRA_OPTION_TABLE

View File

@ -35,6 +35,10 @@
#ifndef ABS
#define ABS(x) (((x)>0)?(x):(-(x)))
#endif
#ifdef __MINT__ /* avoid using GCCs builtin min/max functions */
#undef min
#undef max
#endif
#ifndef min
#define min(x,y) (((x)<(y))?(x):(y))
#endif
@ -52,6 +56,10 @@
#define strtof(s,p) ((float)(strtod((s),(p))))
#endif
#if !defined(ceilf) && defined(__MINT__)
#define ceilf(x) (float)ceil((double)x)
#endif
/**
* Calculate length of constant C string.
*