Merge branch 'vince/themectomy'

Remove broken GTK theme code
This commit is contained in:
Vincent Sanders 2016-03-10 13:30:44 +00:00
commit 875fc5381e
49 changed files with 257 additions and 2202 deletions

View File

@ -179,7 +179,7 @@ endif
S_GTK := font_pango.c bitmap.c gui.c schedule.c plotters.c \
treeview.c scaffolding.c gdk.c completion.c login.c throbber.c \
selection.c history.c window.c fetch.c download.c menu.c \
print.c search.c tabs.c theme.c theme_container.c toolbar.c gettext.c \
print.c search.c tabs.c toolbar.c gettext.c \
compat.c cookies.c hotlist.c viewdata.c viewsource.c \
preferences.c about.c ssl_cert.c resources.c
@ -195,7 +195,7 @@ SOURCES = $(S_COMMON) $(S_IMAGE) $(S_BROWSER) $(S_RESOURCE) $(S_GTK)
# ----------------------------------------------------------------------------
GTK_RESOURCES_LIST := \
languages themelist SearchEngines toolbarIndices ca-bundle.txt \
languages SearchEngines toolbarIndices ca-bundle.txt \
default.css adblock.css quirks.css internal.css \
credits.html licence.html welcome.html maps.html Messages \
default.ico favicon.png netsurf.png netsurf.xpm netsurf-16x16.xpm \
@ -215,7 +215,6 @@ install-gtk:
$(Q)install -m 0644 gtk/res/icons/*.png $(DESTDIR)$(NETSURF_GTK_RESOURCES)/icons
$(Q)mkdir -p $(DESTDIR)$(NETSURF_GTK_RESOURCES)throbber
$(Q)install -m 0644 gtk/res/throbber/*.png $(DESTDIR)$(NETSURF_GTK_RESOURCES)/throbber
$(Q)tar -c -h -C gtk/res -f - themes | tar -xv -C $(DESTDIR)$(NETSURF_GTK_RESOURCES) -f -
$(Q)tar -c -h -C gtk/res -f - $(GTK_TRANSLATIONS_HTML) | tar -xv -C $(DESTDIR)$(NETSURF_GTK_RESOURCES) -f -
$(Q)install -m 0644 $(GTK_RESOURCES_LIST) $(DESTDIR)$(NETSURF_GTK_RESOURCES)

View File

@ -73,13 +73,12 @@
bool nsgtk_complete = false;
char *toolbar_indices_file_location;
char *res_dir_location;
char *themelist_file_location;
char *nsgtk_config_home; /* exported global defined in gtk/gui.h */
GdkPixbuf *favicon_pixbuf; /** favicon default pixbuf */
GdkPixbuf *win_default_icon_pixbuf; /** default window icon pixbuf */
GdkPixbuf *arrow_down_pixbuf; /** arrow down pixbuf */
GtkBuilder *warning_builder;
@ -236,30 +235,6 @@ static nserror nsgtk_init(int argc, char** argv, char **respath)
nsurl *url;
nserror error;
/* find the theme list file */
themelist_file_location = filepath_find(respath, "themelist");
if ((themelist_file_location != NULL) &&
(strlen(themelist_file_location) < 10)) {
free(themelist_file_location);
themelist_file_location = NULL;
}
if (themelist_file_location == NULL) {
LOG("Unable to find themelist - disabling themes");
res_dir_location = NULL;
} else {
/* Obtain resources path location.
*
* Uses the directory the theme file was found in,
* @todo find and slaughter all references to this!
*/
res_dir_location = calloc(1, strlen(themelist_file_location) - 8);
memcpy(res_dir_location,
themelist_file_location,
strlen(themelist_file_location) - 9);
LOG("Using '%s' for resource path", res_dir_location);
}
error = nsgtk_builder_new_from_resname("warning", &warning_builder);
if (error != NSERROR_OK) {
LOG("Unable to initialise warning dialog");
@ -288,7 +263,15 @@ static nserror nsgtk_init(int argc, char** argv, char **respath)
error = nsgdk_pixbuf_new_from_resname("favicon.png", &favicon_pixbuf);
if (error != NSERROR_OK) {
favicon_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
false, 8, 16,16);
false, 8, 16, 16);
}
/* arrow down icon */
error = nsgdk_pixbuf_new_from_resname("arrow_down_8x32.png",
&arrow_down_pixbuf);
if (error != NSERROR_OK) {
arrow_down_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
false, 8, 8, 32);
}
/* Toolbar inicies file */

View File

@ -24,18 +24,15 @@ struct nsurl;
/** toolbar arrangement file path. */
extern char *toolbar_indices_file_location;
/** Resource directory path. */
extern char *res_dir_location;
/** Theme location. */
extern char *themelist_file_location;
/** Directory where all configuration files are held. */
extern char *nsgtk_config_home;
/** favicon default pixbuf */
extern GdkPixbuf *favicon_pixbuf;
/** arrow down pixbuf */
extern GdkPixbuf *arrow_down_pixbuf;
/** resource search path vector */
extern char **respaths;

View File

@ -68,8 +68,5 @@ NSOPTION_STRING(hotlist_path, NULL)
/* Developer information viewer display method */
NSOPTION_INTEGER(developer_view, 0)
/* currently selected theme */
NSOPTION_INTEGER(current_theme, 0)
/* where tabs are positioned */
NSOPTION_INTEGER(position_tab, 0)

View File

@ -33,7 +33,6 @@
#include "gtk/window.h"
#include "gtk/gui.h"
#include "gtk/scaffolding.h"
#include "gtk/theme.h"
#include "gtk/resources.h"
#include "gtk/preferences.h"
@ -53,7 +52,6 @@ struct ppref {
GtkSpinButton *spinProxyPort;
/* dynamic list stores */
GtkListStore *themes;
GtkListStore *content_language;
GtkListStore *search_providers;
};
@ -165,9 +163,6 @@ G_MODULE_EXPORT void nsgtk_preferences_comboDefault_realize(GtkWidget *widget, s
G_MODULE_EXPORT void nsgtk_preferences_fontPreview_clicked(GtkButton *button, struct ppref *priv);
G_MODULE_EXPORT void nsgtk_preferences_comboboxLanguage_changed(GtkComboBox *combo, struct ppref *priv);
G_MODULE_EXPORT void nsgtk_preferences_comboboxLanguage_realize(GtkWidget *widget, struct ppref *priv);
G_MODULE_EXPORT void nsgtk_preferences_comboTheme_changed(GtkComboBox *combo, struct ppref *priv);
G_MODULE_EXPORT void nsgtk_preferences_comboTheme_realize(GtkWidget *widget, struct ppref *priv);
G_MODULE_EXPORT void nsgtk_preferences_buttonAddTheme_clicked(GtkButton *button, struct ppref *priv);
G_MODULE_EXPORT void nsgtk_preferences_checkShowSingleTab_toggled(GtkToggleButton *togglebutton, struct ppref *priv);
G_MODULE_EXPORT void nsgtk_preferences_checkShowSingleTab_realize(GtkWidget *widget, struct ppref *priv);
G_MODULE_EXPORT void nsgtk_preferences_comboTabPosition_changed(GtkComboBox *widget, struct ppref *priv);
@ -709,168 +704,6 @@ nsgtk_preferences_comboboxLanguage_realize(GtkWidget *widget,
/********* Apperance **********/
/* Themes */
/* select theme */
G_MODULE_EXPORT void
nsgtk_preferences_comboTheme_changed(GtkComboBox *combo, struct ppref *priv)
{
struct nsgtk_scaffolding *current;
int theme = 0;
gchar *name;
GtkTreeIter iter;
GtkTreeModel *model;
/* Obtain currently selected item from combo box.
* If nothing is selected, do nothing.
*/
if (gtk_combo_box_get_active_iter(combo, &iter)) {
/* get the row number for the config */
theme = gtk_combo_box_get_active(combo);
nsoption_set_int(current_theme, theme);
/* retrive the theme name if it is not the default */
if (theme != 0) {
/* Obtain data model from combo box. */
model = gtk_combo_box_get_model(combo);
/* Obtain string from model. */
gtk_tree_model_get(model, &iter, 0, &name, -1);
} else {
name = NULL;
}
nsgtk_theme_set_name(name);
if (name != NULL) {
g_free(name);
}
current = nsgtk_scaffolding_iterate(NULL);
while (current != NULL) {
nsgtk_theme_implement(current);
current = nsgtk_scaffolding_iterate(current);
}
}
}
G_MODULE_EXPORT void
nsgtk_preferences_comboTheme_realize(GtkWidget *widget, struct ppref *priv)
{
/* Fill theme list store */
FILE *fp;
GtkTreeIter iter;
char buf[50];
int combo_row_count = 0;
int selected_theme = 0;
if ((priv->themes != NULL) &&
(themelist_file_location != NULL) &&
((fp = fopen(themelist_file_location, "r")) != NULL)) {
gtk_list_store_clear(priv->themes);
LOG("Used %s for themelist", themelist_file_location);
while (fgets(buf, sizeof(buf), fp)) {
/* Ignore blank lines */
if (buf[0] == '\0')
continue;
/* Remove trailing \n */
buf[strlen(buf) - 1] = '\0';
gtk_list_store_append(priv->themes, &iter);
gtk_list_store_set(priv->themes, &iter, 0, buf, -1);
combo_row_count++;
}
fclose(fp);
} else {
LOG("Failed opening themes file");
}
/* get configured theme and sanity check value */
selected_theme = nsoption_int(current_theme);
if (selected_theme > combo_row_count) {
selected_theme = combo_row_count;
}
if (selected_theme < 0) {
selected_theme = 0;
}
gtk_combo_box_set_active(GTK_COMBO_BOX(widget), selected_theme);
}
/* add theme */
G_MODULE_EXPORT void
nsgtk_preferences_buttonAddTheme_clicked(GtkButton *button, struct ppref *priv)
{
char *filename, *directory;
size_t len;
GtkWidget *fc;
char *themesfolder;
gint res;
fc = gtk_file_chooser_dialog_new(messages_get("gtkAddThemeTitle"),
GTK_WINDOW(priv->dialog),
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
NSGTK_STOCK_OK,
GTK_RESPONSE_ACCEPT,
NSGTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL,
NULL);
len = SLEN("themes") + strlen(res_dir_location) + 1;
themesfolder = malloc(len);
snprintf(themesfolder, len, "%sthemes", res_dir_location);
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fc), themesfolder);
res = gtk_dialog_run(GTK_DIALOG(fc));
if (res == GTK_RESPONSE_ACCEPT) {
filename = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(fc));
if (filename != NULL) {
if (strcmp(filename, themesfolder) != 0) {
directory = strrchr(filename, '/');
*directory = '\0';
if (strcmp(filename, themesfolder) != 0) {
warn_user(messages_get(
"gtkThemeFolderInstructions"),
0);
if (filename != NULL)
g_free(filename);
} else {
directory++;
nsgtk_theme_add(directory);
}
} else {
g_free(filename);
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fc));
if (strcmp(filename, themesfolder) == 0) {
warn_user(messages_get("gtkThemeFolderSub"),
0);
} else {
directory = strrchr(filename, '/') + 1;
nsgtk_theme_add(directory);
}
}
g_free(filename);
}
}
free(themesfolder);
gtk_widget_destroy(fc);
}
/* Tabs */
/* always show tab bar */
@ -1174,7 +1007,6 @@ GtkWidget* nsgtk_preferences(struct browser_window *bw, GtkWindow *parent)
*/
#define GB(TYPE, NAME) GTK_##TYPE(gtk_builder_get_object(preferences_builder, #NAME))
priv->entryHomePageURL = GB(ENTRY, entryHomePageURL);
priv->themes = GB(LIST_STORE, liststore_themes);
priv->content_language = GB(LIST_STORE, liststore_content_language);
priv->search_providers = GB(LIST_STORE, liststore_search_provider);
priv->entryProxyHost = GB(ENTRY, entryProxyHost);
@ -1196,12 +1028,3 @@ GtkWidget* nsgtk_preferences(struct browser_window *bw, GtkWindow *parent)
return GTK_WIDGET(priv->dialog);
}
/* exported interface documented in gtk/preferences.h */
void nsgtk_preferences_theme_add(const char *themename)
{
struct ppref *priv = &ppref;
GtkTreeIter iter;
gtk_list_store_append(priv->themes, &iter);
gtk_list_store_set(priv->themes, &iter, 0, themename, -1 );
}

View File

@ -25,8 +25,4 @@
*/
GtkWidget* nsgtk_preferences(struct browser_window *bw, GtkWindow *parent);
/** Theme added
*/
void nsgtk_preferences_theme_add(const char *themename);
#endif

View File

@ -57,6 +57,7 @@
<file>quirks.css</file>
<file>netsurf.png</file>
<file>default.ico</file>
<file>arrow_down_8x32.png</file>
<file>icons/arrow-l.png</file>
<file>icons/content.png</file>
<file>icons/directory2.png</file>

View File

@ -416,79 +416,6 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkFrame" id="frame_appearance_theme">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="alignment4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="top_padding">6</property>
<property name="left_padding">12</property>
<property name="right_padding">12</property>
<child>
<object class="GtkHBox" id="themehbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">12</property>
<child>
<object class="GtkComboBox" id="comboTheme">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">liststore_themes</property>
<signal name="changed" handler="nsgtk_preferences_comboTheme_changed" swapped="no"/>
<signal name="realize" handler="nsgtk_preferences_comboTheme_realize" swapped="no"/>
<child>
<object class="GtkCellRendererText" id="cellrenderertext9"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="buttonAddTheme">
<property name="label" translatable="yes">preferencesThemesAdd</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="nsgtk_preferences_buttonAddTheme_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">preferencesThemes</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="padding">6</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame_appearance_tabs">
<property name="visible">True</property>
@ -3057,17 +2984,6 @@
</row>
</data>
</object>
<object class="GtkListStore" id="liststore_themes">
<columns>
<!-- column-name Theme -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0" translatable="yes">preferencesThemeTypeDefault</col>
</row>
</data>
</object>
<object class="GtkListStore" id="liststore_developer_view">
<columns>
<!-- column-name Type -->

View File

@ -515,83 +515,6 @@
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="spacing">6</property>
<child>
<object class="GtkFrame" id="frame_appearance_theme">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="alignment4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="top_padding">6</property>
<property name="left_padding">12</property>
<property name="right_padding">12</property>
<child>
<object class="GtkHBox" id="themehbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="spacing">12</property>
<child>
<object class="GtkComboBox" id="comboTheme">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="model">liststore_themes</property>
<signal name="changed" handler="nsgtk_preferences_comboTheme_changed" swapped="no"/>
<signal name="realize" handler="nsgtk_preferences_comboTheme_realize" swapped="no"/>
<child>
<object class="GtkCellRendererText" id="cellrenderertext9"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="buttonAddTheme">
<property name="label" translatable="yes">preferencesThemesAdd</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="nsgtk_preferences_buttonAddTheme_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">preferencesThemes</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="padding">6</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame_appearance_tabs">
<property name="visible">True</property>
@ -3111,17 +3034,6 @@
</row>
</data>
</object>
<object class="GtkListStore" id="liststore_themes">
<columns>
<!-- column-name Theme -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0" translatable="yes">preferencesThemeTypeDefault</col>
</row>
</data>
</object>
<object class="GtkListStore" id="liststore_toolbar_buttontype">
<columns>
<!-- column-name Type -->

View File

@ -1,2 +0,0 @@
gtk default theme
gtk+

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 915 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 697 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 906 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1,81 +0,0 @@
This file is part of NetSurf, http://www.netsurf-browser.org/
The images in this theme folder 'gtk+' are from the gtk stock image set
http://library.gnome.org/devel/gtk/unstable/gtk-Stock-Items.html
the image history.png is [for what it's worth!] Copyright 2009 Mark Benjamin
<netsurf-browser.org.MarkBenjamin@dfgh.net>
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/>.
*** Instructions for theming ***
to create a theme, make a folder, whose name is the name of the theme;
put in the folder, a set of png images for the toolbuttons;
the names of the images should be a subset of the list
back.png,
history.png,
forward.png,
stop.png,
reload.png,
home.png,
newwindow.png,
newtab.png,
openfile.png,
closetab.png,
closewindow.png,
savepage.png,
pdf.png,
plaintext.png,
drawfile.png,
postscript.png,
printpreview.png,
print.png,
quit.png,
cut.png,
copy.png,
paste.png,
delete.png,
selectall.png,
find.png,
preferences.png,
zoomplus.png,
zoomminus.png,
zoomnormal.png,
fullscreen.png,
viewsource.png,
downloads.png,
savewindowsize.png,
toggledebugging.png,
saveboxtree.png,
savedomtree.png,
localhistory.png,
globalhistory.png,
addbookmarks.png,
showbookmarks.png,
openlocation.png,
nexttab.png,
prevtab.png,
contents.png,
guide.png,
info.png,
about.png,
searchback.png,
searchforward.png,
searchclose.png
for local theming, the folder may be placed directly [as a subfolder] into the netsurf/gtk/res/themes folder; then 'add theme' from the preferences->advanced tab;
for downloadable themes, compile netsurf/utils/container.c according to the instructions in the header of that file; make a netsurf container of the folder, serve it as content-type "application/x-netsurf-theme"; browse to it in NetSurf, then NetSurf should automatically install it

Binary file not shown.

Before

Width:  |  Height:  |  Size: 736 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 736 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 612 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 893 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 818 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 967 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 717 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 960 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 941 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 962 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 993 B

View File

@ -95,6 +95,7 @@ static struct nsgtk_resource_s pixbuf_resource[] = {
RES_ENTRY("favicon.png"),
RES_ENTRY("netsurf.xpm"),
RES_ENTRY("menu_cursor.png"),
RES_ENTRY("arrow_down_8x32.png"),
RES_ENTRY("throbber/throbber0.png"),
RES_ENTRY("throbber/throbber1.png"),
RES_ENTRY("throbber/throbber2.png"),

View File

@ -67,7 +67,6 @@
#include "gtk/window.h"
#include "gtk/gdk.h"
#include "gtk/scaffolding.h"
#include "gtk/theme.h"
#include "gtk/tabs.h"
#include "gtk/schedule.h"
#include "gtk/viewdata.h"
@ -2290,8 +2289,7 @@ struct nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel)
gs->prev = NULL;
scaf_list = gs;
/* call functions that need access from the list */
nsgtk_theme_init();
/* set icon images */
nsgtk_theme_implement(gs);
/* set web search provider */

View File

@ -1,857 +0,0 @@
/*
* Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.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 <gtk/gtk.h>
#include <stdio.h>
#include <stdint.h>
#include <sys/stat.h>
#include <unistd.h>
#include "utils/config.h"
#include "utils/nsoption.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/utils.h"
#include "desktop/browser.h"
#include "desktop/theme.h"
#include "content/content.h"
#include "content/content_type.h"
#include "content/hlcache.h"
#include "gtk/compat.h"
#include "gtk/gui.h"
#include "gtk/scaffolding.h"
#include "gtk/menu.h"
#include "gtk/theme.h"
#include "gtk/theme_container.h"
#include "gtk/window.h"
#include "gtk/preferences.h"
enum image_sets {
IMAGE_SET_MAIN_MENU = 0,
IMAGE_SET_RCLICK_MENU,
IMAGE_SET_POPUP_MENU,
IMAGE_SET_BUTTONS,
IMAGE_SET_COUNT
};
struct nsgtk_theme_cache {
GdkPixbuf *image[PLACEHOLDER_BUTTON];
GdkPixbuf *searchimage[SEARCH_BUTTONS_COUNT];
/* apng throbber image */
};
static char *current_theme_name = NULL;
static struct nsgtk_theme_cache *theme_cache_menu = NULL;
static struct nsgtk_theme_cache *theme_cache_toolbar = NULL;
/**
* \param themename contains a name of theme to check whether it may
* properly be added to the list; alternatively NULL to check the integrity
* of the list
* \return true for themename may be added / every item in the list is
* a valid directory
*/
static bool nsgtk_theme_verify(const char *themename)
{
long filelength;
FILE *fp;
size_t val = SLEN("themelist") + strlen(res_dir_location) + 1;
char buf[50];
char themefile[val];
snprintf(themefile, val, "%s%s", res_dir_location, "themelist");
if (themename == NULL) {
char *filecontent, *testfile;
struct stat sta;
fp = fopen(themefile, "r+");
if (fp == NULL) {
warn_user(messages_get("gtkFileError"), themefile);
return true;
}
fseek(fp, 0L, SEEK_END);
filelength = ftell(fp);
filecontent = malloc(filelength +
SLEN("gtk default theme\n") + SLEN("\n")
+ 1);
if (filecontent == NULL) {
warn_user(messages_get("NoMemory"), 0);
fclose(fp);
return true;
}
strcpy(filecontent, "gtk default theme\n");
fseek(fp, 0L, SEEK_SET);
while (fgets(buf, sizeof(buf), fp) != NULL) {
/* iterate list */
buf[strlen(buf) - 1] = '\0';
/* "\n\0" -> "\0\0" */
testfile = malloc(strlen(res_dir_location) +
SLEN("themes/") + strlen(buf) + 1);
if (testfile == NULL) {
warn_user(messages_get("NoMemory"), 0);
free(filecontent);
fclose(fp);
return false;
}
sprintf(testfile, "%sthemes/%s", res_dir_location,
buf);
/* check every directory */
if (access(testfile, R_OK) == 0) {
if ((stat(testfile, &sta) == 0) &&
(S_ISDIR(sta.st_mode))) {
buf[strlen(buf)] = '\n';
/* "\0\0" -> "\n\0" */
strcat(filecontent, buf);
}
}
free(testfile);
}
fclose(fp);
fp = fopen(themefile, "w");
if (fp == NULL) {
warn_user(messages_get("gtkFileError"), themefile);
free(filecontent);
return true;
}
val = fwrite(filecontent, strlen(filecontent), 1, fp);
if (val == 0)
LOG("empty write themelist");
fclose(fp);
free(filecontent);
return true;
} else {
fp = fopen(themefile, "r");
if (fp == NULL) {
warn_user(messages_get("gtkFileError"), themefile);
return false;
}
while (fgets(buf, sizeof(buf), fp) != NULL) {
buf[strlen(buf) - 1] = '\0';
/* "\n\0" -> "\0\0" */
if (strcmp(buf, themename) == 0) {
fclose(fp);
return false;
}
}
fclose(fp);
return true;
}
}
/**
* called during gui init phase to retrieve theme name from file then
* implement
*/
void nsgtk_theme_init(void)
{
int theme;
struct nsgtk_scaffolding *list;
FILE *fp;
char buf[50];
int row_count = 0;
theme = nsoption_int(current_theme);
/* check if default theme is selected */
if (theme == 0) {
return;
}
nsgtk_theme_verify(NULL);
fp = fopen(themelist_file_location, "r");
if (fp == NULL)
return;
while (fgets(buf, sizeof(buf), fp) != NULL) {
if (buf[0] == '\0')
continue;
if (row_count++ == theme) {
if (current_theme_name != NULL) {
free(current_theme_name);
}
/* clear the '\n' ["\n\0"->"\0\0"] */
buf[strlen(buf) - 1] = '\0';
current_theme_name = strdup(buf);
break;
}
}
fclose(fp);
list = nsgtk_scaffolding_iterate(NULL);
while (list != NULL) {
nsgtk_theme_implement(list);
list = nsgtk_scaffolding_iterate(list);
}
}
/**
* return reference to static global current_theme_name; caller then has
* responsibility for global reference
*/
char *nsgtk_theme_name(void)
{
return current_theme_name;
}
/**
* set static global current_theme_name from param
*/
void nsgtk_theme_set_name(const char *name)
{
if ((name == NULL) && (current_theme_name == NULL)) {
return; /* setting it to the same thing */
} else if ((name == NULL) && (current_theme_name != NULL)) {
free(current_theme_name);
current_theme_name = NULL;
} else if ((name != NULL) && (current_theme_name == NULL)) {
current_theme_name = strdup(name);
nsgtk_theme_prepare();
} else if (strcmp(name, current_theme_name) != 0) {
/* disimilar new name */
free(current_theme_name);
current_theme_name = strdup(name);
nsgtk_theme_prepare();
}
}
/**
* adds a theme name to the list of themes
*/
void nsgtk_theme_add(const char *themename)
{
size_t len;
GtkWidget *notification, *label;
len = SLEN("themelist") + strlen(res_dir_location) + 1;
char themefile[len];
snprintf(themefile, len, "%s%s", res_dir_location, "themelist");
/* conduct verification here; no adding duplicates to list */
if (nsgtk_theme_verify(themename) == false) {
warn_user(messages_get("gtkThemeDup"), 0);
return;
}
FILE *fp = fopen(themefile, "a");
if (fp == NULL) {
warn_user(messages_get("gtkFileError"), themefile);
return;
}
fprintf(fp, "%s\n", themename);
fclose(fp);
/* notification that theme was added successfully */
notification = gtk_dialog_new_with_buttons(messages_get("gtkThemeAdd"),
NULL,
GTK_DIALOG_DESTROY_WITH_PARENT,
NSGTK_STOCK_OK, GTK_RESPONSE_NONE,
NULL, NULL);
if (notification == NULL) {
warn_user(messages_get("NoMemory"), 0);
return;
}
len = SLEN("\t\t\t\t\t\t") + strlen(messages_get("gtkThemeAdd")) + 1;
char labelcontent[len];
snprintf(labelcontent, len, "\t\t\t%s\t\t\t",
messages_get("gtkThemeAdd"));
label = gtk_label_new(labelcontent);
if (label == NULL) {
warn_user(messages_get("NoMemory"), 0);
return;
}
g_signal_connect_swapped(notification, "response",
G_CALLBACK(gtk_widget_destroy), notification);
gtk_container_add(GTK_CONTAINER(nsgtk_dialog_get_content_area(GTK_DIALOG(notification))), label);
gtk_widget_show_all(notification);
/* update combo */
nsgtk_preferences_theme_add(themename);
}
/**
* sets the images for a particular scaffolding according to the current theme
*/
void nsgtk_theme_implement(struct nsgtk_scaffolding *g)
{
struct nsgtk_theme *theme[IMAGE_SET_COUNT];
int i;
struct nsgtk_button_connect *button;
struct gtk_search *search;
for (i = 0; i <= IMAGE_SET_POPUP_MENU; i++)
theme[i] = nsgtk_theme_load(GTK_ICON_SIZE_MENU);
theme[IMAGE_SET_BUTTONS] =
nsgtk_theme_load(GTK_ICON_SIZE_LARGE_TOOLBAR);
for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) {
if ((i == URL_BAR_ITEM) || (i == THROBBER_ITEM) ||
(i == WEBSEARCH_ITEM))
continue;
button = nsgtk_scaffolding_button(g, i);
if (button == NULL)
continue;
/* gtk_image_menu_item_set_image accepts NULL image */
if ((button->main != NULL) &&
(theme[IMAGE_SET_MAIN_MENU] != NULL)) {
nsgtk_image_menu_item_set_image(GTK_WIDGET(button->main),
GTK_WIDGET(
theme[IMAGE_SET_MAIN_MENU]->
image[i]));
gtk_widget_show_all(GTK_WIDGET(button->main));
}
if ((button->rclick != NULL) &&
(theme[IMAGE_SET_RCLICK_MENU] != NULL)) {
nsgtk_image_menu_item_set_image(GTK_WIDGET(button->rclick),
GTK_WIDGET(
theme[IMAGE_SET_RCLICK_MENU]->
image[i]));
gtk_widget_show_all(GTK_WIDGET(button->rclick));
}
if ((button->popup != NULL) &&
(theme[IMAGE_SET_POPUP_MENU] != NULL)) {
nsgtk_image_menu_item_set_image(GTK_WIDGET(button->popup),
GTK_WIDGET(
theme[IMAGE_SET_POPUP_MENU]->
image[i]));
gtk_widget_show_all(GTK_WIDGET(button->popup));
}
if ((button->location != -1) && (button->button != NULL) &&
(theme[IMAGE_SET_BUTTONS] != NULL)) {
gtk_tool_button_set_icon_widget(
GTK_TOOL_BUTTON(button->button),
GTK_WIDGET(
theme[IMAGE_SET_BUTTONS]->
image[i]));
gtk_widget_show_all(GTK_WIDGET(button->button));
}
}
/* set search bar images */
search = nsgtk_scaffolding_search(g);
if ((search != NULL) && (theme[IMAGE_SET_MAIN_MENU] != NULL)) {
/* gtk_tool_button_set_icon_widget accepts NULL image */
if (search->buttons[SEARCH_BACK_BUTTON] != NULL) {
gtk_tool_button_set_icon_widget(
search->buttons[SEARCH_BACK_BUTTON],
GTK_WIDGET(theme[IMAGE_SET_MAIN_MENU]->
searchimage[SEARCH_BACK_BUTTON]));
gtk_widget_show_all(GTK_WIDGET(
search->buttons[SEARCH_BACK_BUTTON]));
}
if (search->buttons[SEARCH_FORWARD_BUTTON] != NULL) {
gtk_tool_button_set_icon_widget(
search->buttons[SEARCH_FORWARD_BUTTON],
GTK_WIDGET(theme[IMAGE_SET_MAIN_MENU]->
searchimage[SEARCH_FORWARD_BUTTON]));
gtk_widget_show_all(GTK_WIDGET(
search->buttons[
SEARCH_FORWARD_BUTTON]));
}
if (search->buttons[SEARCH_CLOSE_BUTTON] != NULL) {
gtk_tool_button_set_icon_widget(
search->buttons[SEARCH_CLOSE_BUTTON],
GTK_WIDGET(theme[IMAGE_SET_MAIN_MENU]->
searchimage[SEARCH_CLOSE_BUTTON]));
gtk_widget_show_all(GTK_WIDGET(
search->buttons[SEARCH_CLOSE_BUTTON]));
}
}
for (i = 0; i < IMAGE_SET_COUNT; i++) {
if (theme[i] != NULL) {
free(theme[i]);
}
}
}
/**
* get default image for buttons / menu items from gtk stock items.
*
* \param tbbutton button reference
* \param iconsize The size of icons to select.
* \return default images.
*/
static GtkImage *
nsgtk_theme_image_default(nsgtk_toolbar_button tbbutton, GtkIconSize iconsize)
{
GtkImage *image; /* The GTK image to return */
char *imagefile;
size_t len;
switch(tbbutton) {
#define BUTTON_IMAGE(p, q) \
case p##_BUTTON: \
image = GTK_IMAGE(nsgtk_image_new_from_stock(q, iconsize)); \
break
BUTTON_IMAGE(BACK, NSGTK_STOCK_GO_BACK);
BUTTON_IMAGE(FORWARD, NSGTK_STOCK_GO_FORWARD);
BUTTON_IMAGE(STOP, NSGTK_STOCK_STOP);
BUTTON_IMAGE(RELOAD, NSGTK_STOCK_REFRESH);
BUTTON_IMAGE(HOME, NSGTK_STOCK_HOME);
BUTTON_IMAGE(NEWWINDOW, "gtk-new");
BUTTON_IMAGE(NEWTAB, "gtk-new");
BUTTON_IMAGE(OPENFILE, NSGTK_STOCK_OPEN);
BUTTON_IMAGE(CLOSETAB, NSGTK_STOCK_CLOSE);
BUTTON_IMAGE(CLOSEWINDOW, NSGTK_STOCK_CLOSE);
BUTTON_IMAGE(SAVEPAGE, NSGTK_STOCK_SAVE_AS);
BUTTON_IMAGE(PRINTPREVIEW, "gtk-print-preview");
BUTTON_IMAGE(PRINT, "gtk-print");
BUTTON_IMAGE(QUIT, "gtk-quit");
BUTTON_IMAGE(CUT, "gtk-cut");
BUTTON_IMAGE(COPY, "gtk-copy");
BUTTON_IMAGE(PASTE, "gtk-paste");
BUTTON_IMAGE(DELETE, "gtk-delete");
BUTTON_IMAGE(SELECTALL, "gtk-select-all");
BUTTON_IMAGE(FIND, NSGTK_STOCK_FIND);
BUTTON_IMAGE(PREFERENCES, "gtk-preferences");
BUTTON_IMAGE(ZOOMPLUS, "gtk-zoom-in");
BUTTON_IMAGE(ZOOMMINUS, "gtk-zoom-out");
BUTTON_IMAGE(ZOOMNORMAL, "gtk-zoom-100");
BUTTON_IMAGE(FULLSCREEN, "gtk-fullscreen");
BUTTON_IMAGE(VIEWSOURCE, "gtk-index");
BUTTON_IMAGE(CONTENTS, "gtk-help");
BUTTON_IMAGE(ABOUT, "gtk-about");
#undef BUTTON_IMAGE
case HISTORY_BUTTON:
len = SLEN("arrow_down_8x32.png") +strlen(res_dir_location) + 1;
imagefile = malloc(len);
if (imagefile == NULL) {
warn_user(messages_get("NoMemory"), 0);
return NULL;
}
snprintf(imagefile, len, "%sarrow_down_8x32.png",
res_dir_location);
image = GTK_IMAGE(gtk_image_new_from_file(imagefile));
free(imagefile);
break;
default:
len = SLEN("themes/Alpha.png") + strlen(res_dir_location) + 1;
imagefile = malloc(len);
if (imagefile == NULL) {
warn_user(messages_get("NoMemory"), 0);
return NULL;
}
snprintf(imagefile, len, "%sthemes/Alpha.png",res_dir_location);
image = GTK_IMAGE(gtk_image_new_from_file(imagefile));
free(imagefile);
break;
}
return image;
}
/**
* Get default image for search buttons / menu items from gtk stock items
*
* \param tbbutton search button reference
* \param iconsize The size of icons to select.
* \return default search image.
*/
static GtkImage *
nsgtk_theme_searchimage_default(nsgtk_search_buttons tbbutton,
GtkIconSize iconsize)
{
char *imagefile;
GtkImage *image;
switch(tbbutton) {
case (SEARCH_BACK_BUTTON):
return GTK_IMAGE(nsgtk_image_new_from_stock(NSGTK_STOCK_GO_BACK,
iconsize));
case (SEARCH_FORWARD_BUTTON):
return GTK_IMAGE(nsgtk_image_new_from_stock(NSGTK_STOCK_GO_FORWARD,
iconsize));
case (SEARCH_CLOSE_BUTTON):
return GTK_IMAGE(nsgtk_image_new_from_stock(NSGTK_STOCK_CLOSE,
iconsize));
default: {
size_t len = SLEN("themes/Alpha.png") +
strlen(res_dir_location) + 1;
imagefile = malloc(len);
if (imagefile == NULL) {
warn_user(messages_get("NoMemory"), 0);
return NULL;
}
snprintf(imagefile, len, "%sthemes/Alpha.png",
res_dir_location);
image = GTK_IMAGE(
gtk_image_new_from_file(imagefile));
free(imagefile);
return image;
}
}
}
/**
* loads the set of default images for the toolbar / menus
*/
static struct nsgtk_theme *nsgtk_theme_default(GtkIconSize iconsize)
{
struct nsgtk_theme *theme = malloc(sizeof(struct nsgtk_theme));
int btnloop;
if (theme == NULL) {
warn_user("NoMemory", 0);
return NULL;
}
for (btnloop = BACK_BUTTON; btnloop < PLACEHOLDER_BUTTON ; btnloop++) {
theme->image[btnloop] = nsgtk_theme_image_default(btnloop, iconsize);
}
for (btnloop = SEARCH_BACK_BUTTON; btnloop < SEARCH_BUTTONS_COUNT; btnloop++) {
theme->searchimage[btnloop] = nsgtk_theme_searchimage_default(btnloop, iconsize);
}
return theme;
}
/**
* creates a set of images to add to buttons / menus
* loads images from cache, calling an update to the cache when necessary
* \return a struct nsgtk_theme is an array of images
*/
struct nsgtk_theme *nsgtk_theme_load(GtkIconSize s)
{
if (current_theme_name == NULL) {
return nsgtk_theme_default(s);
}
struct nsgtk_theme *theme = malloc(sizeof(struct nsgtk_theme));
if (theme == NULL) {
return theme;
}
if ((theme_cache_menu == NULL) || (theme_cache_toolbar == NULL)) {
nsgtk_theme_prepare();
}
/* load theme from cache */
struct nsgtk_theme_cache *cachetheme = (s == GTK_ICON_SIZE_MENU) ?
theme_cache_menu : theme_cache_toolbar;
if (cachetheme == NULL) {
free(theme);
return NULL;
}
#define SET_BUTTON_IMAGE(p, q, r) \
if (p->image[q##_BUTTON] != NULL) \
r->image[q##_BUTTON] = GTK_IMAGE(gtk_image_new_from_pixbuf( \
p->image[q##_BUTTON])); \
else \
r->image[q##_BUTTON] = nsgtk_theme_image_default(q##_BUTTON, s)
SET_BUTTON_IMAGE(cachetheme, BACK, theme);
SET_BUTTON_IMAGE(cachetheme, HISTORY, theme);
SET_BUTTON_IMAGE(cachetheme, FORWARD, theme);
SET_BUTTON_IMAGE(cachetheme, STOP, theme);
SET_BUTTON_IMAGE(cachetheme, RELOAD, theme);
SET_BUTTON_IMAGE(cachetheme, HOME, theme);
SET_BUTTON_IMAGE(cachetheme, NEWWINDOW, theme);
SET_BUTTON_IMAGE(cachetheme, NEWTAB, theme);
SET_BUTTON_IMAGE(cachetheme, OPENFILE, theme);
SET_BUTTON_IMAGE(cachetheme, CLOSETAB, theme);
SET_BUTTON_IMAGE(cachetheme, CLOSEWINDOW, theme);
SET_BUTTON_IMAGE(cachetheme, SAVEPAGE, theme);
SET_BUTTON_IMAGE(cachetheme, PRINTPREVIEW, theme);
SET_BUTTON_IMAGE(cachetheme, PRINT, theme);
SET_BUTTON_IMAGE(cachetheme, QUIT, theme);
SET_BUTTON_IMAGE(cachetheme, CUT, theme);
SET_BUTTON_IMAGE(cachetheme, COPY, theme);
SET_BUTTON_IMAGE(cachetheme, PASTE, theme);
SET_BUTTON_IMAGE(cachetheme, DELETE, theme);
SET_BUTTON_IMAGE(cachetheme, SELECTALL, theme);
SET_BUTTON_IMAGE(cachetheme, PREFERENCES, theme);
SET_BUTTON_IMAGE(cachetheme, ZOOMPLUS, theme);
SET_BUTTON_IMAGE(cachetheme, ZOOMMINUS, theme);
SET_BUTTON_IMAGE(cachetheme, ZOOMNORMAL, theme);
SET_BUTTON_IMAGE(cachetheme, FULLSCREEN, theme);
SET_BUTTON_IMAGE(cachetheme, VIEWSOURCE, theme);
SET_BUTTON_IMAGE(cachetheme, CONTENTS, theme);
SET_BUTTON_IMAGE(cachetheme, ABOUT, theme);
SET_BUTTON_IMAGE(cachetheme, PDF, theme);
SET_BUTTON_IMAGE(cachetheme, PLAINTEXT, theme);
SET_BUTTON_IMAGE(cachetheme, DRAWFILE, theme);
SET_BUTTON_IMAGE(cachetheme, POSTSCRIPT, theme);
SET_BUTTON_IMAGE(cachetheme, FIND, theme);
SET_BUTTON_IMAGE(cachetheme, DOWNLOADS, theme);
SET_BUTTON_IMAGE(cachetheme, SAVEWINDOWSIZE, theme);
SET_BUTTON_IMAGE(cachetheme, TOGGLEDEBUGGING, theme);
SET_BUTTON_IMAGE(cachetheme, SAVEBOXTREE, theme);
SET_BUTTON_IMAGE(cachetheme, SAVEDOMTREE, theme);
SET_BUTTON_IMAGE(cachetheme, LOCALHISTORY, theme);
SET_BUTTON_IMAGE(cachetheme, GLOBALHISTORY, theme);
SET_BUTTON_IMAGE(cachetheme, ADDBOOKMARKS, theme);
SET_BUTTON_IMAGE(cachetheme, SHOWBOOKMARKS, theme);
SET_BUTTON_IMAGE(cachetheme, SHOWCOOKIES, theme);
SET_BUTTON_IMAGE(cachetheme, OPENLOCATION, theme);
SET_BUTTON_IMAGE(cachetheme, NEXTTAB, theme);
SET_BUTTON_IMAGE(cachetheme, PREVTAB, theme);
SET_BUTTON_IMAGE(cachetheme, GUIDE, theme);
SET_BUTTON_IMAGE(cachetheme, INFO, theme);
#undef SET_BUTTON_IMAGE
#define SET_BUTTON_IMAGE(p, q, qq, r) \
if (qq->searchimage[SEARCH_##p##_BUTTON] != NULL) \
r->searchimage[SEARCH_##p##_BUTTON] = \
GTK_IMAGE(gtk_image_new_from_pixbuf( \
qq->searchimage[ \
SEARCH_##p##_BUTTON])); \
else if (qq->image[q##_BUTTON] != NULL) \
r->searchimage[SEARCH_##p##_BUTTON] = \
GTK_IMAGE(gtk_image_new_from_pixbuf( \
qq->image[q##_BUTTON])); \
else \
r->searchimage[SEARCH_##p##_BUTTON] = \
nsgtk_theme_searchimage_default( \
SEARCH_##p##_BUTTON, s)
SET_BUTTON_IMAGE(BACK, BACK, cachetheme, theme);
SET_BUTTON_IMAGE(FORWARD, FORWARD, cachetheme, theme);
SET_BUTTON_IMAGE(CLOSE, CLOSEWINDOW, cachetheme, theme);
#undef SET_BUTTON_IMAGE
return theme;
}
/**
* caches individual theme images from file
* \param i the toolbar button reference
* \param filename the image file name
* \param path the path to the theme folder
*/
static void
nsgtk_theme_cache_image(nsgtk_toolbar_button i, const char *filename,
const char *path)
{
char fullpath[strlen(filename) + strlen(path) + 1];
sprintf(fullpath, "%s%s", path, filename);
if (theme_cache_toolbar != NULL)
theme_cache_toolbar->image[i] =
gdk_pixbuf_new_from_file_at_size(fullpath,
24, 24, NULL);
if (theme_cache_menu != NULL) {
theme_cache_menu->image[i] = gdk_pixbuf_new_from_file_at_size(
fullpath, 16, 16, NULL);
}
}
static void
nsgtk_theme_cache_searchimage(nsgtk_search_buttons i,
const char *filename, const char *path)
{
char fullpath[strlen(filename) + strlen(path) + 1];
sprintf(fullpath, "%s%s", path, filename);
if (theme_cache_toolbar != NULL) {
theme_cache_toolbar->searchimage[i] =
gdk_pixbuf_new_from_file_at_size(fullpath,
24, 24, NULL);
}
if (theme_cache_menu != NULL) {
theme_cache_menu->searchimage[i] =
gdk_pixbuf_new_from_file_at_size(fullpath,
16, 16, NULL);
}
}
/**
* caches theme images from file as pixbufs
*/
void nsgtk_theme_prepare(void)
{
if (current_theme_name == NULL)
return;
if (theme_cache_menu == NULL)
theme_cache_menu = malloc(sizeof(struct nsgtk_theme_cache));
if (theme_cache_toolbar == NULL)
theme_cache_toolbar = malloc(sizeof(struct nsgtk_theme_cache));
size_t len = strlen(res_dir_location) + SLEN("/themes/") +
strlen(current_theme_name) + 1;
char path[len];
snprintf(path, len, "%sthemes/%s/", res_dir_location,
current_theme_name);
#define CACHE_IMAGE(p, q, r) \
nsgtk_theme_cache_image(p##_BUTTON, #q ".png", r)
CACHE_IMAGE(BACK, back, path);
CACHE_IMAGE(HISTORY, history, path);
CACHE_IMAGE(FORWARD, forward, path);
CACHE_IMAGE(STOP, stop, path);
CACHE_IMAGE(RELOAD, reload, path);
CACHE_IMAGE(HOME, home, path);
CACHE_IMAGE(NEWWINDOW, newwindow, path);
CACHE_IMAGE(NEWTAB, newtab, path);
CACHE_IMAGE(OPENFILE, openfile, path);
CACHE_IMAGE(CLOSETAB, closetab, path);
CACHE_IMAGE(CLOSEWINDOW, closewindow, path);
CACHE_IMAGE(SAVEPAGE, savepage, path);
CACHE_IMAGE(PRINTPREVIEW, printpreview, path);
CACHE_IMAGE(PRINT, print, path);
CACHE_IMAGE(QUIT, quit, path);
CACHE_IMAGE(CUT, cut, path);
CACHE_IMAGE(COPY, copy, path);
CACHE_IMAGE(PASTE, paste, path);
CACHE_IMAGE(DELETE, delete, path);
CACHE_IMAGE(SELECTALL, selectall, path);
CACHE_IMAGE(PREFERENCES, preferences, path);
CACHE_IMAGE(ZOOMPLUS, zoomplus, path);
CACHE_IMAGE(ZOOMMINUS, zoomminus, path);
CACHE_IMAGE(ZOOMNORMAL, zoomnormal, path);
CACHE_IMAGE(FULLSCREEN, fullscreen, path);
CACHE_IMAGE(VIEWSOURCE, viewsource, path);
CACHE_IMAGE(CONTENTS, helpcontents, path);
CACHE_IMAGE(ABOUT, helpabout, path);
CACHE_IMAGE(PDF, pdf, path);
CACHE_IMAGE(PLAINTEXT, plaintext, path);
CACHE_IMAGE(DRAWFILE, drawfile, path);
CACHE_IMAGE(POSTSCRIPT, postscript, path);
CACHE_IMAGE(FIND, find, path);
CACHE_IMAGE(DOWNLOADS, downloads, path);
CACHE_IMAGE(SAVEWINDOWSIZE, savewindowsize, path);
CACHE_IMAGE(TOGGLEDEBUGGING, toggledebugging, path);
CACHE_IMAGE(SAVEBOXTREE, boxtree, path);
CACHE_IMAGE(SAVEDOMTREE, domtree, path);
CACHE_IMAGE(LOCALHISTORY, localhistory, path);
CACHE_IMAGE(GLOBALHISTORY, globalhistory, path);
CACHE_IMAGE(ADDBOOKMARKS, addbookmarks, path);
CACHE_IMAGE(SHOWBOOKMARKS, showbookmarks, path);
CACHE_IMAGE(SHOWCOOKIES, showcookies, path);
CACHE_IMAGE(OPENLOCATION, openlocation, path);
CACHE_IMAGE(NEXTTAB, nexttab, path);
CACHE_IMAGE(PREVTAB, prevtab, path);
CACHE_IMAGE(GUIDE, helpguide, path);
CACHE_IMAGE(INFO, helpinfo, path);
#undef CACHE_IMAGE
#define CACHE_IMAGE(p, q, r) \
nsgtk_theme_cache_searchimage(p, #q ".png", r);
CACHE_IMAGE(SEARCH_BACK_BUTTON, searchback, path);
CACHE_IMAGE(SEARCH_FORWARD_BUTTON, searchforward, path);
CACHE_IMAGE(SEARCH_CLOSE_BUTTON, searchclose, path);
#undef CACHE_IMAGE
}
#ifdef WITH_THEME_INSTALL
/**
* handler saves theme data content as a local theme
*/
static bool theme_install_read(const char *data, unsigned long len)
{
char *filename, *newfilename;
size_t namelen;
int handle = g_file_open_tmp("nsgtkthemeXXXXXX", &filename, NULL);
if (handle == -1) {
warn_user(messages_get("gtkFileError"),
"temporary theme file");
return false;
}
ssize_t written = write(handle, data, len);
close(handle);
if ((unsigned)written != len)
return false;
/* get name of theme; set as dirname */
namelen = SLEN("themes/") + strlen(res_dir_location) + 1;
char dirname[namelen];
snprintf(dirname, namelen, "%sthemes/", res_dir_location);
/* save individual files in theme */
newfilename = container_extract_theme(filename, dirname);
g_free(filename);
if (newfilename == NULL)
return false;
nsgtk_theme_add(newfilename);
free(newfilename);
return true;
}
/**
* Callback for fetchcache() for theme install fetches.
*/
static nserror
theme_install_callback(hlcache_handle *c,
const hlcache_event *event, void *pw)
{
switch (event->type) {
case CONTENT_MSG_DONE: {
const char *source_data;
unsigned long source_size;
source_data = content_get_source_data(c, &source_size);
if (!theme_install_read(source_data, source_size))
warn_user("ThemeInvalid", 0);
hlcache_handle_release(c);
break;
}
case CONTENT_MSG_ERROR:
warn_user(event->data.error, 0);
break;
default:
break;
}
return NSERROR_OK;
}
/**
* when CONTENT_THEME needs handling call this function
*/
void theme_install_start(hlcache_handle *c)
{
assert(c);
assert(content_get_type(c) == CONTENT_THEME);
/* stop theme sitting in memory cache */
content_invalidate_reuse_data(c);
hlcache_handle_replace_callback(c, theme_install_callback, NULL);
}
#endif

View File

@ -1,43 +0,0 @@
/*
* Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.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 _NETSURF_GTK_THEME_H_
#define _NETSURF_GTK_THEME_H_
typedef enum search_buttons {
SEARCH_BACK_BUTTON = 0,
SEARCH_FORWARD_BUTTON,
SEARCH_CLOSE_BUTTON,
SEARCH_BUTTONS_COUNT
} nsgtk_search_buttons;
struct nsgtk_theme {
GtkImage *image[PLACEHOLDER_BUTTON];
GtkImage *searchimage[SEARCH_BUTTONS_COUNT];
/* apng throbber element */
};
struct nsgtk_theme *nsgtk_theme_load(GtkIconSize s);
void nsgtk_theme_add(const char *themename);
void nsgtk_theme_init(void);
void nsgtk_theme_prepare(void);
void nsgtk_theme_implement(struct nsgtk_scaffolding *g);
char *nsgtk_theme_name(void);
void nsgtk_theme_set_name(const char *name);
#endif

View File

@ -1,765 +0,0 @@
/*
* Copyright 2006 Rob Kendrick <rjek@rjek.com>
*
* 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/>.
*/
/* To build a stand-alone command-line utility to create and dismantal
* these theme files, build this thusly:
*
* gcc -I../ -DNSTHEME -o themetool container.c
*
* [needs a c99 compiler]
*
* then for instance to create a theme file called mythemefilename
* ./themetool --verbose --create -n"My theme name" mythemefilename\
* --author "Myname" /path/to/directory/containing/theme/files/
*/
/** \file
* Container format handling for themes etc. */
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include "utils/config.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/utils.h"
#include "gtk/theme_container.h"
#ifdef WITH_MMAP
#include <sys/mman.h>
#endif
#ifdef NSTHEME
bool verbose_log = true;
#endif
struct container_dirent {
unsigned char filename[64];
u_int32_t startoffset;
u_int32_t len;
u_int32_t flags1;
u_int32_t flags2;
};
struct container_header {
u_int32_t magic; /* 0x4d54534e little endian */
u_int32_t parser;
unsigned char name[32];
unsigned char author[64];
u_int32_t diroffset;
};
struct container_ctx {
FILE *fh;
bool creating;
bool processed;
struct container_header header;
unsigned int entries;
unsigned char *data;
struct container_dirent *directory;
};
inline static size_t container_filelen(FILE *fd)
{
long o;
long a;
o = ftell(fd);
if (o == -1) {
LOG("Could not get current stream position");
return 0;
}
if (fseek(fd, 0, SEEK_END) != 0) {
LOG("Could not get seek to end of file");
return 0;
}
a = ftell(fd);
if (fseek(fd, o, SEEK_SET) != 0) {
LOG("Could not reset seek position in file");
return 0;
}
if (a == -1) {
LOG("could not ascertain size of file in theme container; omitting");
return 0;
}
if (((unsigned long) a) > SIZE_MAX) {
LOG("overlarge file in theme container; possible truncation");
return SIZE_MAX;
}
return (size_t) a;
}
static void container_add_to_dir(struct container_ctx *ctx,
const unsigned char *entryname,
const u_int32_t offset,
const u_int32_t length)
{
struct container_dirent *temp;
temp = realloc(ctx->directory, ctx->entries *
sizeof(struct container_dirent));
if (temp == NULL) {
printf("error adding entry for %s to theme container\n", entryname);
return;
}
ctx->entries += 1;
ctx->directory = temp;
snprintf((char*)ctx->directory[ctx->entries - 1].filename,
sizeof(ctx->directory[ctx->entries - 1].filename),
"%s", (char *)entryname);
ctx->directory[ctx->entries - 1].startoffset = offset;
ctx->directory[ctx->entries - 1].len = length;
ctx->directory[ctx->entries - 1].flags1 = 0;
ctx->directory[ctx->entries - 1].flags2 = 0;
}
struct container_ctx *container_open(const char *filename)
{
size_t val;
struct container_ctx *ctx = calloc(sizeof(struct container_ctx), 1);
ctx->fh = fopen(filename, "rb");
if (ctx->fh == NULL) {
free(ctx);
return NULL;
}
/* we don't actually load any of the data (including directory)
* until we need to, such that _get_name and _get_author are as quick
* as possible. When we have, this gets set to true.
*/
ctx->processed = false;
val = fread(&ctx->header.magic, 4, 1, ctx->fh);
if (val == 0)
LOG("empty read magic");
ctx->header.magic = ntohl(ctx->header.magic);
val = fread(&ctx->header.parser, 4, 1, ctx->fh);
if (val == 0)
LOG("empty read parser");
ctx->header.parser = ntohl(ctx->header.parser);
val = fread(ctx->header.name, 32, 1, ctx->fh);
if (val == 0)
LOG("empty read name");
val = fread(ctx->header.author, 64, 1, ctx->fh);
if (val == 0)
LOG("empty read author");
val = fread(&ctx->header.diroffset, 4, 1, ctx->fh);
if (val == 0)
LOG("empty read diroffset");
ctx->header.diroffset = ntohl(ctx->header.diroffset);
if (ctx->header.magic != 0x4e53544d || ctx->header.parser != 3) {
fclose(ctx->fh);
free(ctx);
return NULL;
}
return ctx;
}
static void container_process(struct container_ctx *ctx)
{
size_t val;
unsigned char filename[64];
u_int32_t start, len, flags1, flags2;
#ifdef WITH_MMAP
ctx->data = mmap(NULL, ctx->header.diroffset, PROT_READ, MAP_PRIVATE,
fileno(ctx->fh), 0);
#else
ctx->data = malloc(ctx->header.diroffset);
if (fseek(ctx->fh, 0, SEEK_SET) != 0) {
return;
}
val = fread(ctx->data, ctx->header.diroffset, 1, ctx->fh);
if (val == 0)
LOG("empty read diroffset");
#endif
if (fseek(ctx->fh, ctx->header.diroffset, SEEK_SET) != 0) {
return;
}
/* now work through the directory structure taking it apart into
* our structure */
#define BEREAD(x) do { val = fread(&(x), 4, 1, ctx->fh); if (val == 0)\
LOG("empty read");(x) = ntohl((x)); } while (0)
do {
val = fread(filename, 64, 1, ctx->fh);
if (val == 0)
LOG("empty read filename");
BEREAD(start);
BEREAD(len);
BEREAD(flags1);
BEREAD(flags2);
if (filename[0] != '\0')
container_add_to_dir(ctx, filename, start, len);
} while (filename[0] != '\0');
#undef BEREAD
ctx->processed = true;
}
static const struct container_dirent *container_lookup(
struct container_ctx *ctx,
const unsigned char *entryname)
{
unsigned int i;
for (i = 1; i <= ctx->entries; i++) {
struct container_dirent *e = ctx->directory + i - 1;
if (strcmp((char *)e->filename, (char *)entryname) == 0)
return e;
}
return NULL;
}
const unsigned char *container_get(struct container_ctx *ctx,
const unsigned char *entryname,
u_int32_t *size)
{
const struct container_dirent *e;
if (ctx->processed == false)
container_process(ctx);
e = container_lookup(ctx, entryname);
if (e == NULL)
return NULL;
*size = e->len;
return &ctx->data[e->startoffset];
}
const unsigned char *container_iterate(struct container_ctx *ctx, int *state)
{
struct container_dirent *e;
unsigned char *r;
if (ctx->processed == false)
container_process(ctx);
e = ctx->directory + *state;
r = e->filename;
if (r == NULL || r[0] == '\0')
r = NULL;
*state += 1;
return r;
}
const unsigned char *container_get_name(struct container_ctx *ctx)
{
return ctx->header.name;
}
const unsigned char *container_get_author(struct container_ctx *ctx)
{
return ctx->header.author;
}
static void container_write_dir(struct container_ctx *ctx)
{
size_t val;
unsigned int i;
u_int32_t tmp;
#define BEWRITE(x) do {tmp = htonl((x)); val = fwrite(&tmp, 4, 1, ctx->fh);\
if (val == 0) LOG("empty write"); } while(0)
for (i = 1; i <= ctx->entries; i++) {
struct container_dirent *e = ctx->directory + i - 1;
val = fwrite(e->filename, 64, 1, ctx->fh);
if (val == 0)
LOG("empty write filename");
BEWRITE(e->startoffset);
BEWRITE(e->len);
BEWRITE(e->flags1);
BEWRITE(e->flags2);
}
#undef BEWRITE
/* empty entry signifies end of directory */
tmp = 0;
val = fwrite(&tmp, 4, 8, ctx->fh);
if (val == 0)
LOG("empty write end");
}
struct container_ctx *container_create(const char *filename,
const unsigned char *name,
const unsigned char *author)
{
size_t val;
struct container_ctx *ctx = calloc(sizeof(struct container_ctx), 1);
ctx->fh = fopen(filename, "wb");
if (ctx->fh == NULL) {
free(ctx);
return NULL;
}
ctx->creating = true;
ctx->entries = 0;
ctx->directory = NULL;
ctx->header.parser = htonl(3);
snprintf((char *)ctx->header.name,
sizeof(ctx->header.name),
"%s", (char *)name);
snprintf((char *)ctx->header.author,
sizeof(ctx->header.author),
"%s", (char *)author);
val = fwrite("NSTM", 4, 1, ctx->fh);
if (val == 0)
LOG("empty write NSTM");
val = fwrite(&ctx->header.parser, 4, 1, ctx->fh);
if (val == 0)
LOG("empty write parser");
val = fwrite(ctx->header.name, 32, 1, ctx->fh);
if (val == 0)
LOG("empty write name");
val = fwrite(ctx->header.author, 64, 1, ctx->fh);
if (val == 0)
LOG("empty write author");
ctx->header.diroffset = 108;
/* skip over the directory offset for now, and fill it in later.
* we don't know where it'll be yet!
*/
if (fseek(ctx->fh, 108, SEEK_SET) == -1) {
LOG("directory offset seek failed");
free(ctx);
return NULL;
}
return ctx;
}
void container_add(struct container_ctx *ctx, const unsigned char *entryname,
const unsigned char *data,
const u_int32_t datalen)
{
size_t val;
container_add_to_dir(ctx, entryname, ftell(ctx->fh), datalen);
val = fwrite(data, datalen, 1, ctx->fh);
if (val == 0)
LOG("empty write add file");
}
void container_close(struct container_ctx *ctx)
{
if (ctx->creating == true) {
size_t flen, nflen, val;
/* discover where the directory's going to go. */
flen = container_filelen(ctx->fh);
flen = (flen + 3) & (~3); /* round up to nearest 4 bytes */
/* write this location to the header */
if (fseek(ctx->fh, 104, SEEK_SET) == 0) {
nflen = htonl(flen);
val = fwrite(&nflen, 4, 1, ctx->fh);
if (val == 0)
LOG("empty write directory location");
/* seek to where the directory will be, and write it */
if (fseek(ctx->fh, flen, SEEK_SET) == 0) {
container_write_dir(ctx);
}
}
} else if (ctx->processed) {
#ifdef WITH_MMAP
munmap(ctx->data, ctx->header.diroffset);
#else
free(ctx->data);
#endif
}
fclose(ctx->fh);
free(ctx);
}
#ifdef WITH_THEME_INSTALL
/**
* install theme from container
* \param themefile a file containing the containerized theme
* \param dirbasename a directory basename including trailing path sep; the
* full path of the theme is then a subdirectory of that
* caller owns reference to returned string, NULL for error
*/
char *container_extract_theme(const char *themefile, const char *dirbasename)
{
struct stat statbuf;
struct container_ctx *cctx;
FILE *fh;
size_t val;
const unsigned char *e, *d;
char *themename, *dirname;
char path[PATH_MAX];
int state = 0;
unsigned int i;
u_int32_t flen;
cctx = container_open(themefile);
if (cctx == NULL) {
warn_user("FileOpenError", themefile);
return NULL;
}
themename = strdup((const char *)container_get_name(cctx));
if (themename == NULL) {
warn_user("NoMemory", 0);
container_close(cctx);
return NULL;
}
LOG("theme name: %s", themename);
LOG("theme author: %s", container_get_author(cctx));
dirname = malloc(strlen(dirbasename) + strlen(themename) + 2);
if (dirname == NULL) {
warn_user(messages_get("NoMemory"), 0);
free(themename);
container_close(cctx);
return NULL;
}
strcpy(dirname, dirbasename);
strcat(dirname, themename);
if (stat(dirname, &statbuf) != -1) {
/* directory exists */
warn_user("DirectoryError", dirname);
container_close(cctx);
free(dirname);
free(themename);
return NULL;
}
if (mkdir(dirname, S_IRWXU) != 0) {
warn_user("DirectoryError", dirname);
container_close(cctx);
free(dirname);
free(themename);
return NULL;
}
for (e = container_iterate(cctx, &state), i = 0; i < cctx->entries;
e = container_iterate(cctx, &state), i++) {
LOG("extracting %s", e);
snprintf(path, PATH_MAX, "%s/%s", dirname, e);
fh = fopen(path, "wb");
if (fh == NULL) {
warn_user("FileOpenError", (char *)e);
} else {
d = container_get(cctx, e, &flen);
val = fwrite(d, flen, 1, fh);
if (val == 0)
LOG("empty write");
fclose(fh);
}
}
LOG("theme container unpacked");
container_close(cctx);
free(dirname);
return themename;
}
#endif
#ifdef TEST_RIG
int main(int argc, char *argv[])
{
struct container_ctx *ctx = container_create("test.theme", "Test theme",
"Rob Kendrick");
u_int32_t size;
int state = 0;
char *n;
container_add(ctx, "CHEESE", "This is a test of some cheese.", sizeof("This is a test of some cheese."));
container_add(ctx, "FOO", "This is a test of some cheese.", sizeof("This is a test of some cheese."));
container_close(ctx);
ctx = container_open("test.theme");
printf("Theme name: %s\n", container_get_name(ctx));
printf("Theme author: %s\n", container_get_author(ctx));
printf("Test string: %s\n", container_get(ctx, "CHEESE", &size));
printf("Length of text: %d\n", size);
while ( (n = container_iterate(ctx, &state)) ) {
printf("%s\n", n);
}
container_close(ctx);
exit(0);
}
#endif
#ifdef NSTHEME
/* code to implement a simple container creator/extractor */
#include <getopt.h>
#include <dirent.h>
#include <errno.h>
#include <unistd.h>
static bool verbose = false;
static void show_usage(const char *argv0)
{
fprintf(stderr, "%s [options] <theme file> <directory>\n", argv0);
fprintf(stderr, " --help This text\n");
fprintf(stderr, " --create Create theme file from directory\n");
fprintf(stderr, " --extract Extract theme file into directory\n");
fprintf(stderr, " --name x Set theme's name when creating\n");
fprintf(stderr, " --author x Set theme's author when creating\n");
fprintf(stderr, " --verbose Print progress information\n");
fprintf(stderr, "\nOne and only one of --create or --extract must be specified.\n");
}
static void extract_theme(const char *themefile, const char *dirname)
{
struct stat statbuf;
struct container_ctx *cctx;
FILE *fh;
const unsigned char *e, *d;
char path[PATH_MAX];
int i, state = 0;
u_int32_t flen;
if (stat(dirname, &statbuf) != -1) {
fprintf(stderr, "error: directory '%s' already exists.\n",
dirname);
exit(1);
}
mkdir(dirname, S_IRWXU);
cctx = container_open(themefile);
if (cctx == NULL) {
fprintf(stderr, "error: unable to open theme file '%s'\n",
themefile);
exit(1);
}
if (verbose == true) {
printf("theme name: %s\n", container_get_name(cctx));
printf("theme author: %s\n", container_get_author(cctx));
}
for (e = container_iterate(cctx, &state), i = 0; i < cctx->entries;
e = container_iterate(cctx, &state), i++) {
if (verbose == true)
printf("extracting %s\n", e);
snprintf(path, PATH_MAX, "%s/%s", dirname, e);
fh = fopen(path, "wb");
if (fh == NULL) {
perror("warning: unable to open file for output");
} else {
d = container_get(cctx, e, &flen);
fwrite(d, flen, 1, fh);
fclose(fh);
}
}
container_close(cctx);
}
static void create_theme(const char *themefile, const char *dirname,
const unsigned char *name,
const unsigned char *author)
{
DIR *dir = opendir(dirname);
FILE *fh;
struct dirent *e;
struct stat statbuf;
struct container_ctx *cctx;
unsigned char *data;
char path[PATH_MAX];
size_t flen;
int t;
if (dir == NULL) {
perror("error: unable to open directory");
exit(1);
}
cctx = container_create(themefile, name, author);
errno = 0; /* to distinguish between end of dir and err */
while ((e = readdir(dir)) != NULL) {
if (strcmp(e->d_name, ".") != 0 &&
strcmp(e->d_name, "..") != 0) {
/* not the metadirs, so we want to process this. */
if (verbose == true)
printf("adding %s\n", e->d_name);
if (strlen(e->d_name) > 63) {
fprintf(stderr,
"warning: name truncated to length 63.\n");
}
snprintf(path, PATH_MAX, "%s/%s", dirname, e->d_name);
stat(path, &statbuf);
if (S_ISDIR(statbuf.st_mode)) {
fprintf(stderr,
"warning: skipping directory '%s'\n",
e->d_name);
continue;
}
fh = fopen(path, "rb");
if (fh == NULL) {
fprintf(stderr,
"warning: unable to open, skipping.");
} else {
flen = statbuf.st_size;
data = malloc(flen);
t = fread(data, flen, 1, fh);
fclose(fh);
container_add(cctx, (unsigned char *)e->d_name,
data, flen);
free(data);
}
}
errno = 0;
}
if (errno != 0) {
perror("error: couldn't enumerate directory");
closedir(dir);
container_close(cctx);
exit(1);
}
closedir(dir);
container_close(cctx);
}
int main(int argc, char *argv[])
{
static struct option l_opts[] = {
{ "help", 0, 0, 'h' },
{ "create", 0, 0, 'c' },
{ "extract", 0, 0, 'x' },
{ "name", 1, 0, 'n' },
{ "author", 1, 0, 'a' },
{ "verbose", 0, 0, 'v' },
{ NULL, 0, 0, 0 }
};
static char *s_opts = "hcxn:a:v";
int optch, optidx;
bool creating = false, extracting = false;
unsigned char name[32] = { '\0' }, author[64] = { '\0' };
char *themefile, *dirname;
while ((optch = getopt_long(argc, argv, s_opts, l_opts, &optidx)) != -1)
switch (optch) {
case 'h':
show_usage(argv[0]);
exit(0);
break;
case 'c':
creating = true;
break;
case 'x':
extracting = true;
break;
case 'n':
strncpy((char *)name, optarg, 31);
if (strlen(optarg) > 32)
fprintf(stderr, "warning: theme name truncated to 32 characters.\n");
break;
case 'a':
strncpy((char *)author, optarg, 63);
if (strlen(optarg) > 64)
fprintf(stderr, "warning: theme author truncated to 64 characters.\n");
break;
case 'v':
verbose = true;
break;
default:
show_usage(argv[0]);
exit(1);
break;
}
if (creating == extracting) {
show_usage(argv[0]);
exit(1);
}
if ((argc - optind) < 2) {
show_usage(argv[0]);
exit(1);
}
if (creating == true &&
(strlen((char *)name) == 0 || strlen((char *)author) == 0)) {
fprintf(stderr, "No theme name and/or author specified.\n");
show_usage(argv[0]);
exit(1);
}
themefile = strdup(argv[optind]);
dirname = strdup(argv[optind + 1]);
if (verbose == true)
printf("%s '%s' %s directory '%s'\n",
creating ? "creating" : "extracting", themefile,
creating ? "from" : "to", dirname);
if (creating) {
if (verbose == true)
printf("name = %s, author = %s\n", name, author);
create_theme(themefile, dirname, name, author);
} else {
extract_theme(themefile, dirname);
}
return 0;
}
#endif

View File

@ -1,53 +0,0 @@
/*
* Copyright 2006 Rob Kendrick <rjek@rjek.com>
*
* 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/>.
*/
/** \file
* Container format handling for themes etc. */
#ifndef __CONTAINER_H__
#define __CONTAINER_H__
#include <sys/types.h>
struct container_ctx;
/* reading interface */
struct container_ctx *container_open(const char *filename);
const unsigned char *container_get(struct container_ctx *ctx,
const unsigned char *entryname,
u_int32_t *size);
const unsigned char *container_get_name(struct container_ctx *ctx);
const unsigned char *container_get_author(struct container_ctx *ctx);
const unsigned char *container_iterate(struct container_ctx *ctx,
int *state);
/* creating interface */
struct container_ctx *container_create(const char *filename,
const unsigned char *name,
const unsigned char *author);
void container_add(struct container_ctx *ctx, const unsigned char *entryname,
const unsigned char *data,
const u_int32_t datalen);
/* common interface */
void container_close(struct container_ctx *ctx);
#ifdef WITH_THEME_INSTALL
char *container_extract_theme(const char *themefile, const char *dirbasename);
#endif
#endif /* __CONTAINER_H__ */

View File

@ -29,7 +29,6 @@
#include "gtk/gui.h"
#include "gtk/scaffolding.h"
#include "gtk/search.h"
#include "gtk/theme.h"
#include "gtk/throbber.h"
#include "gtk/window.h"
#include "gtk/compat.h"
@ -69,6 +68,240 @@ possible into the store */
static struct nsgtk_toolbar_custom_store store;
static struct nsgtk_toolbar_custom_store *window = &store;
enum image_sets {
IMAGE_SET_MAIN_MENU = 0,
IMAGE_SET_RCLICK_MENU,
IMAGE_SET_POPUP_MENU,
IMAGE_SET_BUTTONS,
IMAGE_SET_COUNT
};
typedef enum search_buttons {
SEARCH_BACK_BUTTON = 0,
SEARCH_FORWARD_BUTTON,
SEARCH_CLOSE_BUTTON,
SEARCH_BUTTONS_COUNT
} nsgtk_search_buttons;
struct nsgtk_theme {
GtkImage *image[PLACEHOLDER_BUTTON];
GtkImage *searchimage[SEARCH_BUTTONS_COUNT];
/* apng throbber element */
};
/**
* get default image for buttons / menu items from gtk stock items.
*
* \param tbbutton button reference
* \param iconsize The size of icons to select.
* \return default images.
*/
static GtkImage *
nsgtk_theme_image_default(nsgtk_toolbar_button tbbutton, GtkIconSize iconsize)
{
GtkImage *image; /* The GTK image to return */
switch(tbbutton) {
#define BUTTON_IMAGE(p, q) \
case p##_BUTTON: \
image = GTK_IMAGE(nsgtk_image_new_from_stock(q, iconsize)); \
break
BUTTON_IMAGE(BACK, NSGTK_STOCK_GO_BACK);
BUTTON_IMAGE(FORWARD, NSGTK_STOCK_GO_FORWARD);
BUTTON_IMAGE(STOP, NSGTK_STOCK_STOP);
BUTTON_IMAGE(RELOAD, NSGTK_STOCK_REFRESH);
BUTTON_IMAGE(HOME, NSGTK_STOCK_HOME);
BUTTON_IMAGE(NEWWINDOW, "gtk-new");
BUTTON_IMAGE(NEWTAB, "gtk-new");
BUTTON_IMAGE(OPENFILE, NSGTK_STOCK_OPEN);
BUTTON_IMAGE(CLOSETAB, NSGTK_STOCK_CLOSE);
BUTTON_IMAGE(CLOSEWINDOW, NSGTK_STOCK_CLOSE);
BUTTON_IMAGE(SAVEPAGE, NSGTK_STOCK_SAVE_AS);
BUTTON_IMAGE(PRINTPREVIEW, "gtk-print-preview");
BUTTON_IMAGE(PRINT, "gtk-print");
BUTTON_IMAGE(QUIT, "gtk-quit");
BUTTON_IMAGE(CUT, "gtk-cut");
BUTTON_IMAGE(COPY, "gtk-copy");
BUTTON_IMAGE(PASTE, "gtk-paste");
BUTTON_IMAGE(DELETE, "gtk-delete");
BUTTON_IMAGE(SELECTALL, "gtk-select-all");
BUTTON_IMAGE(FIND, NSGTK_STOCK_FIND);
BUTTON_IMAGE(PREFERENCES, "gtk-preferences");
BUTTON_IMAGE(ZOOMPLUS, "gtk-zoom-in");
BUTTON_IMAGE(ZOOMMINUS, "gtk-zoom-out");
BUTTON_IMAGE(ZOOMNORMAL, "gtk-zoom-100");
BUTTON_IMAGE(FULLSCREEN, "gtk-fullscreen");
BUTTON_IMAGE(VIEWSOURCE, "gtk-index");
BUTTON_IMAGE(CONTENTS, "gtk-help");
BUTTON_IMAGE(ABOUT, "gtk-about");
#undef BUTTON_IMAGE
case HISTORY_BUTTON:
image = GTK_IMAGE(gtk_image_new_from_pixbuf(arrow_down_pixbuf));
break;
default:
image = GTK_IMAGE(nsgtk_image_new_from_stock("gtk-missing-image",
iconsize));
break;
}
return image;
}
/**
* Get default image for search buttons / menu items from gtk stock items
*
* \param tbbutton search button reference
* \param iconsize The size of icons to select.
* \return default search image.
*/
static GtkImage *
nsgtk_theme_searchimage_default(nsgtk_search_buttons tbbutton,
GtkIconSize iconsize)
{
switch (tbbutton) {
case (SEARCH_BACK_BUTTON):
return GTK_IMAGE(nsgtk_image_new_from_stock(NSGTK_STOCK_GO_BACK,
iconsize));
case (SEARCH_FORWARD_BUTTON):
return GTK_IMAGE(nsgtk_image_new_from_stock(NSGTK_STOCK_GO_FORWARD,
iconsize));
case (SEARCH_CLOSE_BUTTON):
return GTK_IMAGE(nsgtk_image_new_from_stock(NSGTK_STOCK_CLOSE,
iconsize));
default:
return NULL;
}
}
/**
* initialise a theme structure with gtk images
*/
static struct nsgtk_theme *nsgtk_theme_load(GtkIconSize iconsize)
{
struct nsgtk_theme *theme = malloc(sizeof(struct nsgtk_theme));
int btnloop;
if (theme == NULL) {
warn_user("NoMemory", 0);
return NULL;
}
for (btnloop = BACK_BUTTON; btnloop < PLACEHOLDER_BUTTON ; btnloop++) {
theme->image[btnloop] = nsgtk_theme_image_default(btnloop, iconsize);
}
for (btnloop = SEARCH_BACK_BUTTON; btnloop < SEARCH_BUTTONS_COUNT; btnloop++) {
theme->searchimage[btnloop] = nsgtk_theme_searchimage_default(btnloop, iconsize);
}
return theme;
}
/* exported function documented in gtk/toolbar.h */
void nsgtk_theme_implement(struct nsgtk_scaffolding *g)
{
struct nsgtk_theme *theme[IMAGE_SET_COUNT];
int i;
struct nsgtk_button_connect *button;
struct gtk_search *search;
theme[IMAGE_SET_MAIN_MENU] = nsgtk_theme_load(GTK_ICON_SIZE_MENU);
theme[IMAGE_SET_RCLICK_MENU] = nsgtk_theme_load(GTK_ICON_SIZE_MENU);
theme[IMAGE_SET_POPUP_MENU] = nsgtk_theme_load(GTK_ICON_SIZE_MENU);
theme[IMAGE_SET_BUTTONS] = nsgtk_theme_load(GTK_ICON_SIZE_LARGE_TOOLBAR);
for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) {
if ((i == URL_BAR_ITEM) || (i == THROBBER_ITEM) ||
(i == WEBSEARCH_ITEM))
continue;
button = nsgtk_scaffolding_button(g, i);
if (button == NULL)
continue;
/* gtk_image_menu_item_set_image accepts NULL image */
if ((button->main != NULL) &&
(theme[IMAGE_SET_MAIN_MENU] != NULL)) {
nsgtk_image_menu_item_set_image(
GTK_WIDGET(button->main),
GTK_WIDGET(theme[IMAGE_SET_MAIN_MENU]->image[i]));
gtk_widget_show_all(GTK_WIDGET(button->main));
}
if ((button->rclick != NULL) &&
(theme[IMAGE_SET_RCLICK_MENU] != NULL)) {
nsgtk_image_menu_item_set_image(GTK_WIDGET(button->rclick),
GTK_WIDGET(
theme[IMAGE_SET_RCLICK_MENU]->
image[i]));
gtk_widget_show_all(GTK_WIDGET(button->rclick));
}
if ((button->popup != NULL) &&
(theme[IMAGE_SET_POPUP_MENU] != NULL)) {
nsgtk_image_menu_item_set_image(GTK_WIDGET(button->popup),
GTK_WIDGET(
theme[IMAGE_SET_POPUP_MENU]->
image[i]));
gtk_widget_show_all(GTK_WIDGET(button->popup));
}
if ((button->location != -1) && (button->button != NULL) &&
(theme[IMAGE_SET_BUTTONS] != NULL)) {
gtk_tool_button_set_icon_widget(
GTK_TOOL_BUTTON(button->button),
GTK_WIDGET(
theme[IMAGE_SET_BUTTONS]->
image[i]));
gtk_widget_show_all(GTK_WIDGET(button->button));
}
}
/* set search bar images */
search = nsgtk_scaffolding_search(g);
if ((search != NULL) && (theme[IMAGE_SET_MAIN_MENU] != NULL)) {
/* gtk_tool_button_set_icon_widget accepts NULL image */
if (search->buttons[SEARCH_BACK_BUTTON] != NULL) {
gtk_tool_button_set_icon_widget(
search->buttons[SEARCH_BACK_BUTTON],
GTK_WIDGET(theme[IMAGE_SET_MAIN_MENU]->
searchimage[SEARCH_BACK_BUTTON]));
gtk_widget_show_all(GTK_WIDGET(
search->buttons[SEARCH_BACK_BUTTON]));
}
if (search->buttons[SEARCH_FORWARD_BUTTON] != NULL) {
gtk_tool_button_set_icon_widget(
search->buttons[SEARCH_FORWARD_BUTTON],
GTK_WIDGET(theme[IMAGE_SET_MAIN_MENU]->
searchimage[SEARCH_FORWARD_BUTTON]));
gtk_widget_show_all(GTK_WIDGET(
search->buttons[
SEARCH_FORWARD_BUTTON]));
}
if (search->buttons[SEARCH_CLOSE_BUTTON] != NULL) {
gtk_tool_button_set_icon_widget(
search->buttons[SEARCH_CLOSE_BUTTON],
GTK_WIDGET(theme[IMAGE_SET_MAIN_MENU]->
searchimage[SEARCH_CLOSE_BUTTON]));
gtk_widget_show_all(GTK_WIDGET(
search->buttons[SEARCH_CLOSE_BUTTON]));
}
}
for (i = 0; i < IMAGE_SET_COUNT; i++) {
if (theme[i] != NULL) {
free(theme[i]);
}
}
}
/**
* callback function to iterate toolbar's widgets
*/

View File

@ -23,6 +23,11 @@
#include "gtk/scaffolding.h"
/**
* sets up the images for scaffolding.
*/
void nsgtk_theme_implement(struct nsgtk_scaffolding *g);
void nsgtk_toolbar_customization_init(struct nsgtk_scaffolding *g);
void nsgtk_toolbar_init(struct nsgtk_scaffolding *g);
void nsgtk_toolbar_customization_load(struct nsgtk_scaffolding *g);

View File

@ -146,11 +146,6 @@ int scandir(const char *dir, struct dirent ***namelist,
#define WITH_MMAP
#endif
/* gtk */
#if defined(gtk)
#define WITH_THEME_INSTALL
#endif
/* amiga */
#if defined(__amigaos4__) || defined(__AMIGA__) || \
defined(nsatari)