diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/plain.cc | 217 |
1 files changed, 100 insertions, 117 deletions
diff --git a/src/plain.cc b/src/plain.cc index 24089fc0..217f4a10 100644 --- a/src/plain.cc +++ b/src/plain.cc @@ -16,6 +16,7 @@ #include <string.h> /* for memcpy and memmove */ #include <math.h> /* for rint() */ +#include "msg.h" #include "prefs.h" #include "cache.h" #include "bw.h" @@ -33,37 +34,30 @@ using namespace dw; using namespace dw::core; -typedef struct _DilloPlainED DilloPlainED; - -struct _DilloPlainED { - class PlainEventReceiver: public dw::core::Widget::EventReceiver - { - private: - DilloPlainED *ed; +class DilloPlain { +private: + class PlainEventReceiver: public dw::core::Widget::EventReceiver { public: - inline PlainEventReceiver (DilloPlainED *ed) { this->ed = ed; } - + DilloPlain *plain; bool buttonPress(dw::core::Widget *widget, dw::core::EventButton *event); }; + PlainEventReceiver plainReceiver; - // Since DilloPlain is a struct, not a class, a simple - // "PlainEventReceiver eventReceiver" (see signal documentation) would not - // work, therefore the pointer. - PlainEventReceiver *eventReceiver; - +public: BrowserWindow *bw; DilloUrl *url; -}; -typedef struct _DilloPlain { Widget *dw; - DilloPlainED *eventdata; - size_t Start_Ofs; /* Offset of where to start reading next */ style::Style *widgetStyle; - BrowserWindow *bw; + size_t Start_Ofs; /* Offset of where to start reading next */ int state; -} DilloPlain; + + DilloPlain(BrowserWindow *bw, const DilloUrl *url); + ~DilloPlain(); + + void write(void *Buf, uint_t BufSize, int Eof); +}; /* FSM states */ enum { @@ -82,68 +76,29 @@ void *a_Plain_text(const char *type, void *P, CA_Callback_t *Call,void **Data); /* * Forward declarations */ -static void Plain_write(DilloPlain *plain, void *Buf, uint_t BufSize, int Eof); static void Plain_callback(int Op, CacheClient_t *Client); +void a_Plain_free(void *data); -/* - * Create the plain event-data structure (analog to linkblock in HTML). - */ -static DilloPlainED *Plain_ed_new(BrowserWindow *bw, const DilloUrl *url) -{ - DilloPlainED *plain_ed = dNew(DilloPlainED, 1); - - plain_ed->eventReceiver = new DilloPlainED::PlainEventReceiver (plain_ed); - plain_ed->bw = bw; - plain_ed->url = a_Url_dup(url); - - return plain_ed; -} - -/* - * Free memory used by the eventdata structure - */ -static void Plain_ed_free(void *ed) -{ - DilloPlainED *plain_ed = (DilloPlainED *)ed; - - delete plain_ed->eventReceiver; - a_Url_free(plain_ed->url); - - dFree(plain_ed); -} /* - * Receive the mouse button press event + * Diplain constructor. */ -bool DilloPlainED::PlainEventReceiver::buttonPress (Widget *widget, - EventButton *event) +DilloPlain::DilloPlain(BrowserWindow *p_bw, const DilloUrl *p_url) { - if (event->button == 3) { - a_UIcmd_page_popup(ed->bw, ed->url, NULL); - return true; - } - return false; -} - -/* - * Create and initialize a new DilloPlain structure. - */ -static DilloPlain *Plain_new(BrowserWindow *bw, const DilloUrl *url) -{ - DilloPlain *plain; Textblock *textblock; style::StyleAttrs styleAttrs; style::FontAttrs fontAttrs; - plain = dNew(DilloPlain, 1); - plain->state = ST_SeekingEol; - plain->Start_Ofs = 0; - plain->bw = bw; - textblock = new Textblock (false); - plain->dw = (Widget*) textblock; + /* init event receiver */ + plainReceiver.plain = this; - // BUG: event receiver is never freed. - plain->eventdata = Plain_ed_new(bw, url); + /* Init internal variables */ + bw = p_bw; + url = a_Url_dup(p_url); + textblock = new Textblock (false); + dw = (Widget*) textblock; + Start_Ofs = 0; + state = ST_SeekingEol; /* Create the font and attribute for the page. */ fontAttrs.name = "Courier"; @@ -158,98 +113,126 @@ static DilloPlain *Plain_new(BrowserWindow *bw, const DilloUrl *url) styleAttrs.color = style::Color::createSimple (layout, prefs.text_color); styleAttrs.backgroundColor = style::Color::createSimple (layout, prefs.bg_color); - plain->widgetStyle = style::Style::create (layout, &styleAttrs); + widgetStyle = style::Style::create (layout, &styleAttrs); /* The context menu */ - textblock->connectEvent (plain->eventdata->eventReceiver); + textblock->connectEvent (&plainReceiver); - return plain; + /* Hook destructor to the dw delete call */ + dw->setDeleteCallback(a_Plain_free, this); } /* - * Set callback function and callback data for "text/" MIME major-type. + * Free memory used by the DilloPlain class. */ -void *a_Plain_text(const char *type, void *P, CA_Callback_t *Call, void **Data) +DilloPlain::~DilloPlain() { - DilloWeb *web = (DilloWeb*)P; - DilloPlain *plain = Plain_new(web->bw, web->url); - - *Call = (CA_Callback_t)Plain_callback; - *Data = (void*)plain; - - return (void*)plain->dw; + a_Url_free(url); + widgetStyle->unref(); } /* - * This function is a cache client + * Receive the mouse button press event */ -static void Plain_callback(int Op, CacheClient_t *Client) +bool DilloPlain::PlainEventReceiver::buttonPress (Widget *widget, + EventButton *event) { - DilloPlain *plain = (DilloPlain*)Client->CbData; - Textblock *textblock = (Textblock*)plain->dw; - - if (Op) { - /* Do the last line: */ - if (plain->Start_Ofs < Client->BufSize) - Plain_write(plain, Client->Buf, Client->BufSize, 1); - /* remove this client from our active list */ - a_Bw_close_client(plain->bw, Client->Key); - /* set progress bar insensitive */ - a_UIcmd_set_page_prog(plain->bw, 0, 0); + _MSG("DilloPlain::PlainEventReceiver::buttonPress\n"); - plain->widgetStyle->unref(); - dFree(plain); - } else { - Plain_write(plain, Client->Buf, Client->BufSize, 0); + if (event->button == 3) { + a_UIcmd_page_popup(plain->bw, plain->url, NULL); + return true; } - - textblock->flush(); + return false; } /* * Here we parse plain text and put it into the page structure. * (This function is called by Plain_callback whenever there's new data) */ -static void Plain_write(DilloPlain *plain, void *Buf, uint_t BufSize, int Eof) +void DilloPlain::write(void *Buf, uint_t BufSize, int Eof) { - Textblock *textblock = (Textblock*)plain->dw; + Textblock *textblock = (Textblock*)dw; char *Start; char *data; uint_t i, len, MaxBytes; - Start = (char*)Buf + plain->Start_Ofs; - MaxBytes = BufSize - plain->Start_Ofs; + Start = (char*)Buf + Start_Ofs; + MaxBytes = BufSize - Start_Ofs; i = len = 0; while ( i < MaxBytes ) { - switch ( plain->state ) { + switch ( state ) { case ST_SeekingEol: if (Start[i] == '\n' || Start[i] == '\r') - plain->state = ST_Eol; + state = ST_Eol; else { ++i; ++len; } break; case ST_Eol: data = dStrndup(Start + i - len, len); - textblock->addText(a_Misc_expand_tabs(data), plain->widgetStyle); - textblock->addParbreak(0, plain->widgetStyle); + textblock->addText(a_Misc_expand_tabs(data), widgetStyle); + textblock->addParbreak(0, widgetStyle); dFree(data); if (Start[i] == '\r' && Start[i + 1] == '\n') ++i; if (i < MaxBytes) ++i; - plain->state = ST_SeekingEol; + state = ST_SeekingEol; len = 0; break; } } - plain->Start_Ofs += i - len; + Start_Ofs += i - len; if (Eof && len) { data = dStrndup(Start + i - len, len); - textblock->addText(a_Misc_expand_tabs(data), plain->widgetStyle); - textblock->addParbreak(0, plain->widgetStyle); + textblock->addText(a_Misc_expand_tabs(data), widgetStyle); + textblock->addParbreak(0, widgetStyle); dFree(data); - plain->Start_Ofs += len; + Start_Ofs += len; } - if (plain->bw) - a_UIcmd_set_page_prog(plain->bw, plain->Start_Ofs, 1); + textblock->flush(); + + if (bw) + a_UIcmd_set_page_prog(bw, Start_Ofs, 1); } + +/* + * Set callback function and callback data for "text/" MIME major-type. + */ +void *a_Plain_text(const char *type, void *P, CA_Callback_t *Call, void **Data) +{ + DilloWeb *web = (DilloWeb*)P; + DilloPlain *plain = new DilloPlain(web->bw, web->url); + + *Call = (CA_Callback_t)Plain_callback; + *Data = (void*)plain; + + return (void*)plain->dw; +} + +void a_Plain_free(void *data) +{ + MSG("a_Plain_free! %p\n", data); + delete ((DilloPlain *)data); +} + +/* + * This function is a cache client + */ +static void Plain_callback(int Op, CacheClient_t *Client) +{ + DilloPlain *plain = (DilloPlain*)Client->CbData; + + if (Op) { + /* Do the last line: */ + if (plain->Start_Ofs < Client->BufSize) + plain->write(Client->Buf, Client->BufSize, 1); + /* remove this client from our active list */ + a_Bw_close_client(plain->bw, Client->Key); + /* set progress bar insensitive */ + a_UIcmd_set_page_prog(plain->bw, 0, 0); + } else { + plain->write(Client->Buf, Client->BufSize, 0); + } +} + |