From e4d780c476bfab347c55a75a65209ec9df8148a8 Mon Sep 17 00:00:00 2001 From: James Bursa Date: Tue, 22 Jun 2004 18:48:33 +0000 Subject: [project @ 2004-06-22 18:48:33 by bursa] Experimental gtk interface. svn path=/import/netsurf/; revision=993 --- gtk/font_pango.c | 166 +++++++++++++++++++++++ gtk/gtk_gui.c | 133 ++++++++++++++++++ gtk/gtk_window.c | 401 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ makefile | 4 +- 4 files changed, 702 insertions(+), 2 deletions(-) create mode 100644 gtk/font_pango.c create mode 100644 gtk/gtk_gui.c create mode 100644 gtk/gtk_window.c diff --git a/gtk/font_pango.c b/gtk/font_pango.c new file mode 100644 index 000000000..17ef149c3 --- /dev/null +++ b/gtk/font_pango.c @@ -0,0 +1,166 @@ +/* + * This file is part of NetSurf, http://netsurf.sourceforge.net/ + * Licensed under the GNU General Public License, + * http://www.opensource.org/licenses/gpl-license + * Copyright 2004 James Bursa + */ + +#include +#include +#include +#include "netsurf/css/css.h" +#include "netsurf/render/font.h" +#include "netsurf/utils/utils.h" +#include "netsurf/utils/log.h" + + +struct font_set { + int x; +}; + + +struct font_set *font_new_set() +{ + return 0; +} + + +struct font_data *font_open(struct font_set *set, struct css_style *style) +{ + struct font_data *data; + unsigned int size = PANGO_SCALE * 11; + PangoFontDescription *fontdesc; + PangoWeight weight = PANGO_WEIGHT_NORMAL; + PangoStyle styl = PANGO_STYLE_NORMAL; + + if (style->font_size.size == CSS_FONT_SIZE_LENGTH) + size = style->font_size.value.length.value * PANGO_SCALE; + + switch (style->font_weight) { + case CSS_FONT_WEIGHT_NORMAL: + weight = PANGO_WEIGHT_NORMAL; break; + case CSS_FONT_WEIGHT_BOLD: + weight = PANGO_WEIGHT_BOLD; break; + case CSS_FONT_WEIGHT_100: weight = 100; break; + case CSS_FONT_WEIGHT_200: weight = 200; break; + case CSS_FONT_WEIGHT_300: weight = 300; break; + case CSS_FONT_WEIGHT_400: weight = 400; break; + case CSS_FONT_WEIGHT_500: weight = 500; break; + case CSS_FONT_WEIGHT_600: weight = 600; break; + case CSS_FONT_WEIGHT_700: weight = 700; break; + case CSS_FONT_WEIGHT_800: weight = 800; break; + case CSS_FONT_WEIGHT_900: weight = 900; break; + default: break; + } + + switch (style->font_style) { + case CSS_FONT_STYLE_ITALIC: styl = PANGO_STYLE_ITALIC; break; + case CSS_FONT_STYLE_OBLIQUE: styl = PANGO_STYLE_OBLIQUE; break; + default: break; + } + + fontdesc = pango_font_description_new(); + pango_font_description_set_size(fontdesc, size); + pango_font_description_set_family_static(fontdesc, "Sans"); + pango_font_description_set_weight(fontdesc, weight); + pango_font_description_set_style(fontdesc, styl); + + data = malloc(sizeof *data); + assert(data); + + data->id = fontdesc; + data->size = size; + data->space_width = font_width(data, " ", 1); + + return data; +} + + +void font_free_set(struct font_set *set) +{ +} + + +unsigned long font_width(struct font_data *font, const char *text, + unsigned int length) +{ + int width; + PangoContext *context; + PangoLayout *layout; + + assert(font && text); + + if (length == 0) + return 0; + + context = gdk_pango_context_get(); + layout = pango_layout_new(context); + pango_layout_set_font_description(layout, font->id); + pango_layout_set_text(layout, text, length); + + pango_layout_get_pixel_size(layout, &width, 0); + + g_object_unref(layout); + g_object_unref(context); + + return width; +} + + +void font_position_in_string(const char *text, struct font_data *font, + unsigned int length, unsigned long x, int *char_offset, + int *pixel_offset) +{ + int index; + PangoContext *context; + PangoLayout *layout; + PangoRectangle pos; + + assert(font && text); + + context = gdk_pango_context_get(); + layout = pango_layout_new(context); + pango_layout_set_font_description(layout, font->id); + pango_layout_set_text(layout, text, length); + + pango_layout_xy_to_index(layout, x * PANGO_SCALE, 0, &index, 0); + pango_layout_index_to_pos(layout, index, &pos); + + g_object_unref(layout); + g_object_unref(context); + + *char_offset = index; + *pixel_offset = PANGO_PIXELS(pos.x); +} + + +char *font_split(struct font_data *font, const char *text, unsigned int length, + unsigned int width, unsigned int *used_width) +{ + int index = length; + int x_pos; + PangoContext *context; + PangoLayout *layout; + PangoLayoutLine *line; + + assert(font && text); + + context = gdk_pango_context_get(); + layout = pango_layout_new(context); + pango_layout_set_font_description(layout, font->id); + pango_layout_set_text(layout, text, length); + + pango_layout_set_width(layout, width * PANGO_SCALE); + pango_layout_set_wrap(layout, PANGO_WRAP_WORD); + line = pango_layout_get_line(layout, 1); + if (line) + index = line->start_index - 1; + pango_layout_line_index_to_x(pango_layout_get_line(layout, 0), + index, 0, &x_pos); + + g_object_unref(layout); + g_object_unref(context); + + *used_width = PANGO_PIXELS(x_pos); + return text + index; +} diff --git a/gtk/gtk_gui.c b/gtk/gtk_gui.c new file mode 100644 index 000000000..b0109ed5a --- /dev/null +++ b/gtk/gtk_gui.c @@ -0,0 +1,133 @@ +/* + * This file is part of NetSurf, http://netsurf.sourceforge.net/ + * Licensed under the GNU General Public License, + * http://www.opensource.org/licenses/gpl-license + * Copyright 2004 James Bursa + */ + +#include +#include +#include +#include +#include +#include +#include "netsurf/content/content.h" +#include "netsurf/desktop/browser.h" +#include "netsurf/desktop/netsurf.h" +#include "netsurf/render/box.h" +#include "netsurf/render/form.h" +#include "netsurf/utils/messages.h" +#include "netsurf/utils/utils.h" + + +static bool gui_start = true; +bool gui_in_multitask = false; + + +void gui_init(int argc, char** argv) +{ + gtk_init(&argc, &argv); + messages_load("messages"); +} + + +void gui_poll(bool active) +{ + if (gui_start) { + browser_window_create("", 0); + gui_start = false; + } + + /*netsurf_quit =*/ gtk_main_iteration_do(!active); +} + + +void gui_multitask(void) +{ + gui_in_multitask = true; + while (gtk_events_pending()) + /*netsurf_quit =*/ gtk_main_iteration(); + gui_in_multitask = false; +} + + +void gui_quit(void) +{ +} + + + + +gui_window *gui_create_download_window(struct content *content) +{ + return 0; +} + + +void gui_download_window_update_status(gui_window *g) +{ +} + + +void gui_download_window_done(gui_window *g) +{ +} + + +void gui_download_window_error(gui_window *g, const char *error) +{ +} + + +void gui_gadget_combo(struct browser_window* bw, struct form_control* g, + unsigned long mx, unsigned long my) +{ +} + + +void gui_launch_url(const char *url) +{ +} + + +void warn_user(const char *warning, const char *detail) +{ +} + + + + + +void html_add_instance(struct content *c, struct browser_window *bw, + struct content *page, struct box *box, + struct object_params *params, void **state) {} +void html_reshape_instance(struct content *c, struct browser_window *bw, + struct content *page, struct box *box, + struct object_params *params, void **state) {} +void html_remove_instance(struct content *c, struct browser_window *bw, + struct content *page, struct box *box, + struct object_params *params, void **state) {} + + +void die(const char * const error) +{ + fprintf(stderr, error); + exit(EXIT_FAILURE); +} + + +struct history *history_create(void) { return 0; } +void history_add(struct history *history, struct content *content) {} +void history_update(struct history *history, struct content *content) {} +void history_destroy(struct history *history) {} +void history_back(struct browser_window *bw, struct history *history) {} +void history_forward(struct browser_window *bw, struct history *history) {} + +struct content *about_create(const char *url, + void (*callback)(content_msg msg, struct content *c, void *p1, + void *p2, const char *error), + void *p1, void *p2, unsigned long width, unsigned long height) +{ return 0; } + +void gui_401login_open(struct browser_window *bw, struct content *c, + char *realm) {} diff --git a/gtk/gtk_window.c b/gtk/gtk_window.c new file mode 100644 index 000000000..461849d6f --- /dev/null +++ b/gtk/gtk_window.c @@ -0,0 +1,401 @@ +/* + * This file is part of NetSurf, http://netsurf.sourceforge.net/ + * Licensed under the GNU General Public License, + * http://www.opensource.org/licenses/gpl-license + * Copyright 2004 James Bursa + */ + +#include +#include +#include +#include +#include +#include +#include "netsurf/content/content.h" +#include "netsurf/desktop/browser.h" +#include "netsurf/desktop/netsurf.h" +#include "netsurf/render/box.h" +#include "netsurf/render/form.h" +#include "netsurf/utils/messages.h" +#include "netsurf/utils/utils.h" + + +extern bool gui_in_multitask; + + +struct gui_window { + GtkWidget *window; + GtkWidget *url_bar; + GtkWidget *drawing_area; + GtkWidget *status_bar; + int old_width; + struct browser_window *bw; +}; +static GtkWidget *current_widget; +static GdkDrawable *current_drawable; +static GdkGC *current_gc; + + +static gboolean gui_window_expose_event(GtkWidget *widget, + GdkEventExpose *event, gpointer data); +static gboolean gui_window_url_key_press_event(GtkWidget *widget, + GdkEventKey *event, gpointer data); +static gboolean gui_window_configure_event(GtkWidget *widget, + GdkEventConfigure *event, gpointer data); +static void html_redraw_box(struct content *content, struct box *box, + int x, int y); + + +gui_window *gui_create_browser_window(struct browser_window *bw, + struct browser_window *clone) +{ + gui_window *g; + GtkWidget *window; + GtkWidget *vbox; + GtkWidget *toolbar; + GtkToolItem *back_button, *forward_button, *stop_button, *reload_button; + GtkToolItem *url_item; + GtkWidget *url_bar; + GtkWidget *scrolled; + GtkWidget *drawing_area; + GtkWidget *status_bar; + + g = malloc(sizeof *g); + if (!g) { + warn_user("NoMemory", 0); + return 0; + } + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_widget_set_size_request(GTK_WIDGET(window), 600, 600); + gtk_window_set_title(GTK_WINDOW(window), "NetSurf"); + + vbox = gtk_vbox_new(false, 0); + gtk_container_add(GTK_CONTAINER(window), vbox); + gtk_widget_show(vbox); + + toolbar = gtk_toolbar_new(); + gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, TRUE, 0); + gtk_widget_show(toolbar); + + back_button = gtk_tool_button_new_from_stock(GTK_STOCK_GO_BACK); + gtk_toolbar_insert(GTK_TOOLBAR(toolbar), back_button, -1); + gtk_widget_show(GTK_WIDGET(back_button)); + + forward_button = gtk_tool_button_new_from_stock(GTK_STOCK_GO_FORWARD); + gtk_toolbar_insert(GTK_TOOLBAR(toolbar), forward_button, -1); + gtk_widget_show(GTK_WIDGET(forward_button)); + + stop_button = gtk_tool_button_new_from_stock(GTK_STOCK_STOP); + gtk_toolbar_insert(GTK_TOOLBAR(toolbar), stop_button, -1); + gtk_widget_show(GTK_WIDGET(stop_button)); + + reload_button = gtk_tool_button_new_from_stock(GTK_STOCK_REFRESH); + gtk_toolbar_insert(GTK_TOOLBAR(toolbar), reload_button, -1); + gtk_widget_show(GTK_WIDGET(reload_button)); + + url_item = gtk_tool_item_new(); + gtk_tool_item_set_expand(url_item, TRUE); + gtk_toolbar_insert(GTK_TOOLBAR(toolbar), url_item, -1); + gtk_widget_show(GTK_WIDGET(url_item)); + + url_bar = gtk_entry_new(); + gtk_container_add(GTK_CONTAINER(url_item), url_bar); + gtk_widget_show(url_bar); + g_signal_connect(G_OBJECT(url_bar), "key_press_event", + G_CALLBACK(gui_window_url_key_press_event), g); + + scrolled = gtk_scrolled_window_new(0, 0); + gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0); + gtk_widget_show(scrolled); + + drawing_area = gtk_drawing_area_new(); + gtk_widget_modify_bg(drawing_area, GTK_STATE_NORMAL, + &((GdkColor) { 0, 0xffff, 0xffff, 0xffff })); + gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled), + drawing_area); + gtk_widget_show(drawing_area); + status_bar = gtk_statusbar_new(); + gtk_box_pack_start(GTK_BOX(vbox), status_bar, FALSE, TRUE, 0); + gtk_widget_show(status_bar); + + gtk_widget_show(window); + + g->window = window; + g->url_bar = url_bar; + g->drawing_area = drawing_area; + g->status_bar = status_bar; + g->old_width = drawing_area->allocation.width; + g->bw = bw; + + g_signal_connect(G_OBJECT(drawing_area), "expose_event", + G_CALLBACK(gui_window_expose_event), g); + g_signal_connect(G_OBJECT(drawing_area), "configure_event", + G_CALLBACK(gui_window_configure_event), g); + + return g; +} + + +gboolean gui_window_expose_event(GtkWidget *widget, + GdkEventExpose *event, gpointer data) +{ + gui_window *g = data; + struct content *c = g->bw->current_content; + + if (!c) + return FALSE; + + current_widget = widget; + current_drawable = widget->window; + current_gc = gdk_gc_new(current_drawable); + + content_redraw(c, 0, 0, + widget->allocation.width, + widget->allocation.height, + event->area.x, + event->area.y, + event->area.x + event->area.width, + event->area.y + event->area.height, + 1.0); + + g_object_unref(current_gc); + + return FALSE; +} + + +gboolean gui_window_url_key_press_event(GtkWidget *widget, + GdkEventKey *event, gpointer data) +{ + gui_window *g = data; + + if (event->keyval != GDK_Return) + return FALSE; + + browser_window_go(g->bw, gtk_entry_get_text(GTK_ENTRY(g->url_bar))); + + return TRUE; +} + + +gboolean gui_window_configure_event(GtkWidget *widget, + GdkEventConfigure *event, gpointer data) +{ + gui_window *g = data; + + if (gui_in_multitask) + return FALSE; + + if (!g->bw->current_content) + return FALSE; + if (g->bw->current_content->status != CONTENT_STATUS_READY && + g->bw->current_content->status != CONTENT_STATUS_DONE) + return FALSE; + + g->old_width = event->width; +/* content_reformat(g->bw->current_content, event->width, event->height); */ + + return FALSE; +} + + +void gui_window_destroy(gui_window* g) +{ +} + + +void gui_window_redraw(gui_window* g, unsigned long x0, unsigned long y0, + unsigned long x1, unsigned long y1) +{ +} + + +void gui_window_redraw_window(gui_window* g) +{ + gtk_widget_queue_draw(g->drawing_area); +} + + +void gui_window_update_box(gui_window *g, const union content_msg_data *data) +{ +} + + +void gui_window_set_scroll(gui_window* g, unsigned long sx, unsigned long sy) +{ +} + + +unsigned long gui_window_get_width(gui_window* g) +{ + return g->drawing_area->allocation.width; +} + + +void gui_window_set_extent(gui_window* g, unsigned long width, + unsigned long height) +{ + gtk_widget_set_size_request(g->drawing_area, width, height); +} + + +void gui_window_set_status(gui_window *g, const char *text) +{ + guint context_id; + + gtk_statusbar_pop(GTK_STATUSBAR(g->status_bar), 0); + context_id = gtk_statusbar_get_context_id( + GTK_STATUSBAR(g->status_bar), text); + gtk_statusbar_push(GTK_STATUSBAR(g->status_bar), context_id, text); +} + + +void gui_window_set_pointer(gui_pointer_shape shape) +{ +} + + +void gui_window_set_title(gui_window *g, char *title) +{ + gtk_window_set_title(GTK_WINDOW(g->window), title); +} + + +void gui_window_set_url(gui_window *g, char *url) +{ + gtk_entry_set_text(GTK_ENTRY(g->url_bar), url); +} + + +void gui_window_clone_options(struct browser_window *new_bw, + struct browser_window *old_bw) +{ +} + + +void gui_window_default_options(struct browser_window *bw) +{ +} + + +void gui_window_start_throbber(gui_window* g) +{ +} + + +void gui_window_stop_throbber(gui_window* g) +{ +} + + +void gui_window_place_caret(gui_window *g, int x, int y, int height) +{ +} + + +void html_redraw(struct content *c, int x, int y, + int width, int height, + int clip_x0, int clip_y0, int clip_x1, int clip_y1, + float scale) +{ + html_redraw_box(c, c->data.html.layout->children, x, y); +} + + +void html_redraw_box(struct content *content, struct box *box, + int x, int y) +{ + struct box *c; + int width, height; + int padding_left, padding_top; + int padding_width, padding_height; + int x0, y0, x1, y1; + + x += box->x; + y += box->y; + width = box->width; + height = box->height; + padding_left = box->padding[LEFT]; + padding_top = box->padding[TOP]; + padding_width = (box->padding[LEFT] + box->width + + box->padding[RIGHT]); + padding_height = (box->padding[TOP] + box->height + + box->padding[BOTTOM]); + + x0 = x; + y1 = y - 1; + x1 = x0 + padding_width - 1; + y0 = y1 - padding_height + 1; + + /* if visibility is hidden render children only */ + if (box->style && box->style->visibility == CSS_VISIBILITY_HIDDEN) { + for (c = box->children; c; c = c->next) + html_redraw_box(content, c, x, y); + return; + } + + /* background colour */ + if (box->style != 0 && box->style->background_color != TRANSPARENT) { + int r, g, b; + GdkColor colour; + + r = box->style->background_color & 0xff; + g = (box->style->background_color & 0xff00) >> 8; + b = (box->style->background_color & 0xff0000) >> 16; + + colour.red = r | (r << 8); + colour.green = g | (g << 8); + colour.blue = b | (b << 8); + colour.pixel = (r << 16) | (g << 8) | b; + + gdk_color_alloc(gtk_widget_get_colormap(current_widget), + &colour); + gdk_gc_set_foreground(current_gc, &colour); + gdk_draw_rectangle(current_drawable, current_gc, + TRUE, x, y, padding_width, padding_height); + } + +/* gdk_draw_rectangle(current_drawable, current_gc, */ +/* FALSE, x, y, padding_width, padding_height); */ + + if (box->object) { + content_redraw(box->object, x + padding_left, y - padding_top, + width, height, x0, y0, x1, y1, 1.0); + + } else if (box->gadget && box->gadget->type == GADGET_CHECKBOX) { + + } else if (box->gadget && box->gadget->type == GADGET_RADIO) { + + } else if (box->gadget && box->gadget->type == GADGET_FILE) { + + } else if (box->text && box->font) { + PangoContext *context; + PangoLayout *layout; + GdkColor colour = { 0, + ((box->style->color & 0xff) << 8) | + (box->style->color & 0xff), + (box->style->color & 0xff00) | + (box->style->color & 0xff00 >> 8), + ((box->style->color & 0xff0000) >> 8) | + (box->style->color & 0xff0000 >> 16) }; + + context = gtk_widget_get_pango_context(current_widget); + layout = pango_layout_new(context); + pango_layout_set_font_description(layout, box->font->id); + pango_layout_set_text(layout, box->text, box->length); + + gdk_draw_layout_with_colors(current_drawable, current_gc, + x, y, layout, &colour, 0); + + g_object_unref(layout); + + } else { + for (c = box->children; c; c = c->next) + if (c->type != BOX_FLOAT_LEFT && c->type != BOX_FLOAT_RIGHT) + html_redraw_box(content, c, x, y); + + for (c = box->float_children; c; c = c->next_float) + html_redraw_box(content, c, x, y); + } +} diff --git a/makefile b/makefile index 100174d36..a69fb77b5 100644 --- a/makefile +++ b/makefile @@ -46,8 +46,8 @@ OBJECTS_DEBUGRO += draw.o filetype.o font.o \ OBJECTS_GTK = $(OBJECTS_COMMON) OBJECTS_GTK += filetyped.o # debug/ -OBJECTS_GTK += browser.o netsurf.o # desktop/ -OBJECTS_GTK += font_pango.o gtk_gui.o # gtk/ +OBJECTS_GTK += browser.o netsurf.o version.o # desktop/ +OBJECTS_GTK += font_pango.o gtk_gui.o gtk_window.o # gtk/ OBJDIR_RISCOS = $(shell $(CC) -dumpmachine) -- cgit v1.2.3