📄 gui.c
字号:
/******************************************************************************* * * gui.c * * Cheetah Web Browser * Copyright (C) 2001 Garett Spencley, Felipe Bergo * * This program 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; either version 2, or (at your option) * any later version. * * This program 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, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * *******************************************************************************/#include <stdlib.h>#include <stdio.h>#include <string.h>#include <unistd.h>#include "../config.h"#include <pthread.h>#include "uri.h"#include "http.h"#include "gui.h"#include "error.h"#include "cheetah.h"#include "history.h"#include "file.h"#include "htmlparser.h"#include "debug.h"#include "dw_gtk_scrolled_window.h"#include "icons.h"#include "menu.h"#include "progress.h"#include "spinner.h"static CheetahWindow **window_list = NULL;static int num_windows = 0;void cheetah_window_add_to_list(CheetahWindow *cw);void cheetah_load_uri_cb(GtkWidget *widget, CheetahWindow *cw);void *cheetah_load_uri_thread(void *p);GtkWidget *create_window(int x, int y);GtkWidget *create_toolbar(CheetahWindow *cw);GtkWidget *create_menubar(CheetahWindow *cw);GtkWidget *create_location_box(void);/* * close_all_window() and close_window() * * These routines were pretty much taken directly from dillo * http://dillo.sourceforge.net */void close_all_windows(){ CheetahWindow **cws; gint i, n_cw; debug_print("Dave? What are you doing?"); n_cw = num_windows; cws = (CheetahWindow **)malloc(sizeof(CheetahWindow *) * n_cw); /* we copy into a new list because destroying the main window can * modify the browser_window array. */ for (i = 0; i < n_cw; i++) cws[i] = window_list[i]; for (i = 0; i < n_cw; i++) gtk_widget_destroy(cws[i]->window); free(cws);}static gboolean close_window(GtkWidget *widget, CheetahWindow *cw){ int i; for(i = 0; i < num_windows; i++) { if(window_list[i] == cw) { window_list[i] = window_list[--num_windows]; break; } } if(num_windows == 0) cheetah_quit(); return FALSE;}void cheetah_close_window(CheetahWindow *cw){ if(cw) close_window(NULL, cw);}/* * cheetah_window_add_to_list() - add a new window to the list */void cheetah_window_add_to_list(CheetahWindow *cw){ if(!window_list) { window_list = (CheetahWindow **)malloc(sizeof(*cw)); num_windows = 0; } else window_list = (CheetahWindow **)realloc(window_list, sizeof(*cw) * num_windows + 1); window_list[num_windows++] = cw;}/* * create_cheetah_gui() - creates a cheetah browser gui */void load_cheetah_page(GtkWidget *w, CheetahWindow *cw){ cheetah_load_uri(cw, "http://cheetah.sourceforge.net"); }CheetahWindow *create_cheetah_gui(){ CheetahWindow *result; GtkWidget *vbox; GtkWidget *action_handle_box; GtkWidget *action_box; GtkWidget *status_box; GtkWidget *menu_handle; result = (CheetahWindow *)malloc(sizeof(CheetahWindow)); if(!result) return NULL; result->req_stop = 0; /* Add window to list */ cheetah_window_add_to_list(result); /* Create the gtk window */ result->window = create_window(800, 600); gtk_widget_show(result->window); gtk_signal_connect(GTK_OBJECT(result->window), "destroy", GTK_SIGNAL_FUNC(close_window), result); /* Vertical box for all the widgets */ vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(result->window), vbox); gtk_widget_show(vbox); /* Menu bar */ menu_handle = gtk_handle_box_new(); gtk_box_pack_start(GTK_BOX(vbox), menu_handle, FALSE, TRUE, 0); gtk_widget_show(menu_handle); result->menubar = create_menubar(result); gtk_container_add(GTK_CONTAINER(menu_handle), result->menubar); gtk_widget_show(result->menubar); /* Tool bar, location box and spinner ("action bar") */ action_handle_box = gtk_handle_box_new(); gtk_box_pack_start(GTK_BOX(vbox), action_handle_box, FALSE, TRUE, 0); gtk_widget_show(action_handle_box); action_box = gtk_hbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(action_handle_box), action_box); gtk_container_set_border_width(GTK_CONTAINER(action_box),4); gtk_widget_show(action_box); result->toolbar = create_toolbar(result); gtk_box_pack_start(GTK_BOX(action_box), result->toolbar, FALSE, TRUE, 0); gtk_widget_show(result->toolbar); result->location_label = gtk_label_new("Location: "); gtk_box_pack_start(GTK_BOX(action_box), result->location_label, FALSE, TRUE, 0); gtk_widget_show(result->location_label); result->location_box = create_location_box(); gtk_box_pack_start(GTK_BOX(action_box), result->location_box, FALSE, TRUE, 0); gtk_signal_connect(GTK_OBJECT(GTK_COMBO(result->location_box)->entry), "activate", GTK_SIGNAL_FUNC(cheetah_load_uri_cb), result); gtk_widget_show(result->location_box); /* Spinner */ result->spinner = create_spinner(result, action_box); /* Document window */ result->docwin = a_Dw_gtk_scrolled_window_new(); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(result->docwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); gtk_box_pack_start(GTK_BOX(vbox), result->docwin, TRUE, TRUE, 0); gtk_widget_show(result->docwin); /* Status bar */ status_box = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), status_box, FALSE, TRUE, 0); gtk_widget_show(status_box); result->status_bar = gtk_statusbar_new(); gtk_box_pack_start(GTK_BOX(status_box), result->status_bar, TRUE, TRUE, 2); gtk_widget_show(result->status_bar); /* Progress bar */ result->progress = gtk_progress_bar_new(); gtk_box_pack_end(GTK_BOX(status_box), result->progress, FALSE, TRUE, 0); gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(result->progress), GTK_PROGRESS_LEFT_TO_RIGHT); gtk_progress_bar_set_bar_style(GTK_PROGRESS_BAR(result->progress), GTK_PROGRESS_CONTINUOUS); gtk_widget_show(result->progress); /* Set default cursor */ cheetah_window_set_cursor(result, GDK_LEFT_PTR); return result;}/* * cheetah_window_new() - creates a new cheetah browser window */CheetahWindow *cheetah_window_new(){ CheetahWindow *result; result = create_cheetah_gui(); if(!result) return NULL; result->progress_timer = 0; result->spinner_timer = 0; //result->history = NULL; return result;}/* * create_gtk_window() - creates a gtk window */GtkWidget *create_window(int x, int y){ GtkWidget *result; result = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_widget_set_usize(result, x, y); gtk_window_set_policy(GTK_WINDOW(result), TRUE, TRUE, TRUE); return result;}/* * set_window_title() - sets the window title */void set_window_title(CheetahWindow *cw, const char *title){ if(!cw || !title) return; gtk_window_set_title(GTK_WINDOW(cw->window), title);}/* * toolbar_add_item() * * appends an item to a toolbar. */static __inline void toolbar_add_xpm(GtkWidget *toolbar, gchar **xpm, char *text, GtkSignalFunc callback, GtkWidget *window, gpointer cbdata){ GdkPixmap *icon; GtkWidget *iconw; GdkBitmap *mask; icon = gdk_pixmap_create_from_xpm_d(window->window, &mask, &window->style->white, xpm); iconw = gtk_pixmap_new(icon, mask); gtk_toolbar_append_item(GTK_TOOLBAR(toolbar), text, text, "Private", iconw, callback, cbdata); return;}/* * create_toolbar() * * creates the toolbar. * Returns pointer to a handlebox containing the * toolbar. */GtkWidget *create_toolbar(CheetahWindow *cw){ GtkWidget *toolbar; toolbar = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_BOTH); gtk_container_set_border_width(GTK_CONTAINER(toolbar), 2); gtk_toolbar_set_button_relief(GTK_TOOLBAR(toolbar), GTK_RELIEF_NONE); gtk_toolbar_set_space_size(GTK_TOOLBAR(toolbar), 5); toolbar_add_xpm(toolbar, (gchar **)back_xpm, "Back", NULL, cw->window, 0); gtk_toolbar_append_space(GTK_TOOLBAR(toolbar)); toolbar_add_xpm(toolbar, (gchar **)forward_xpm, "Forward", NULL, cw->window, 0); gtk_toolbar_append_space(GTK_TOOLBAR(toolbar)); toolbar_add_xpm(toolbar, (gchar **)reload_xpm, "Reload", NULL, cw->window, 0); gtk_toolbar_append_space(GTK_TOOLBAR(toolbar)); toolbar_add_xpm(toolbar, (gchar **)stop_xpm, "Stop", GTK_SIGNAL_FUNC(cheetah_stop_cb), cw->window, (gpointer) cw); gtk_toolbar_append_space(GTK_TOOLBAR(toolbar)); gtk_toolbar_append_space(GTK_TOOLBAR(toolbar)); gtk_widget_show(toolbar); return toolbar;}/* * create_location_box() - create the location box */GtkWidget *create_location_box(void){ GtkWidget *combo; combo = gtk_combo_new(); gtk_widget_set_usize(combo, 400, 25); gtk_combo_disable_activate(GTK_COMBO(combo)); return combo;}/* * cheetah_open_uri() - opens a uri */static __inline void update_history(CheetahWindow *cw, const char *uri){ /* GList *list = NULL; if(!uri) return; list = g_list_prepend(list, item); gtk_combo_set_popdown_strings(GTK_COMBO(cw->location_box), list); g_list_free(list); */}/* * cheetah_load_uri_cb() - loads the uri from the location box */void cheetah_load_uri_cb(GtkWidget *widget, CheetahWindow *cw){ char *text; text = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(cw->location_box)->entry)); if(!text || strcmp(text, "") == 0) return; debug_print("%s it is!", text); if(cheetah_load_uri(cw, text) == 0) update_history(cw, text);}/* * cheetah_thread_load_uri() - start routine for uri loading thread */void *cheetah_load_uri_thread(void *p){ InterThread *itd; itd = (InterThread *)p;#ifdef HAVE_PTHREADS_CANCEL_FLAGS /* FreeBSD compatibility */ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,0); pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,0);#endif if(itd->uri->protocol == HTTP) itd->source = http_get_file(itd->uri, &(itd->status)); else if(itd->uri->protocol == L_FILE) itd->source = load_file(itd->uri->abs_path); itd->done = 1; pthread_exit(NULL); return NULL;}/* * cheetah_load_uri() - opens a uri. */int cheetah_load_uri(CheetahWindow *cw, const char *uri_string){ uri_t *uri; char *source = NULL; pthread_t child; static InterThread itd; int last_seq = 0; if(!uri_string) return -1; uri = parse_uri(uri_string); if(!uri) return -1; gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(cw->location_box)->entry), uri_string); /* Thread stuff */ itd.uri = uri; itd.source = 0; itd.done = 0; itd.status.seq = 0; itd.status.pop = -1; cw->req_stop = 0; /* cancel pending stop requests from the GUI */ pthread_create(&child, NULL, cheetah_load_uri_thread, (void *)(&itd)); /* Start the progress stuff */ progress_start(cw); /* Do stuff while thread is working */ while(!itd.done) { if(cw->req_stop) { cw->req_stop = 0; pthread_cancel(child); itd.source = 0; strcpy(itd.status.text, "Interrupted."); itd.status.seq++; http_close(); break; } if(itd.status.seq > last_seq) { if(strlen(itd.status.text)) { status_print(cw, "%s", itd.status.text); last_seq = itd.status.seq; if(itd.status.pop == itd.status.seq) create_error_dialog(itd.status.text); } } if (gtk_events_pending()) gtk_main_iteration(); else usleep(50000); } pthread_join(child, NULL); if(itd.status.seq > last_seq) { status_print(cw,"%s",itd.status.text); last_seq=itd.status.seq; if(itd.status.pop == itd.status.seq) create_error_dialog(itd.status.text); } /* Render the document */ source = itd.source; if(!source) { uri_free(uri); progress_stop(cw); return -1; } html_render_document(cw, uri, source); /* Cleanup */ free(source); uri_free(uri); /* Reset progress stuff */ progress_stop(cw); status_print(cw, "Done."); return 0;}/* * cheetah_stop_cb() - stops the current page from loading */void cheetah_stop_cb(GtkWidget *w, gpointer data){ CheetahWindow *me; me = (CheetahWindow *)data; me->req_stop = 1;}/* * cheetah_set_window_cursor() - set the window cursor */void cheetah_window_set_cursor(CheetahWindow *cw, GdkCursorType type){ GdkCursor *cursor; cursor = gdk_cursor_new(type); gdk_window_set_cursor(cw->docwin->window, cursor); gdk_cursor_destroy(cursor);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -