summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
Diffstat (limited to 'ui')
-rw-r--r--ui/Makefile.am12
-rw-r--r--ui/gtk.c203
-rw-r--r--ui/internal.h71
-rw-r--r--ui/librccui.c387
-rw-r--r--ui/librccui.h46
-rw-r--r--ui/rccnames.c31
-rw-r--r--ui/rccnames.h9
7 files changed, 759 insertions, 0 deletions
diff --git a/ui/Makefile.am b/ui/Makefile.am
new file mode 100644
index 0000000..121d2c4
--- /dev/null
+++ b/ui/Makefile.am
@@ -0,0 +1,12 @@
+if HAVE_GTK
+lib_LTLIBRARIES = librccgtk.la
+librccgtk_la_SOURCES = librccui.c \
+ rccnames.c rccnames.h \
+ internal.h \
+ gtk.c
+librccgtk_la_LIBADD = @GTK_LIBS@ ../src/librcc.la
+librccgtk_la_LDFLAGS = -version-info @LIBRCC_VERSION_INFO@
+endif
+
+INCLUDES = -I../src @GTK_INCLUDES@
+include_HEADERS = librccui.h
diff --git a/ui/gtk.c b/ui/gtk.c
new file mode 100644
index 0000000..d299a8e
--- /dev/null
+++ b/ui/gtk.c
@@ -0,0 +1,203 @@
+#include <stdio.h>
+#include <gtk/gtk.h>
+#include "internal.h"
+#include "rccnames.h"
+
+rcc_ui_internal rccUiCreateInternal(rcc_ui_context ctx) {
+ return NULL;
+}
+
+void rccUiFreeInternal(rcc_ui_context ctx) {
+}
+
+rcc_ui_widget rccUiMenuCreateWidget(rcc_ui_menu_context ctx) {
+ return NULL;
+}
+
+void rccUiMenuDestroyWidget(rcc_ui_menu_context ctx) {
+}
+
+rcc_ui_id rccUiMenuGet(rcc_ui_menu_context ctx) {
+ GtkWidget *menu;
+
+ if (!ctx) return (rcc_ui_id)-1;
+
+ if (ctx->type == RCC_UI_MENU_OPTION)
+ return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ctx->widget));
+
+ menu = gtk_option_menu_get_menu(ctx->widget);
+ return g_list_index(GTK_MENU_SHELL(menu)->children, gtk_menu_get_active(GTK_MENU(menu)));
+}
+
+int rccUiMenuSet(rcc_ui_menu_context ctx, rcc_ui_id id) {
+ if (!ctx) return -1;
+
+ switch (ctx->type) {
+ case RCC_UI_MENU_OPTION:
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ctx->widget),id);
+ break;
+ default:
+ gtk_option_menu_set_history(ctx->widget, id);
+ }
+
+ return 0;
+}
+
+
+static int rccGtkMenuLanguageCB(GtkWidget * w, gpointer item) {
+ rccUiRestoreLanguage(((rcc_ui_menu_context)item)->uictx);
+}
+
+int rccUiMenuConfigureWidget(rcc_ui_menu_context ctx) {
+ unsigned int i;
+
+ rcc_context rccctx;
+ rcc_ui_context uictx;
+
+ rcc_language_config config;
+ rcc_language_ptr *languages;
+ rcc_language_id language_id;
+
+ rcc_charset *charsets;
+ rcc_engine_ptr *engines;
+
+ rcc_charset_id charset_id;
+ rcc_engine_id engine_id;
+
+ GtkWidget *list, *item, *menu;
+
+ if (!ctx) return -1;
+
+ uictx = ctx->uictx;
+ rccctx = uictx->rccctx;
+
+ switch (ctx->type) {
+ case RCC_UI_MENU_LANGUAGE:
+ list = gtk_menu_new();
+
+ languages=rccGetLanguageList(rccctx);
+ for (i=0; languages[i]; i++) {
+ item = gtk_menu_item_new_with_label(rccUiGetLanguageName(uictx, languages[i]->sn));
+ gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(rccGtkMenuLanguageCB), ctx);
+ gtk_menu_append(GTK_MENU(list), item);
+ gtk_widget_show(item);
+ }
+
+ language_id = rccGetSelectedLanguage(rccctx);
+ if (language_id < 0) language_id = 0;
+
+ if (ctx->widget) menu = ctx->widget;
+ else {
+ menu = gtk_option_menu_new();
+ ctx->widget = menu;
+ }
+ gtk_option_menu_remove_menu(GTK_OPTION_MENU(menu));
+ gtk_option_menu_set_menu(GTK_OPTION_MENU(menu), list);
+ gtk_option_menu_set_history(GTK_OPTION_MENU(menu), language_id);
+
+ return 0;
+ break;
+ case RCC_UI_MENU_CHARSET:
+
+ list = gtk_menu_new();
+
+ language_id = (rcc_language_id)rccUiMenuGet(uictx->language);
+ charsets = rccGetCharsetList(rccctx, language_id);
+
+ for (i=0;charsets[i];i++) {
+ list = gtk_menu_item_new_with_label(charsets[i]);
+ gtk_widget_show(item);
+ gtk_menu_append(GTK_MENU(list), item);
+ }
+
+ if (ctx->widget) menu = ctx->widget;
+ else {
+ menu = gtk_option_menu_new();
+ ctx->widget = menu;
+ }
+
+ gtk_option_menu_remove_menu(GTK_OPTION_MENU(menu));
+ gtk_option_menu_set_menu(GTK_OPTION_MENU(menu), list);
+
+ config = rccGetConfig(rccctx, language_id);
+ charset_id = rccConfigGetSelectedCharset(config, (rcc_class_id)ctx->id);
+ if (charset_id < 0) charset_id = 0;
+ gtk_option_menu_set_history(GTK_OPTION_MENU(menu), charset_id);
+ break;
+ case RCC_UI_MENU_ENGINE:
+ list = gtk_menu_new();
+
+ language_id = (rcc_language_id)rccUiMenuGet(uictx->language);
+ engines = rccGetEngineList(rccctx, language_id);
+ for (i=0;engines[i];i++) {
+ list = gtk_menu_item_new_with_label(engines[i]->title);
+ gtk_widget_show(item);
+ gtk_menu_append(GTK_MENU(list), item);
+ }
+
+ if (ctx->widget) menu = ctx->widget;
+ else {
+ menu = gtk_option_menu_new();
+ ctx->widget = menu;
+ }
+
+ gtk_option_menu_remove_menu(GTK_OPTION_MENU(menu));
+ gtk_option_menu_set_menu(GTK_OPTION_MENU(menu), list);
+
+ config = rccGetConfig(rccctx, language_id);
+ engine_id = rccConfigGetSelectedEngine(config);
+ if (engine_id < 0) engine_id = 0;
+ gtk_option_menu_set_history(GTK_OPTION_MENU(menu), engine_id);
+
+ break;
+ case RCC_UI_MENU_OPTION:
+ item = gtk_check_button_new_with_label(rccUiGetOptionName(uictx, (rcc_option)ctx->id));
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(item), rccGetOption(rccctx, (rcc_option)ctx->id));
+ break;
+ }
+
+ return 0;
+}
+
+
+rcc_ui_box rccUiBoxCreate(rcc_ui_menu_context ctx, const char *title) {
+ GtkWidget *hbox, *label;
+ hbox = gtk_hbox_new(FALSE, 10);
+ gtk_container_border_width(GTK_CONTAINER(hbox), 5);
+ if (ctx->type != RCC_UI_MENU_OPTION) {
+ label = gtk_label_new(title);
+ gtk_widget_set_usize(label, 120, 17);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+ }
+ gtk_box_pack_start(GTK_BOX(hbox), (GtkWidget*)ctx->widget, TRUE, TRUE, 0);
+ return (rcc_ui_box)hbox;
+}
+
+rcc_ui_frame rccUiFrameCreate(rcc_ui_context ctx, const char *title) {
+ GtkWidget *frame, *box;
+ frame = gtk_frame_new(title?title:"");
+ gtk_container_border_width(GTK_CONTAINER(frame), 5);
+
+ box = gtk_vbox_new(FALSE, 3);
+ gtk_container_add(GTK_CONTAINER(frame), box);
+
+ return (rcc_ui_frame)frame;
+}
+
+int rccUiFrameAdd(rcc_ui_frame frame, rcc_ui_box box) {
+ GtkWidget *vbox;
+
+ vbox = gtk_container_get_toplevels()->data;
+ gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(box), FALSE, FALSE, 0);
+ return 0;
+}
+
+rcc_ui_page rccUiPageCreate(rcc_ui_context ctx, const char *title) {
+ return (rcc_ui_page)gtk_vbox_new(FALSE, 0);
+}
+
+int rccUiPageAdd(rcc_ui_page page, rcc_ui_frame frame) {
+ if ((!page)||(!frame)) return -1;
+ gtk_box_pack_start(GTK_BOX(page), GTK_WIDGET(frame), FALSE, FALSE, 0);
+ return 0;
+}
diff --git a/ui/internal.h b/ui/internal.h
new file mode 100644
index 0000000..afc0a08
--- /dev/null
+++ b/ui/internal.h
@@ -0,0 +1,71 @@
+#ifndef _RCC_UI_INTERNAL_H
+#define _RCC_UI_INTERNAL_H
+
+#include "../src/librcc.h"
+#include "librccui.h"
+
+typedef unsigned int rcc_ui_id;
+typedef void *rcc_ui_internal;
+typedef void *rcc_ui_menu_internal;
+
+enum rcc_ui_menu_type_t {
+ RCC_UI_MENU_LANGUAGE = 0,
+ RCC_UI_MENU_CHARSET,
+ RCC_UI_MENU_ENGINE,
+ RCC_UI_MENU_OPTION,
+ RCC_UI_MENU_MAX
+};
+typedef enum rcc_ui_menu_type_t rcc_ui_menu_type;
+
+struct rcc_ui_menu_context_t {
+ rcc_ui_widget widget;
+ rcc_ui_box box;
+
+ rcc_ui_context uictx;
+ rcc_ui_menu_type type;
+ rcc_ui_id id;
+
+ rcc_ui_menu_internal internal;
+};
+typedef struct rcc_ui_menu_context_t rcc_ui_menu_context_s;
+typedef struct rcc_ui_menu_context_t *rcc_ui_menu_context;
+
+struct rcc_ui_context_t {
+ rcc_context rccctx;
+
+ rcc_ui_menu_context language;
+ rcc_ui_menu_context engine;
+ rcc_ui_menu_context *charsets;
+ rcc_ui_menu_context *options;
+
+ rcc_ui_internal internal;
+
+ rcc_language_name *language_names;
+ rcc_option_name *option_names;
+
+ rcc_ui_frame language_frame;
+ rcc_ui_frame charset_frame;
+ rcc_ui_frame engine_frame;
+
+ rcc_ui_page page;
+};
+typedef struct rcc_ui_context_t rcc_ui_contexts_s;
+
+
+rcc_ui_internal rccUiCreateInternal(rcc_ui_context ctx);
+void rccUiFreeInternal(rcc_ui_context ctx);
+
+rcc_ui_widget rccUiMenuCreateWidget(rcc_ui_menu_context ctx);
+void rccUiMenuDestroyWidget(rcc_ui_menu_context ctx);
+int rccUiMenuConfigureWidget(rcc_ui_menu_context ctx);
+
+rcc_ui_id rccUiMenuGet(rcc_ui_menu_context ctx);
+int rccUiMenuSet(rcc_ui_menu_context ctx, rcc_ui_id id);
+
+rcc_ui_box rccUiBoxCreate(rcc_ui_menu_context ctx, const char *title);
+rcc_ui_frame rccUiFrameCreate(rcc_ui_context ctx, const char *title);
+int rccUiFrameAdd(rcc_ui_frame frame, rcc_ui_box box);
+rcc_ui_page rccUiPageCreate(rcc_ui_context ctx, const char *title);
+int rccUiPageAdd(rcc_ui_page page, rcc_ui_frame frame);
+
+#endif /* _RCC_UI_INTERNAL_H */
diff --git a/ui/librccui.c b/ui/librccui.c
new file mode 100644
index 0000000..0700b8b
--- /dev/null
+++ b/ui/librccui.c
@@ -0,0 +1,387 @@
+#include <stdio.h>
+#include "../src/rccconfig.h"
+#include "internal.h"
+#include "rccnames.h"
+
+#define RCC_UI_LOCK_CODE 0x1111
+
+static rcc_ui_menu_context rccUiMenuCreateContext(rcc_ui_menu_type type, rcc_ui_id id, rcc_ui_context uictx) {
+ rcc_ui_menu_context ctx;
+ if ((!uictx)||(type>RCC_UI_MENU_MAX)) return NULL;
+
+ ctx = (rcc_ui_menu_context)malloc(sizeof(rcc_ui_menu_context_s));
+ if (!ctx) return ctx;
+
+ ctx->uictx = uictx;
+ ctx->type = type;
+ ctx->id = id;
+
+ ctx->widget = rccUiMenuCreateWidget(ctx);
+ ctx->box = NULL;
+
+ return ctx;
+}
+
+static void rccUiMenuFreeContext(rcc_ui_menu_context ctx) {
+ if (!ctx) return;
+ rccUiMenuFreeWidget(ctx);
+ free(ctx);
+}
+
+rcc_ui_context rccUiCreateContext(rcc_context rccctx) {
+ int err = 0;
+ unsigned int i;
+
+ rcc_class_ptr *classes;
+ rcc_ui_context ctx;
+ rcc_ui_menu_context *charsets;
+ rcc_ui_menu_context *options;
+
+ if (!rccctx) return NULL;
+
+ err = rccLockConfiguration(rccctx, RCC_UI_LOCK_CODE);
+ if (err) return NULL;
+
+ classes = rccGetClassList(rccctx);
+ for (i=0; classes[i]; i++);
+
+ ctx = (rcc_ui_context)malloc(sizeof(struct rcc_ui_context_t));
+ charsets = (rcc_ui_menu_context*)malloc((i+1)*sizeof(rcc_ui_menu_context));
+ options = (rcc_ui_menu_context*)malloc((RCC_MAX_OPTIONS)*sizeof(rcc_ui_menu_context));
+ if ((!ctx)||(!charsets)) {
+ if (ctx) free(ctx);
+ if (charsets) free(charsets);
+ rccUnlockConfiguration(rccctx, RCC_UI_LOCK_CODE);
+ return NULL;
+ }
+
+ ctx->language_frame = NULL;
+ ctx->charset_frame = NULL;
+ ctx->engine_frame = NULL;
+ ctx->page = NULL;
+
+ ctx->charsets = charsets;
+ ctx->rccctx = rccctx;
+
+ ctx->language_names = rcc_default_language_names;
+ ctx->option_names = rcc_default_option_names;
+
+ ctx->internal = rccUiCreateInternal(ctx);
+
+ ctx->language = rccUiMenuCreateContext(RCC_UI_MENU_LANGUAGE, 0, ctx);
+ ctx->engine = rccUiMenuCreateContext(RCC_UI_MENU_ENGINE, 0, ctx);
+ for (i=0; classes[i]; i++) {
+ charsets[i] = rccUiMenuCreateContext(RCC_UI_MENU_CHARSET, i, ctx);
+ if (!charsets[i]) err = 1;
+ }
+ charsets[i] = NULL;
+ for (i=0; i<RCC_MAX_OPTIONS; i++) {
+ options[i] = rccUiMenuCreateContext(RCC_UI_MENU_OPTION, i, ctx);
+ if (!options[i]) err = 1;
+ }
+
+ if ((err)||(!ctx->language)||(!ctx->engine)) {
+ rccUiFreeContext(ctx);
+ return NULL;
+ }
+
+ return ctx;
+}
+
+void rccUiFreeContext(rcc_ui_context ctx) {
+ unsigned int i;
+ rcc_class_ptr *classes;
+
+ if (!ctx) return;
+
+ rccUiFreeInternal(ctx);
+
+ if (ctx->charsets) {
+ classes = rccGetClassList(ctx->rccctx);
+ for (i=0; classes[i]; i++)
+ if (ctx->charsets[i]) rccUiMenuFreeContext(ctx->charsets[i]);
+ free(ctx->charsets);
+ }
+ if (ctx->options) {
+ for (i=0;i<RCC_MAX_OPTIONS;i++) {
+ if (ctx->options[i]) rccUiMenuFreeContext(ctx->options[i]);
+ }
+ free(ctx->options);
+ }
+ if (ctx->engine) rccUiMenuFreeContext(ctx->engine);
+ if (ctx->language) rccUiMenuFreeContext(ctx->language);
+
+ rccUnlockConfiguration(ctx->rccctx, RCC_UI_LOCK_CODE);
+
+ free(ctx);
+}
+
+int rccUiSetLanguageNames(rcc_ui_context ctx, rcc_language_name *names) {
+ if (!ctx) return -1;
+
+ if (names) ctx->language_names = names;
+ else ctx->language_names = rcc_default_language_names;
+ return 0;
+}
+
+int rccUiSetOptionNames(rcc_ui_context ctx, rcc_option_name *names) {
+ if (!ctx) return -1;
+
+ if (names) ctx->option_names = names;
+ else ctx->option_names = rcc_default_option_names;
+ return 0;
+}
+
+
+int rccUiRestoreLanguage(rcc_ui_context ctx) {
+ unsigned int i;
+ rcc_class_ptr *classes;
+ rcc_context rccctx;
+
+ if (!ctx) return -1;
+
+ rccctx = ctx->rccctx;
+
+ rccUiMenuSet(ctx->engine, (rcc_ui_id)rccGetSelectedEngine(rccctx));
+
+ for (i=0;i<RCC_MAX_OPTIONS;i++)
+ rccUiMenuSet(ctx->options[i], rccGetOption(rccctx, (rcc_option)i));
+
+ classes = rccGetClassList(rccctx);
+ for (i=0;classes[i];i++)
+ rccUiMenuSet(ctx->charsets[i], rccGetSelectedCharset(rccctx, (rcc_class_id)i));
+
+ return 0;
+}
+
+int rccUiRestore(rcc_ui_context ctx) {
+ rcc_language_id language_id;
+
+ if (!ctx) return -1;
+
+ language_id = rccGetSelectedLanguage(ctx->rccctx);
+ rccUiMenuSet(ctx->language, (rcc_ui_id)language_id);
+ return 0;
+}
+
+int rccUiUpdate(rcc_ui_context ctx) {
+ unsigned int i;
+ rcc_class_ptr *classes;
+ rcc_context rccctx;
+
+ if (!ctx) return -1;
+
+ rccctx = ctx->rccctx;
+
+ rccSetLanguage(rccctx, (rcc_language_id)rccUiMenuGet(ctx->language));
+
+ for (i=0;i<RCC_MAX_OPTIONS;i++)
+ rccSetOption(rccctx, (rcc_option)i, (rcc_option_value)rccUiMenuGet(ctx->options[i]));
+
+ rccSetEngine(rccctx, (rcc_language_id)rccUiMenuGet(ctx->engine));
+
+ classes = rccGetClassList(rccctx);
+ for (i=0;classes[i];i++)
+ rccSetCharset(rccctx, (rcc_class_id)i, rccUiMenuGet(ctx->charsets[i]));
+
+ return 0;
+}
+
+
+
+rcc_ui_widget rccUiGetLanguageMenu(rcc_ui_context ctx) {
+ if (!ctx) return NULL;
+
+ if (rccUiMenuConfigureWidget(ctx->language)) return NULL;
+ return ctx->language->widget;
+}
+
+rcc_ui_widget rccUiGetCharsetMenu(rcc_ui_context ctx, rcc_class_id id) {
+ rcc_charset *charsets;
+ unsigned int i;
+
+ if ((!ctx)||(id<0)) return NULL;
+
+ charsets = rccGetCurrentCharsetList(ctx->rccctx);
+ for (i=0;charsets[i];i++);
+ if (id>=i) return NULL;
+
+ if (rccUiMenuConfigureWidget(ctx->charsets[i])) return NULL;
+ return ctx->charsets[i]->widget;
+}
+
+
+rcc_ui_widget rccUiGetEngineMenu(rcc_ui_context ctx) {
+ if (!ctx) return NULL;
+
+ if (rccUiMenuConfigureWidget(ctx->engine)) return NULL;
+ return ctx->engine->widget;
+}
+
+
+rcc_ui_widget rccUiGetOptionMenu(rcc_ui_context ctx, rcc_option option) {
+ if ((!ctx)||(option<0)||(option>RCC_MAX_OPTIONS)) return NULL;
+
+ if (rccUiMenuConfigureWidget(ctx->options[option])) return NULL;
+ return ctx->options[option]->widget;
+}
+
+
+rcc_ui_box rccUiGetLanguageBox(rcc_ui_context ctx, const char *title) {
+ rcc_ui_widget language;
+
+ if (!ctx) return NULL;
+ if (ctx->language->box) return ctx->language->box;
+
+ language = rccUiGetLanguageMenu(ctx);
+ if (!language) return NULL;
+
+ ctx->language->box = rccUiBoxCreate(ctx->language, title);
+ return ctx->language->box;
+}
+
+rcc_ui_box rccUiGetCharsetBox(rcc_ui_context ctx, rcc_class_id id, const char *title) {
+ unsigned int i;
+ rcc_class_ptr *classes;
+ rcc_ui_widget charset;
+
+ if (!ctx) return NULL;
+
+ classes = rccGetClassList(ctx->rccctx);
+ for (i=0; classes[i]; i++);
+ if (id>=i) return NULL;
+
+ if (ctx->charsets[id]->box) return ctx->charsets[id]->box;
+
+
+ charset = rccUiGetCharsetMenu(ctx, id);
+ if (!charset) return NULL;
+
+ ctx->charsets[id]->box = rccUiBoxCreate(ctx->charsets[id], title);
+ return ctx->charsets[id]->box;
+}
+
+rcc_ui_box rccUiGetEngineBox(rcc_ui_context ctx, const char *title) {
+ rcc_ui_widget engine;
+
+ if (!ctx) return NULL;
+ if (ctx->engine->box) return ctx->engine->box;
+
+ engine = rccUiGetEngineMenu(ctx);
+ if (!engine) return NULL;
+
+ ctx->engine->box = rccUiBoxCreate(ctx->engine, title);
+ return ctx->engine->box;
+}
+
+rcc_ui_box rccUiGetOptionBox(rcc_ui_context ctx, rcc_option option, const char *title) {
+ rcc_ui_widget opt;
+
+ if ((!ctx)||(option<0)||(option>=RCC_MAX_OPTIONS)) return NULL;
+ if (ctx->options[option]->box) return ctx->options[option]->box;
+
+ opt = rccUiGetOptionMenu(ctx, option);
+ if (!opt) return NULL;
+
+ ctx->options[option]->box = rccUiBoxCreate(ctx->options[option], title);
+ return ctx->options[option]->box;
+
+}
+
+rcc_ui_frame rccUiGetLanguageFrame(rcc_ui_context ctx, const char *title) {
+ rcc_ui_frame frame;
+ rcc_ui_box language;
+
+ if (!ctx) return NULL;
+
+ if (ctx->language_frame) return ctx->language_frame;
+
+ frame = rccUiFrameCreate(ctx, title);
+ if (!frame) return NULL;
+
+ language = rccUiGetLanguageBox(ctx, title);
+ if (!language) return NULL;
+
+ rccUiFrameAdd(frame, language);
+
+ ctx->language_frame = frame;
+
+ return frame;
+}
+
+rcc_ui_frame rccUiGetCharsetsFrame(rcc_ui_context ctx, const char *title) {
+ unsigned int i;
+ rcc_class_ptr *classes;
+ rcc_ui_frame frame;
+ rcc_ui_box charset;
+
+ if (!ctx) return NULL;
+
+ if (ctx->charset_frame) return ctx->charset_frame;
+
+ frame = rccUiFrameCreate(ctx, title);
+ if (!frame) return NULL;
+
+ classes = rccGetClassList(ctx->rccctx);
+ for (i=0; classes[i]; i++) {
+ charset = rccUiGetCharsetBox(ctx, (rcc_class_id)i, classes[i]->fullname);
+ rccUiFrameAdd(frame, charset);
+ }
+
+ ctx->charset_frame = frame;
+
+ return frame;
+}
+
+
+rcc_ui_frame rccUiGetEngineFrame(rcc_ui_context ctx, const char *title) {
+ unsigned int i;
+ rcc_ui_frame frame;
+ rcc_ui_box engine;
+ rcc_ui_box opt;
+
+ if (!ctx) return NULL;
+
+ if (ctx->engine_frame) return ctx->engine_frame;
+
+ frame = rccUiFrameCreate(ctx, title);
+ if (!frame) return NULL;
+
+ engine = rccUiGetEngineBox(ctx, title);
+ rccUiFrameAdd(frame, engine);
+
+ for (i=0; i<RCC_MAX_OPTIONS; i++) {
+ opt = rccUiGetOptionBox(ctx, (rcc_option)i, rccUiGetOptionName(ctx, i));
+ rccUiFrameAdd(frame, opt);
+ }
+
+ ctx->engine_frame = frame;
+
+ return frame;
+}
+
+
+rcc_ui_page rccUiGetPage(rcc_ui_context ctx, const char *title, const char *language_title, const char *charset_title, const char *engine_title) {
+ rcc_ui_page page;
+ rcc_ui_frame frame;
+
+ if (!ctx) return NULL;
+
+ if (ctx->page) return ctx->page;
+
+ page = rccUiPageCreate(ctx, title);
+ if (!page) return NULL;
+
+ frame = rccUiGetLanguageFrame(ctx, language_title);
+ rccUiPageAdd(page, frame);
+
+ frame = rccUiGetCharsetsFrame(ctx, charset_title);
+ rccUiPageAdd(page, frame);
+
+ frame = rccUiGetEngineFrame(ctx, engine_title);
+ rccUiPageAdd(page, frame);
+
+ ctx->page = page;
+
+ return page;
+}
diff --git a/ui/librccui.h b/ui/librccui.h
new file mode 100644
index 0000000..6b114da
--- /dev/null
+++ b/ui/librccui.h
@@ -0,0 +1,46 @@
+#ifndef _LIBRCC_UI_H
+#define _LIBRCC_UI_H
+
+#include <librcc.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void *rcc_ui_widget;
+typedef void *rcc_ui_box;
+typedef void *rcc_ui_frame;
+typedef void *rcc_ui_page;
+
+typedef struct rcc_ui_context_t *rcc_ui_context;
+
+rcc_ui_context rccUiCreateContext(rcc_context rccctx);
+void rccUiFreeContext(rcc_ui_context ctx);
+int rccUiSetLanguageNames(rcc_ui_context ctx, rcc_language_name *names);
+int rccUiSetOptionNames(rcc_ui_context ctx, rcc_option_name *names);
+
+int rccUiRestoreLanguage(rcc_ui_context ctx);
+int rccUiRestore(rcc_ui_context ctx);
+int rccUiUpdate(rcc_ui_context ctx);
+
+rcc_ui_widget rccUiGetLanguageMenu(rcc_ui_context ctx);
+rcc_ui_widget rccUiGetCharsetMenu(rcc_ui_context ctx, rcc_class_id id);
+rcc_ui_widget rccUiGetEngineMenu(rcc_ui_context ctx);
+rcc_ui_widget rccUiGetOptionMenu(rcc_ui_context ctx, rcc_option option);
+
+rcc_ui_box rccUiGetLanguageBox(rcc_ui_context ctx, const char *title);
+rcc_ui_box rccUiGetCharsetBox(rcc_ui_context ctx, rcc_class_id id, const char *title);
+rcc_ui_box rccUiGetEngineBox(rcc_ui_context ctx, const char *title);
+rcc_ui_box rccUiGetOptionBox(rcc_ui_context ctx, rcc_option option, const char *title);
+
+rcc_ui_frame rccUiGetLanguageFrame(rcc_ui_context ctx, const char *title);
+rcc_ui_frame rccUiGetCharsetsFrame(rcc_ui_context ctx, const char *title);
+rcc_ui_frame rccUiGetEngineFrame(rcc_ui_context ctx, const char *title);
+
+rcc_ui_page rccUiGetPage(rcc_ui_context ctx, const char *title, const char *language_title, const char *charset_title, const char *engine_title);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBRCC_UI_H */
diff --git a/ui/rccnames.c b/ui/rccnames.c
new file mode 100644
index 0000000..e4f4b48
--- /dev/null
+++ b/ui/rccnames.c
@@ -0,0 +1,31 @@
+#include <stdio.h>
+
+#include "internal.h"
+
+const char *rccUiGetLanguageName(rcc_ui_context ctx, const char *lang) {
+ unsigned int i;
+ rcc_language_name *names;
+
+ if ((!ctx)||(!lang)) return NULL;
+
+ names = ctx->language_names;
+
+ for (i=0;names[i].sn;i++)
+ if (!strcmp(lang, names[i].sn)) return names[i].name;
+
+ return lang;
+}
+
+const char *rccUiGetOptionName(rcc_ui_context ctx, rcc_option option) {
+ unsigned int i;
+ rcc_option_name *names;
+
+ if (!ctx) return NULL;
+
+ names = ctx->option_names;
+
+ for (i=0;i<RCC_MAX_OPTIONS;i++)
+ if (names[i].option == option) return names[i].name;
+
+ return NULL;
+}
diff --git a/ui/rccnames.h b/ui/rccnames.h
new file mode 100644
index 0000000..cb23960
--- /dev/null
+++ b/ui/rccnames.h
@@ -0,0 +1,9 @@
+#ifndef _RCC_UI_NAMES_C
+#define _RCC_UI_NAMES_H
+
+
+const char *rccUiGetLanguageName(rcc_ui_context ctx, const char *lang);
+const char *rccUiGetOptionName(rcc_ui_context ctx, rcc_option option);
+
+
+#endif /* _RCC_UI_NAMES_H */