summaryrefslogtreecommitdiff
path: root/Build/source/texk/xdvik/gui/xm_prefs.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/xdvik/gui/xm_prefs.c')
-rw-r--r--Build/source/texk/xdvik/gui/xm_prefs.c590
1 files changed, 590 insertions, 0 deletions
diff --git a/Build/source/texk/xdvik/gui/xm_prefs.c b/Build/source/texk/xdvik/gui/xm_prefs.c
new file mode 100644
index 00000000000..388ef07ac12
--- /dev/null
+++ b/Build/source/texk/xdvik/gui/xm_prefs.c
@@ -0,0 +1,590 @@
+/*
+ * Copyright (c) 2004 Stefan Ulrich
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PAUL VOJTA OR ANY OTHER AUTHOR OF THIS SOFTWARE BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/*
+ * Preferences dialog for xdvik.
+ */
+
+#include "xdvi-config.h"
+#include "xdvi.h"
+
+#include "x_util.h"
+#include "xm_colorsel.h"
+#include "topic-window.h"
+#include "message-window.h"
+#include "util.h"
+#include "events.h"
+
+#include "xm_prefsP.h"
+#include "xm_prefs.h"
+
+#include "xm_prefs_appearance.h"
+#include "xm_prefs_fonts.h"
+#include "xm_prefs_helpers.h"
+#include "xm_prefs_page.h"
+#include "xm_prefs_scroll.h"
+
+/* for reverting preferences, we need access to more prototypes ... */
+#include "dvi-draw.h"
+#include "search-internal.h"
+#include "statusline.h"
+#include "xm_toolbar.h"
+#include "xm_menu.h"
+#include "pagesel.h"
+
+#ifdef MOTIF /* entire file */
+
+#include <X11/Xatom.h>
+
+#include <Xm/Xm.h>
+#include <Xm/Protocols.h>
+#include <Xm/DialogS.h>
+#include <Xm/Form.h>
+
+#define SCROLLING_DONE 0
+
+#define NUM_PREFS_TOPICS 16 /* should be ample ... */
+
+/* hmm, should maybe move these into xm_prefsP.c ... */
+void
+h_attach_below(Widget x, Widget y) {
+ if (y == NULL) {
+ /* no top widget, attach to form - could just pass NULL as XmNtopWidget, but lesstif warns in that case ... */
+ XtVaSetValues(x,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM,
+ NULL);
+ }
+ else {
+ XtVaSetValues(x,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, y,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM,
+ NULL);
+ }
+}
+
+
+static void
+initialize_items(struct topic_info *info)
+{
+ int i = 0;
+
+ info->items[i].widget = prefs_appearance(info);
+ info->items[i].topic = xstrdup("Appearance");
+ info->items[i].title = xstrdup("Change the appearance of xdvi");
+
+ i++;
+ info->items[i].widget = prefs_fonts_and_colors(info);
+ info->items[i].topic = xstrdup("Fonts and Colors");
+ info->items[i].title = xstrdup("Display of fonts and colors in DVI files");
+
+ i++;
+ info->items[i].widget = prefs_paper(info);
+ info->items[i].topic = xstrdup("Page Size");
+ info->items[i].title = xstrdup("Customize the default window and page size");
+
+#if SCROLLING_DONE /* not finished yet */
+ i++;
+ info->items[i].widget = prefs_scrolling(info);
+ info->items[i].topic = xstrdup("Scrolling");
+ info->items[i].title = xstrdup("Customize the scrolling behaviour when switching pages");
+#endif
+
+ i++;
+ info->items[i].widget = prefs_helpers(info);
+#ifdef LESSTIF_VERSION
+ /* compensate for width computation bug by adding extra whitespace at end */
+ info->items[i].topic = xstrdup("Helper Applications ");
+#else
+ info->items[i].topic = xstrdup("Helper Applications");
+#endif
+ info->items[i].title = xstrdup("External programs used by xdvi");
+
+ /* terminate */
+ i++;
+ info->items[i].widget = 0;
+ info->items[i].topic = info->items[i].title = NULL;
+
+ ASSERT(i < NUM_PREFS_TOPICS, "NUM_PREFS_TOPICS too small!");
+}
+
+void
+remove_from_deplist(struct prefs_choice *prefs, Widget w)
+{
+ size_t i;
+ Boolean found = False;
+
+ /* locate this widget */
+ for (i = 0; i < prefs->depwin_cnt; i++) {
+ if (prefs->depwin[i] == w) {
+ found = True;
+ break;
+ }
+ }
+
+ if (found) {
+ /* move later widgets down */
+ for (; i < prefs->depwin_cnt - 1; i++) {
+ prefs->depwin[i] = prefs->depwin[i + 1];
+ }
+ prefs->depwin_cnt--;
+ }
+
+#if 0
+ fprintf(stderr, "deplist after removal:\n");
+ for (i = 0; i < prefs->depwin_cnt; i++) {
+ fprintf(stderr, "%d: %p\n", i, prefs->depwin[i]);
+ }
+#endif
+}
+
+static void
+update_button(Widget button, Pixel pix)
+{
+ struct color_button_info *cinfo;
+ static XmDrawnButtonCallbackStruct cbs;
+
+ XtVaGetValues(button, XmNuserData, &cinfo, NULL);
+ cinfo->pixel = pix;
+ cbs.reason = XmCR_EXPOSE;
+ XtCallCallbacks(button, XmNexposeCallback, &cbs);
+}
+
+static void
+update_button_by_name(Pixel pix, const char *name)
+{
+ static Widget pref_shell = 0;
+ Widget button;
+
+ if (pref_shell == 0
+ && !get_widget_by_name(&pref_shell, globals.widgets.top_level, Xdvi_PREFS_DIALOG_NAME, True))
+ return;
+
+ if (get_widget_by_name(&button, pref_shell, name, True)) {
+ update_button(button, pix);
+ }
+}
+
+static Boolean
+revert_colors(Pixel fg, Pixel bg, Pixel hl)
+{
+ XColor color_data[2];
+ Boolean need_redraw = False;
+ Widget button;
+ Pixel visited, unvisited;
+
+ color_data[0].pixel = resource.fore_Pixel;
+ color_data[1].pixel = resource.back_Pixel;
+
+ str_to_pixel(globals.widgets.top_level, resource.visited_link_color, &visited);
+ str_to_pixel(globals.widgets.top_level, resource.link_color, &unvisited);
+
+ XQueryColors(DISP, G_colormap, color_data, 2);
+
+ if (fg != resource.fore_Pixel) {
+ XGCValues values;
+
+ fg_initial.r = color_data[0].red;
+ fg_initial.g = color_data[0].green;
+ fg_initial.b = color_data[0].blue;
+
+ values.foreground = resource.rule_pixel = resource.fore_Pixel;
+ XChangeGC(DISP, globals.gc.ruler, GCForeground, &values);
+
+ scanned_page = scanned_page_color = scanned_page_reset;
+
+ update_button_by_name(resource.fore_Pixel, Xdvi_FG_COLOR_BTN);
+
+ need_redraw = True;
+ }
+ if (bg != resource.back_Pixel) {
+ bg_initial.r = color_data[1].red;
+ bg_initial.g = color_data[1].green;
+ bg_initial.b = color_data[1].blue;
+
+ scanned_page = scanned_page_color = scanned_page_reset;
+
+ update_button_by_name(resource.back_Pixel, Xdvi_BG_COLOR_BTN);
+
+ need_redraw = True;
+ }
+ if (hl != resource.hl_Pixel) {
+ XGCValues values;
+ values.foreground = resource.hl_Pixel;
+ XChangeGC(DISP, globals.gc.high, GCForeground, &values);
+ /* hack to update match GC: fake change in inverted property, redraw
+ so that GC is cleared, then change inverted property back */
+ resource.match_highlight_inverted = !resource.match_highlight_inverted;
+ search_draw_inverted_regions();
+ resource.match_highlight_inverted = !resource.match_highlight_inverted;
+
+ update_button_by_name(resource.hl_Pixel, Xdvi_HL_COLOR_BTN);
+
+ need_redraw = True;
+ }
+ /* NOTE: pixels for hyperlinks are not stored anywhere; just update always: */
+ if (get_widget_by_name(&button, globals.widgets.top_level, Xdvi_VISITED_LINKS_BTN, True)) {
+ update_button(button, visited);
+ h_update_hyperlinks(button, visited); /* this already triggers a redraw */
+ }
+ if (get_widget_by_name(&button, globals.widgets.top_level, Xdvi_UNVISITED_LINKS_BTN, True)) {
+ update_button(button, unvisited);
+ h_update_hyperlinks(button, unvisited); /* this already triggers a redraw */
+ }
+ return need_redraw;
+}
+
+static void
+revert_resources(void)
+{
+ Pixel curr_fg = resource.fore_Pixel;
+ Pixel curr_bg = resource.back_Pixel;
+ Pixel curr_hl = resource.hl_Pixel;
+ Boolean need_redraw = False;
+
+ /* save some old values */
+ int save_shrink = resource.shrinkfactor;
+
+ reload_app_resources();
+
+ /* revert from saved values */
+ resource.use_color = globals.curr_use_color;
+ resource.gamma = globals.curr_gamma;
+ resource.paper = globals.curr_paper;
+ resource.shrinkfactor = save_shrink;
+ do_set_shrinkfactor(resource.shrinkfactor, True);
+
+ update_preferences_darkness();
+
+ /* revert expert mode */
+ if (resource.expert)
+ resource.expert_mode = XPRT_SHOW_NONE;
+ update_expert_mode();
+
+ toggle_statusline();
+#ifndef MOTIF
+ if (!BROKEN_RECONFIG)
+ toggle_scrollbars();
+#else
+ toggle_scrollbars();
+#endif
+
+#ifdef MOTIF
+ toggle_pagelist();
+ toggle_toolbar();
+ toggle_menubar();
+#else
+ toggle_buttons();
+#endif
+
+ /* reset tooltips_wait_period, similar to TipAddWidget() in Tip.c */
+ resource.tooltips_wait_period = resource.tooltips_wait_period_bak;
+ if (resource.tooltips_wait_period < 0) {
+ resource.show_tooltips = False;
+ }
+ else if (!resource.show_tooltips) {
+ if (resource.tooltips_wait_period == 0)
+ resource.tooltips_wait_period = -1;
+ else
+ resource.tooltips_wait_period = -resource.tooltips_wait_period;
+ }
+
+ update_preferences_expert();
+ update_preferences_tooltips();
+ update_preferences_search();
+
+ update_preferences_color();
+ update_preferences_hyperlinks();
+
+ update_preferences_windowsize();
+ update_preferences_shrink();
+ update_preferences_paper();
+
+ update_preferences_helpers();
+
+ need_redraw |= revert_colors(curr_fg, curr_bg, curr_hl);
+
+/* if (need_redraw) */
+ /* just reload it always, there's too many exceptions ...
+ redraw isn't always sufficient if file has colors. */
+ globals.ev.flags |= EV_RELOAD;
+
+}
+
+/* add widget w to list of dependent windows */
+void
+add_to_deplist(struct prefs_choice *prefs, Widget w)
+{
+#if 0
+ size_t i;
+#endif
+ prefs->depwin = xrealloc(prefs->depwin,
+ (prefs->depwin_cnt + 1) * sizeof *(prefs->depwin));
+ prefs->depwin[prefs->depwin_cnt] = w;
+ prefs->depwin_cnt++;
+
+#if 0
+ fprintf(stderr, "deplist after adding:\n");
+ for (i = 0; i < prefs->depwin_cnt; i++) {
+ fprintf(stderr, "%lu: %p\n", (unsigned long)i, prefs->depwin[i]);
+ }
+#endif
+}
+
+static void
+reread_prefs_cb(Window w)
+{
+ if (w != XtWindow(globals.widgets.top_level)) {
+ XChangeProperty(DISP, w,
+ atom_reread_prefs(), atom_reread_prefs(), 8,
+ PropModeReplace,
+ /* dummy values, since all the other instance needs to do is
+ reread the ~/.xdvirc.tmp file */
+ (unsigned char *)"Y", 1);
+ }
+}
+
+static void
+apply_prefs_cb(XtPointer arg)
+{
+ struct topic_info *info = (struct topic_info *)arg;
+ struct prefs_choice *prefs = (struct prefs_choice *)info->data;
+ size_t i;
+ Widget colorsel;
+
+ if (get_widget_by_name(&colorsel, globals.widgets.top_level, Xdvi_COLOR_DIALOG_NAME, False)) {
+ XtPopdown(XtParent(colorsel));
+ }
+
+ /* pop down dependent windows */
+ TRACE_GUI((stderr, "window count: %lu\n", (unsigned long)prefs->depwin_cnt));
+ for (i = 0; i < prefs->depwin_cnt; i++) {
+ TRACE_GUI((stderr, "popping down %lu: %p", (unsigned long)i, (void *)(prefs->depwin[i])));
+ if (XtIsRealized(prefs->depwin[i])) {
+ XtCallCallbacks(prefs->depwin[i], XmNcancelCallback, NULL);
+ XSync(DISP, True); /* wait for server to catch up */
+ if (XtIsRealized(prefs->depwin[i])) {
+ TRACE_GUI((stderr, "calling XmNokCallback of %lu: %p", (unsigned long)i, (void *)(prefs->depwin[i])));
+ XtCallCallbacks(prefs->depwin[i], XmNokCallback, NULL);
+ }
+ }
+ }
+ free(prefs->depwin);
+ prefs->depwin = NULL;
+ prefs->depwin_cnt = 0;
+
+ if (prefs->db == NULL) /* callback invoked multiple times? */
+ return;
+
+ merge_into_user_db(prefs->db); /* this destroys prefs->db */
+ prefs->db = NULL;
+
+ /* remember some current values */
+ free(globals.curr_paper);
+ if (resource.paper != NULL)
+ globals.curr_paper = xstrdup(resource.paper);
+
+ free(globals.curr_editor);
+ if (resource.editor != NULL)
+ globals.curr_editor = xstrdup(resource.editor);
+
+ free(globals.curr_browser);
+ if (resource.browser != NULL)
+ globals.curr_browser = xstrdup(resource.browser);
+
+/* fprintf(stderr, "set curr_browser to: |%s|\n", globals.curr_browser); */
+/* fprintf(stderr, "set curr_editor to: |%s|\n", globals.curr_editor); */
+
+ if (get_xdvi_window_id(False, NULL) && save_user_preferences(False)) {
+ /* if other instances of xdvi are running, make them reread the
+ changed preferences by writing them to ~/.xdvirc.tmp and having
+ them read that file; otherwise they would overwrite the file if
+ user quits them after the current instance.
+ */
+ get_xdvi_window_id(False, reread_prefs_cb);
+ }
+}
+
+static void
+revert_prefs_cb(XtPointer arg)
+{
+ struct topic_info *info = (struct topic_info *)arg;
+ struct prefs_choice *prefs = (struct prefs_choice *)info->data;
+ size_t i;
+
+ /* pop down dependent windows */
+ TRACE_GUI((stderr, "window count: %lu", (unsigned long)prefs->depwin_cnt));
+ for (i = 0; i < prefs->depwin_cnt; i++) {
+ TRACE_GUI((stderr, "popping down %lu: %p", (unsigned long)i, (void *)(prefs->depwin[i])));
+ if (XtIsRealized(prefs->depwin[i])) {
+ XtCallCallbacks(prefs->depwin[i], XmNcancelCallback, NULL);
+ XSync(DISP, True); /* wait for server to catch up */
+ if (XtIsRealized(prefs->depwin[i])) {
+ TRACE_GUI((stderr, "calling XmNokCallback of %lu: %p", (unsigned long)i, (void *)(prefs->depwin[i])));
+ XtCallCallbacks(prefs->depwin[i], XmNokCallback, NULL);
+ }
+ }
+ }
+ free(prefs->depwin);
+ prefs->depwin = NULL;
+ prefs->depwin_cnt = 0;
+
+ if (prefs->db == NULL) { /* callback invoked multiple times, or prefs not changed */
+ return;
+ }
+
+ revert_resources();
+
+ XrmDestroyDatabase(prefs->db);
+ prefs->db = NULL;
+}
+
+static void
+save_prefs_exit(XtPointer arg)
+{
+ struct topic_info *info = (struct topic_info *)arg;
+ apply_prefs_cb(info);
+ XtPopdown(info->shell);
+ XSync(DISP, False);
+ xdvi_exit(EXIT_SUCCESS);
+}
+
+static void
+no_save_prefs_exit(XtPointer arg)
+{
+ struct topic_info *info = (struct topic_info *)arg;
+ revert_prefs_cb(info);
+ XtPopdown(info->shell);
+ XSync(DISP, False);
+ xdvi_exit(EXIT_SUCCESS);
+}
+
+static void
+close_prefs_exit(Widget w, XtPointer arg)
+{
+ struct topic_info *info = (struct topic_info *)arg;
+ struct prefs_choice *prefs = (struct prefs_choice *)info->data;
+/* Widget dialog; */
+/* if (get_widget_by_name(&dialog, w, Xdvi_MESSAGE_DIALOG_NAME, True)) { */
+/* fprintf(stderr, "!!!!!!!!! removing window from deplist!\n"); */
+/* remove_from_deplist(prefs, dialog); */
+/* } */
+
+ remove_from_deplist(prefs, w);
+
+}
+
+Boolean
+preferences_changed(void)
+{
+ Widget prefs_shell = 0, topic_pane = 0;
+
+ if (get_widget_by_name(&prefs_shell, globals.widgets.top_level, "preferences_window", False)
+ && get_widget_by_name(&topic_pane, prefs_shell, "topic_pane", False)) {
+ struct topic_info *info = NULL;
+ struct prefs_choice *prefs = NULL;
+
+ XtVaGetValues(topic_pane, XmNuserData, &info, NULL);
+ if (info == NULL) {
+ return False;
+ }
+ prefs = (struct prefs_choice *)info->data;
+ if (prefs->db != NULL) { /* prefs changed */
+
+ Widget popup = choice3_dialog(prefs_shell,
+ MSG_QUESTION, NULL,
+#ifndef MOTIF
+ NULL,
+#endif
+ close_prefs_exit, info, /* pre_callbacks */
+ "Save and Exit", save_prefs_exit, info,
+ "Exit, don't Save", no_save_prefs_exit, info,
+ "Cancel", NULL, NULL,
+ "Preferences have been changed, but not saved yet. "
+ "Save them now?");
+ add_to_deplist(prefs, popup);
+ return True;
+ }
+ }
+
+ return False;
+}
+
+void
+popup_preferences_dialog(Widget parent, int arg)
+{
+ static Widget preferences_shell = 0;
+ static struct topic_info info;
+ static struct topic_item items[NUM_PREFS_TOPICS];
+ static struct prefs_choice *prefs = NULL;
+
+ if (preferences_shell == 0) { /* called 1st time; create widget */
+ info.ok_callback = apply_prefs_cb;
+ info.cancel_callback = revert_prefs_cb;
+ info.items = items;
+/* info.items_size = NUM_PREFS_TOPICS; */
+
+ prefs = xmalloc(sizeof *prefs);
+ prefs->depwin_cnt = 0;
+ prefs->depwin = NULL;
+/* prefs->orig = orig_prefs; */
+ /* apply_prefs_cb/revert_prefs_cb are responsible for copying
+ the changed preferences into the current preferences as
+ appropriate, and free()ing prefs.changed */
+/* prefs->changed = xmalloc(sizeof *(prefs->changed)); */
+/* copy_resources(orig_prefs, prefs->changed); */
+ prefs->db = NULL; /* XrmGetStringDatabase(""); */
+ info.data = prefs;
+
+ preferences_shell = create_topic_window(parent,
+ "xdvik: Preferences",
+ Xdvi_PREFS_DIALOG_NAME,
+ &info,
+ initialize_items,
+ "OK", "Cancel");
+ info.shell = preferences_shell;
+ center_window(preferences_shell, parent);
+ select_topic(&info, 0);
+ }
+
+ if (arg >= 0)
+ select_topic(&info, arg);
+
+ XtPopup(preferences_shell, XtGrabNone);
+
+ if (resource.no_init_file) {
+ popup_message(preferences_shell,
+ MSG_WARN,
+ NULL,
+ "You specified the resource `noInitFile' or the `-q' command-line option. "
+ "Any preferences that you set in this dialog will be lost when you exit xdvi.");
+ }
+}
+
+#else
+/* silence `empty compilation unit' warnings */
+static void bar(void); static void foo() { bar(); } static void bar(void) { foo(); }
+#endif /* MOTIF */