Back to index

tetex-bin  3.0
xm_colorsel.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2004 Stefan Ulrich
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a copy
00005  * of this software and associated documentation files (the "Software"), to
00006  * deal in the Software without restriction, including without limitation the
00007  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
00008  * sell copies of the Software, and to permit persons to whom the Software is
00009  * furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included in
00012  * all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00017  * PAUL VOJTA OR ANY OTHER AUTHOR OF THIS SOFTWARE BE LIABLE FOR ANY CLAIM,
00018  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00020  * OTHER DEALINGS IN THE SOFTWARE.
00021  *
00022  */
00023 
00024 /*
00025  * Color selector window showing a range of colors, and sliders to customize them.
00026  * Heavily influenced by color_slide.c from ch. 13 of O'Reilly's Motif Programming Manual 1.2.
00027  */
00028 
00029 #include "xdvi-config.h"
00030 #include "xdvi.h"
00031 
00032 #include "Tip.h"
00033 #include "x_util.h"
00034 #include "xm_colorsel.h"
00035 #include "xm_prefsP.h"
00036 #include "xm_prefs.h"
00037 #include "events.h"
00038 #include "dvi-draw.h"
00039 #include "util.h"
00040 #include "topic-window.h"
00041 #include "search-internal.h"
00042 
00043 #ifdef MOTIF /* entire file */
00044 
00045 #include <X11/Xatom.h>
00046 
00047 #include <Xm/Xm.h>
00048 #include <Xm/Protocols.h>
00049 #include <Xm/DialogS.h>
00050 #include <Xm/LabelG.h>
00051 #include <Xm/PushB.h>
00052 #include <Xm/Form.h>
00053 #include <Xm/PanedW.h>
00054 #include <Xm/DrawnB.h>
00055 #include <Xm/RowColumn.h>
00056 #include <Xm/Scale.h>
00057 #include <Xm/SelectioB.h>
00058 # include <Xm/AtomMgr.h>
00059 
00060 #include <Xm/MwmUtil.h>
00061 
00062 #define ROWS 7
00063 #define COLS 10
00064 
00065 /* for passing around information - no global data here ;-) */
00066 struct color_info {
00067     XColor new_color;
00068     Widget tooltip;
00069     Widget new_sample;
00070     Widget r_scale;
00071     Widget g_scale;
00072     Widget b_scale;
00073     struct color_button_info *button_info;
00074 };
00075 
00076 /*
00077  * These are the colors of the GTK/Mozilla color picker
00078  * (see e.g. http://lxr.mozilla.org/mozilla/source/toolkit/content/widgets/colorpicker.xml)
00079  * which has the colors more or less sorted by columns.
00080  * It's terminated by NULL just in case the table gets out of sync with
00081  * the row/column number.
00082  */
00083 static const char *colors[] = {
00084     /* column 1 */
00085     "#FFFFFF", "#CCCCCC", "#C0C0C0", "#999999", "#666666", "#333333", "#000000",
00086     /* column 2 */
00087     "#FFCCCC", "#FF6666", "#FF0000", "#CC0000", "#990000", "#660000", "#330000",
00088     /* column 3 */
00089     "#FFCC99", "#FF9966", "#FF9900", "#FF6600", "#CC6600", "#993300", "#663300",
00090     /* column 4 */
00091     "#FFFF99", "#FFFF66", "#FFCC66", "#FFCC33", "#CC9933", "#996633", "#663333",
00092     /* column 5 */
00093     "#FFFFCC", "#FFFF33", "#FFFF00", "#FFCC00", "#999900", "#666600", "#333300",
00094     /* column 6 */
00095     "#99FF99", "#66FF99", "#33FF33", "#33CC00", "#009900", "#006600", "#003300",
00096     /* column 7 */
00097     "#99FFFF", "#33FFFF", "#66CCCC", "#00CCCC", "#339999", "#336666", "#003333",
00098     /* column 8 */
00099     "#CCFFFF", "#66FFFF", "#33CCFF", "#3366FF", "#3333FF", "#000099", "#000066",
00100     /* column 9 */
00101     "#CCCCFF", "#9999FF", "#6666CC", "#6633FF", "#6600CC", "#333399", "#330099",
00102     /* column 10 */
00103     "#FFCCFF", "#FF99FF", "#CC66CC", "#CC33CC", "#993399", "#663366", "#330033",
00104     /* safety */
00105     NULL
00106 };
00107 
00108 #define MOTIF 1
00109 
00110 static void
00111 popdown_cb(Widget widget, XtPointer client_data, XtPointer call_data)
00112 {
00113     Widget dialog;
00114     struct prefs_choice *prefs = (struct prefs_choice *)client_data;
00115 
00116     UNUSED(call_data);
00117 
00118     ASSERT(prefs != NULL, "user_data in popdown_cb musn't be NULL!");
00119     if (get_widget_by_name(&dialog, widget, Xdvi_COLOR_DIALOG_NAME, True)) {
00120 /*     fprintf(stderr, "popdown!\n"); */
00121        remove_from_deplist(prefs, dialog);
00122        XtUnmanageChild(dialog);
00123     }
00124 }
00125 
00126 static void
00127 popdown_apply_cb(Widget widget, XtPointer client_data, XtPointer call_data)
00128 {
00129     struct color_info *cinfo = NULL;
00130     static XmDrawnButtonCallbackStruct cbs;
00131     struct prefs_choice *prefs = (struct prefs_choice *)client_data;
00132 
00133     UNUSED(call_data);
00134     ASSERT(prefs != NULL, "struct prefs_choice * in popdown_apply_cb mustn't be NULL!");
00135 
00136     /* To update button to new color, set its button_info color
00137        and call the button's expose callback */
00138     XtVaGetValues(widget, XmNuserData, &cinfo, NULL);
00139     ASSERT(cinfo != NULL, "XmNuserData in popdown_apply_cb musn't be NULL!");
00140     cinfo->button_info->pixel = cinfo->new_color.pixel;
00141 
00142     cbs.reason = XmCR_EXPOSE;
00143     XtCallCallbacks(cinfo->button_info->w, XmNexposeCallback, &cbs);
00144     
00145     remove_from_deplist(prefs, widget);
00146 
00147     /* Store the current setting -
00148        FIXME: better way of converting color or pixel to string? pixel_to_str() in x_util.c is broken! */
00149     store_preference(&(prefs->db), cinfo->button_info->resource_name,
00150                    "#%.2x%.2x%.2x",
00151                    cinfo->new_color.red >> 8,
00152                    cinfo->new_color.green >> 8,
00153                    cinfo->new_color.blue >> 8);
00154 
00155     /* Update the display to use the new foreground/background.
00156      * I don't really understand the entire color interface, but
00157      * apparently the following works, and nothing else I tried did ... */
00158     if (strcmp(cinfo->button_info->resource_name, "foreground") == 0) {
00159        XGCValues values;
00160 
00161        fg_initial.r = cinfo->new_color.red;
00162        fg_initial.g = cinfo->new_color.green;
00163        fg_initial.b = cinfo->new_color.blue;
00164 
00165        values.foreground = resource.fore_Pixel = resource.rule_pixel = cinfo->new_color.pixel;
00166        XChangeGC(DISP, globals.gc.ruler, GCForeground, &values);
00167 
00168        scanned_page = scanned_page_color = scanned_page_reset;
00169        globals.ev.flags |= EV_NEWPAGE;
00170 
00171     }
00172     else if (strcmp(cinfo->button_info->resource_name, "background") == 0) {
00173        bg_initial.r = cinfo->new_color.red;
00174        bg_initial.g = cinfo->new_color.green;
00175        bg_initial.b = cinfo->new_color.blue;
00176 
00177        resource.back_Pixel = cinfo->new_color.pixel;
00178        scanned_page = scanned_page_color = scanned_page_reset;
00179        globals.ev.flags |= EV_RELOAD; /* EV_NEWPAGE not sufficient with color code ... */
00180     }
00181     else if (strcmp(cinfo->button_info->resource_name, "highlight") == 0) {
00182        XGCValues values;
00183        values.foreground = resource.hl_Pixel = cinfo->new_color.pixel;
00184        XChangeGC(DISP, globals.gc.high, GCForeground, &values);
00185        /* hack to update match GC: fake change in inverted property, redraw
00186           so that GC is cleared, then change inverted property back */
00187        resource.match_highlight_inverted = !resource.match_highlight_inverted;
00188        search_draw_inverted_regions();
00189        resource.match_highlight_inverted = !resource.match_highlight_inverted;
00190        /* end of hack to update match GC */
00191        globals.ev.flags |= EV_NEWPAGE; /* force redraw */
00192     }
00193     
00194     XtUnmanageChild(widget);
00195 }
00196 
00197 static void
00198 popdown_cancel_cb(Widget widget, XtPointer client_data, XtPointer call_data)
00199 {
00200     struct prefs_choice *prefs = (struct prefs_choice *)client_data;
00201     
00202 /*     fprintf(stderr, "popdown cancel; call_data: %p!\n", call_data); */
00203     if (call_data != NULL) {
00204 /*     fprintf(stderr, "removing from deplist: %p!!!\n", prefs); */
00205        remove_from_deplist(prefs, widget);
00206     }
00207     
00208     XtUnmanageChild(widget);
00209 /*     XtPopdown(XtParent(widget)); */
00210 }
00211 
00212 static void
00213 revert_color_cb(Widget widget, XtPointer client_data, XtPointer call_data)
00214 {
00215     struct color_info *cinfo = (struct color_info *)client_data;
00216     Pixel pix;
00217     unsigned r, g, b;
00218 
00219     UNUSED(call_data);
00220     
00221     /* get color of old_sample button */
00222     XtVaGetValues(widget, XmNbackground, &pix, NULL);
00223     /*  fprintf(stderr, "Color: 0x%.6lx\n", pix); */
00224 
00225     /* use this instead of XtVaSetValues on XmNbackground so that
00226        the foreground color gets also changed appropriately. */
00227 #if XmVersion >= 1002
00228     XmChangeColor(cinfo->new_sample, pix);
00229 #else
00230     XtVaSetValues(cinfo->new_sample, XmNbackground, pix, NULL);
00231 #endif
00232 
00233     /* update sliders */
00234     XFreeColors(DISP, G_colormap, &(cinfo->new_color.pixel), 1, 0);
00235     pixel_to_color(pix, &(cinfo->new_color), DISP, G_colormap);
00236 
00237     r = cinfo->new_color.red >> 8;
00238     g = cinfo->new_color.green >> 8;
00239     b = cinfo->new_color.blue >> 8;
00240     
00241 /*      fprintf(stderr, "Pixel: 0x%.6lx\n", cinfo->new_color.pixel); */
00242 
00243     XtVaSetValues(cinfo->r_scale, XmNvalue, r, NULL);
00244     XtVaSetValues(cinfo->g_scale, XmNvalue, g, NULL);
00245     XtVaSetValues(cinfo->b_scale, XmNvalue, b, NULL);
00246 }
00247 
00248 static void
00249 show_color_cb(Widget widget, XtPointer client_data, XtPointer call_data)
00250 {
00251     struct color_info *cinfo = (struct color_info *)client_data;
00252     Pixel pix;
00253     unsigned r, g, b;
00254     
00255     UNUSED(call_data);
00256     XtVaGetValues(widget, XmNbackground, &pix, NULL);
00257 /*      fprintf(stderr, "Color: 0x%.6lx\n", pix); */
00258 
00259     /* use this instead of XtVaSetValues on XmNbackground so that
00260        the foreground color gets also changed appropriately. */
00261 #if XmVersion >= 1002
00262     XmChangeColor(cinfo->new_sample, pix);
00263 #else
00264     XtVaSetValues(cinfo->new_sample, XmNbackground, pix, NULL);
00265 #endif
00266 
00267     /* update sliders */
00268     XFreeColors(DISP, G_colormap, &(cinfo->new_color.pixel), 1, 0);
00269     pixel_to_color(pix, &(cinfo->new_color), DISP, G_colormap);
00270 
00271     r = cinfo->new_color.red >> 8;
00272     g = cinfo->new_color.green >> 8;
00273     b = cinfo->new_color.blue >> 8;
00274     
00275 /*      fprintf(stderr, "Pixel: 0x%.6lx\n", cinfo->new_color.pixel); */
00276 
00277     XtVaSetValues(cinfo->r_scale, XmNvalue, r, NULL);
00278     XtVaSetValues(cinfo->g_scale, XmNvalue, g, NULL);
00279     XtVaSetValues(cinfo->b_scale, XmNvalue, b, NULL);
00280 }
00281 
00282 static void
00283 slider_cb(Widget widget, XtPointer client_data, XtPointer call_data)
00284 {
00285     struct color_info *cinfo = (struct color_info *)client_data;
00286     XmScaleCallbackStruct *cbs = (XmScaleCallbackStruct *)call_data;
00287 
00288 /*      fprintf(stderr, "Pixel1 : 0x%.6lx\n", cinfo->new_color.pixel); */
00289     /* reuse cinfo->new_color */
00290     XFreeColors(DISP, G_colormap, &(cinfo->new_color.pixel), 1, 0);
00291     
00292     if (widget == cinfo->r_scale) {
00293        cinfo->new_color.red = cbs->value << 8; /* << 8  ==  * 65535 */
00294     }
00295     else if (widget == cinfo->g_scale) {
00296        cinfo->new_color.green = cbs->value << 8;
00297     }
00298     else if (widget == cinfo->b_scale) {
00299        cinfo->new_color.blue = cbs->value << 8;
00300     }
00301 
00302     if (!XAllocColor(DISP, G_colormap, &(cinfo->new_color))) {
00303        XDVI_ERROR((stderr, "Couldn't XAllocColor\n"));
00304        return;
00305     }
00306 /*      fprintf(stderr, "Pixel: 0x%.6lx\n", cinfo->new_color.pixel); */
00307 
00308 #if XmVersion >= 1002
00309     /* if avaliable, use this so that the foreground color also
00310        gets updated appropriately: */
00311     XmChangeColor(cinfo->new_sample, cinfo->new_color.pixel);
00312 #else
00313     XtVaSetValues(cinfo->new_sample, XmNbackground, cinfo->new_color.pixel, NULL);
00314 #endif
00315 }
00316 
00317 static void
00318 h_init_sliders(struct color_info *cinfo)
00319 {
00320     unsigned r, g, b;
00321 
00322     r = cinfo->new_color.red >> 8;
00323     g = cinfo->new_color.green >> 8;
00324     b = cinfo->new_color.blue >> 8;
00325 
00326     XtVaSetValues(cinfo->r_scale, XmNvalue, r, NULL);
00327     XtVaSetValues(cinfo->g_scale, XmNvalue, g, NULL);
00328     XtVaSetValues(cinfo->b_scale, XmNvalue, b, NULL);
00329 }
00330 
00331 static Widget
00332 h_create_color_matrix(Widget parent, Widget top, struct color_info *cinfo)
00333 {
00334     int i, j;
00335     const char **color_ptr = colors;
00336        
00337     Widget matrix =
00338        XtVaCreateManagedWidget("color_matrix", xmRowColumnWidgetClass,
00339                             parent,
00340                             XmNtopAttachment, XmATTACH_WIDGET,
00341                             XmNtopWidget, top,
00342                             XmNleftAttachment, XmATTACH_FORM,
00343                             XmNrightAttachment, XmATTACH_FORM,
00344                             XmNpacking, XmPACK_COLUMN,
00345                             XmNnumColumns, COLS,
00346                             XmNorientation, XmVERTICAL,
00347                             XmNbackground, BlackPixelOfScreen(XtScreen(parent)),
00348                             XmNspacing, 1,
00349                             XmNmarginWidth, 1,
00350                             XmNmarginHeight, 1,
00351                             NULL);
00352     
00353     for (i = 0; i < ROWS; i++) {
00354        for (j = 0; j < COLS; j++) {
00355            Pixel pix = BlackPixelOfScreen(XtScreen(parent));
00356            Widget button;
00357            if (*color_ptr == NULL) /* safety */
00358               break;
00359            str_to_pixel(top, *color_ptr++, &pix);
00360            /*  fprintf(stderr, "creating button %d, %d - %s\n", i, j, k % 2 ? "b" : "w"); */
00361            button = XtVaCreateManagedWidget("c_button", xmDrawnButtonWidgetClass,
00362                                         matrix,
00363                                         XmNbackground, pix,
00364                                         XmNheight, 19,
00365                                         XmNwidth, 19,
00366                                         XmNmarginWidth, 0,
00367                                         XmNmarginHeight, 0,
00368                                         XmNhighlightThickness, 0,
00369                                         XmNshadowThickness, 0,
00370                                         NULL);
00371            XtAddCallback(button, XmNactivateCallback, show_color_cb, cinfo);
00372        }
00373     }
00374     return matrix;
00375 }
00376 
00377 static void
00378 h_create_sliders(Widget parent, Widget top, struct color_info *cinfo)
00379 {
00380     XmString str;
00381     Widget r_label, g_label, b_label;
00382     Widget r_scale, g_scale, b_scale;
00383     Dimension curr, max;
00384 
00385     Arg scale_args[8];
00386     Arg label_args[8];
00387     int scale_n = 0;
00388 
00389     XtSetArg(scale_args[scale_n], XmNmaximum, 255); scale_n++;
00390     /* True is an older setting of XmNshowValue that should also work with 2.x */
00391     XtSetArg(scale_args[scale_n], XmNshowValue, True); scale_n++;
00392     XtSetArg(scale_args[scale_n], XmNorientation, XmHORIZONTAL); scale_n++;
00393 #if XmVersion >= 2000
00394     XtSetArg(scale_args[scale_n], XmNshowArrows, XmEACH_SIDE); scale_n++;
00395     /* XmVersion < 2000 only had `True' which was the default anyway */
00396 #endif
00397     
00398     str = XmStringCreateLocalized("Red");
00399     XtSetArg(label_args[0], XmNlabelString, str);
00400     r_label = XtCreateManagedWidget("r_label", xmLabelGadgetClass, parent, label_args, 1);
00401     XmStringFree(str);
00402 
00403     r_scale = XtCreateWidget("r_scale", xmScaleWidgetClass, parent, scale_args, scale_n);
00404     cinfo->r_scale = r_scale;
00405     XtAddCallback(r_scale, XmNdragCallback, slider_cb, cinfo);
00406     XtAddCallback(r_scale, XmNvalueChangedCallback, slider_cb, cinfo);
00407 
00408     str = XmStringCreateLocalized("Green");
00409     XtSetArg(label_args[0], XmNlabelString, str);
00410     g_label = XtCreateManagedWidget("g_label", xmLabelGadgetClass, parent, label_args, 1);
00411     XmStringFree(str);
00412 
00413     g_scale = XtCreateWidget("g_scale", xmScaleWidgetClass, parent, scale_args, scale_n);
00414     cinfo->g_scale = g_scale;
00415     XtAddCallback(g_scale, XmNdragCallback, slider_cb, cinfo);
00416     XtAddCallback(g_scale, XmNvalueChangedCallback, slider_cb, cinfo);
00417 
00418     str = XmStringCreateLocalized("Blue");
00419     XtSetArg(label_args[0], XmNlabelString, str);
00420     b_label = XtCreateManagedWidget("b_label", xmLabelGadgetClass, parent, label_args, 1);
00421     XmStringFree(str);
00422     
00423     b_scale = XtCreateWidget("b_scale", xmScaleWidgetClass, parent, scale_args, scale_n);
00424     cinfo->b_scale = b_scale;
00425     XtAddCallback(b_scale, XmNdragCallback, slider_cb, cinfo);
00426     XtAddCallback(b_scale, XmNvalueChangedCallback, slider_cb, cinfo);
00427 
00428     /* get max width of labels, and adjust scale size to what's left */
00429     XtVaGetValues(r_label, XmNwidth, &curr, NULL);
00430     XtVaGetValues(g_label, XmNwidth, &max, NULL);
00431     if (curr > max)
00432        max = curr;
00433     XtVaGetValues(b_label, XmNwidth, &curr, NULL);
00434     if (curr > max)
00435        max = curr;
00436     /* we know the width of the color selector is about 200 pixels (10 fields each 20 wide),
00437        so we use that as max length */
00438     curr = 200 - max - 2; /* some additional offset */
00439     
00440     /*  fprintf(stderr, "width of slider: %d\n", curr); */
00441     /*  fprintf(stderr, "width of string: %d\n", max); */
00442     
00443     /* attach widgets; needs to be done after creating them since r_label
00444        attachment references g_label etc. */
00445     XtVaSetValues(r_label,
00446                 XmNleftAttachment, XmATTACH_FORM,
00447                 XmNbottomAttachment, XmATTACH_WIDGET,
00448                 XmNbottomWidget, g_label,
00449                 XmNbottomOffset, 20, /* needed to make label visible */
00450                 NULL);
00451     XtVaSetValues(r_scale,
00452                 XmNtopAttachment, XmATTACH_WIDGET,
00453                 XmNtopWidget, top,
00454                 XmNrightAttachment, XmATTACH_FORM,
00455                 XmNbottomAttachment, XmATTACH_WIDGET,
00456                 XmNbottomWidget, g_label,
00457                 XmNbottomOffset, 20, /* needed to make label visible */
00458                 XmNscaleWidth, curr,
00459                 NULL);
00460     XtVaSetValues(g_label,
00461                 XmNleftAttachment, XmATTACH_FORM,
00462                 XmNbottomAttachment, XmATTACH_WIDGET,
00463                 XmNbottomWidget, b_label,
00464                 XmNbottomOffset, 20, /* needed to make label visible */
00465                 NULL);
00466     XtVaSetValues(g_scale,
00467                 XmNrightAttachment, XmATTACH_FORM,
00468                 XmNbottomAttachment, XmATTACH_WIDGET,
00469                 XmNbottomWidget, b_label,
00470                 XmNbottomOffset, 20, /* needed to make label visible */
00471                 XmNscaleWidth, curr,
00472                 NULL);
00473     XtVaSetValues(b_label,
00474                 XmNleftAttachment, XmATTACH_FORM,
00475                 XmNbottomAttachment, XmATTACH_FORM,
00476                 XmNbottomOffset, 15,
00477                 NULL);
00478     XtVaSetValues(b_scale,
00479                 XmNrightAttachment, XmATTACH_FORM,
00480                 XmNbottomAttachment, XmATTACH_FORM,
00481                 XmNbottomOffset, 15,
00482                 XmNscaleWidth, curr,
00483                 NULL);
00484 
00485     XtManageChild(r_scale);
00486     XtManageChild(g_scale);
00487     XtManageChild(b_scale);
00488 
00489     h_init_sliders(cinfo);
00490     
00491 }
00492 
00493 static Widget
00494 h_create_shell(Widget parent, struct color_info *cinfo)
00495 {
00496     Widget shell, dialog, form, button_row, color_matrix;
00497     Widget old_sample, new_sample;
00498     Widget tip_shell;
00499     Atom WM_DELETE_WINDOW;
00500     Arg args[32];
00501     int n;
00502     
00503     XmString str;
00504     
00505     Pixel old_pixel = cinfo->button_info->pixel;
00506     /* hack to disable resizing of the shell, since this messes up the color matrix badly */
00507     int decoration = MWM_DECOR_ALL | MWM_DECOR_RESIZEH | MWM_DECOR_MENU | MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE;
00508     int functions = MWM_FUNC_ALL | MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE;
00509 
00510     struct color_button_info *binfo = cinfo->button_info;
00511     struct topic_info *tinfo = binfo->tinfo;
00512     struct prefs_choice *prefs = (struct prefs_choice *)tinfo->data;
00513 /*     struct prefs_choice *prefs; */
00514     
00515     n = 0;
00516     XtSetArg(args[n], XmNuserData, cinfo); n++;
00517 
00518 /*     XtSetArg(args[n], XmNdeleteResponse, XmDO_NOTHING); n++; */
00519 /*     XtSetArg(args[n], XmNnoResize, True); n++; */
00520 /*     XtSetArg(args[n], XmNmwmFunctions, functions); n++; */
00521 /*     XtSetArg(args[n], XmNmwmDecorations, decoration); n++; */
00522     XtSetArg(args[n], XtNtitle, "Xdvik: Select Color"); n++;
00523     
00524     dialog = XmCreatePromptDialog(parent, Xdvi_COLOR_DIALOG_NAME, args, n);
00525     /* unmanage stuff to get a `scratch' widget */
00526     XtUnmanageChild(XtNameToWidget(dialog, "Help"));
00527     XtUnmanageChild(XtNameToWidget(dialog, "Text"));
00528     XtUnmanageChild(XtNameToWidget(dialog, "Selection"));
00529 
00530     shell = XtParent(dialog);
00531 
00532     XtVaSetValues(shell,
00533                 XmNdeleteResponse, XmDO_NOTHING,
00534                 XmNnoResize, True,
00535                 XmNmwmFunctions, functions,
00536                 XmNmwmDecorations, decoration,
00537                 NULL);
00538     
00539     /* cinfo->new_color is a allocated/freed by request; initialize it with old_pixel */
00540     XAllocColor(DISP, G_colormap, &(cinfo->new_color));
00541     cinfo->new_color.flags = DoRed | DoGreen | DoBlue;
00542 
00543     XFreeColors(DISP, G_colormap, &(cinfo->new_color.pixel), 1, 0);
00544     pixel_to_color(old_pixel, &(cinfo->new_color), DISP, G_colormap);
00545 
00546     
00547     tip_shell = XtVaCreatePopupShell("tipShell", tipWidgetClass,
00548                                  parent, XtNwidth, 1, XtNheight, 1,
00549                                  NULL);
00550     cinfo->tooltip = tip_shell;
00551     
00552     form = XtVaCreateWidget("form", xmFormWidgetClass,
00553                          dialog,
00554                          XmNhorizontalSpacing, 10,
00555                          XmNverticalSpacing, 10,
00556                          XmNallowResize, False,
00557                          NULL);
00558     
00559     button_row = XtVaCreateManagedWidget("button_row", xmRowColumnWidgetClass,
00560                                     form,
00561                                     XmNtopAttachment, XmATTACH_FORM,
00562                                     XmNleftAttachment, XmATTACH_FORM,
00563                                     XmNorientation, XmHORIZONTAL,
00564                                     XmNpacking, XmPACK_COLUMN,
00565                                     XmNspacing, 8,
00566                                     XmNmarginWidth, 1,
00567                                     XmNmarginHeight, 1,
00568                                     NULL);
00569 
00570     str = XmStringCreateLocalized("Old");
00571     old_sample = XtVaCreateManagedWidget(Xdvi_COLOR_DIALOG_OLD_SAMPLE_NAME, xmPushButtonWidgetClass,
00572                                     button_row,
00573                                     XmNbackground, old_pixel,
00574                                     XmNlabelString, str,
00575                                     XmNhighlightThickness, 0,
00576                                     XmNshadowThickness, 1,
00577                                     NULL);
00578     XtAddCallback(old_sample, XmNactivateCallback, revert_color_cb, cinfo);
00579     XmStringFree(str);
00580     str = XmStringCreateLocalized("New");
00581     new_sample = XtVaCreateManagedWidget("new_sample", xmPushButtonWidgetClass,
00582                                     button_row,
00583                                     XmNbackground, cinfo->new_color.pixel,
00584                                     XmNlabelString, str,
00585                                     XmNhighlightThickness, 0,
00586                                     XmNshadowThickness, 1,
00587                                     NULL);
00588     XmStringFree(str);
00589     XtInsertEventHandler(new_sample,
00590                       KeyPressMask | KeyReleaseMask |
00591                       ButtonPressMask | ButtonReleaseMask |
00592                       PointerMotionMask| PointerMotionHintMask |
00593                       ButtonMotionMask | FocusChangeMask,
00594                       True, block_event_callback,
00595                       (XtPointer)0, 0);
00596     cinfo->new_sample = new_sample;
00597     
00598     color_matrix = h_create_color_matrix(form, button_row, cinfo);
00599 
00600     h_create_sliders(form, color_matrix, cinfo);
00601 
00602     XtManageChild(form);
00603     
00604     XtAddCallback(dialog, XmNokCallback, popdown_apply_cb, prefs);
00605     XtAddCallback(dialog, XmNcancelCallback, popdown_cancel_cb, prefs);
00606 
00607     XtManageChild(dialog);
00608 
00609     add_to_deplist(prefs, dialog);
00610 
00611 /*     h_create_commands(shell, color_globals.widgets.paned, "OK", "Cancel", cinfo); */
00612 
00613 /*     XtManageChild(color_globals.widgets.paned); */
00614     
00615 /*     XtRealizeWidget(shell); */
00616 
00617     TipAddWidget(tip_shell, old_sample, "Click to revert to old color");
00618     /*  TipAddWidget(tip_shell, color_matrix, "Select color"); */
00619 
00620     WM_DELETE_WINDOW = XmInternAtom(DISP, "WM_DELETE_WINDOW", False);
00621     XmAddWMProtocolCallback(shell, WM_DELETE_WINDOW, popdown_cb, prefs);
00622 
00623     return dialog;
00624 }
00625 
00626 void
00627 popup_color_dialog(Widget parent, struct color_button_info *button_info)
00628 {
00629     static Widget shell;
00630     static Boolean first_time = True;
00631     /* Must be static so that we can pass its address around */
00632     static struct color_info cinfo;
00633     struct topic_info *tinfo = button_info->tinfo;
00634     struct prefs_choice *prefs = (struct prefs_choice *)tinfo->data;
00635     
00636     cinfo.button_info = button_info;
00637     
00638     if (first_time) {
00639        shell = h_create_shell(parent, &cinfo);
00640        first_time = False;
00641     }
00642     else {
00643        /* Already created, but we may need to change the colors of old_sample
00644           and new_sample. This is done by changing the value of old_sample and
00645           invoking its activate callback, which will `revert' new_sample to
00646           the same color. */
00647        Widget w;
00648        if (get_widget_by_name(&w, shell, Xdvi_COLOR_DIALOG_OLD_SAMPLE_NAME, True)) {
00649 #if XmVersion >= 1002
00650            XmChangeColor(w, cinfo.button_info->pixel);
00651 #else
00652            XtVaSetValues(w, XmNbackground, cinfo.button_info->pixel, NULL);
00653 #endif
00654            XtCallCallbacks(w, XmNactivateCallback, &cinfo);
00655        }
00656        add_to_deplist(prefs, shell);
00657        XtManageChild(shell);
00658     }
00659 }
00660 
00661 #else
00662 /* silence `empty compilation unit' warnings */
00663 static void bar(void); static void foo() { bar(); } static void bar(void) { foo(); }
00664 #endif /* MOTIF */