home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
x
/
xcolored.zip
/
xcoloredit
/
xcoloredit.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-25
|
28KB
|
1,052 lines
#ifndef lint
static char sccsid[] = "@(#)xcoloredit.c 1.2 (UKC) 25/1/92";
#endif /* !lint */
/*
* Copyright 1990,1992 Richard Hesketh / rlh2@ukc.ac.uk
* Computing Lab. University of Kent at Canterbury, UK
*
* Permission to use, copy, modify and distribute this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the names of Richard Hesketh and The University of
* Kent at Canterbury not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* Richard Hesketh and The University of Kent at Canterbury make no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
* Richard Hesketh AND THE UNIVERSITY OF KENT AT CANTERBURY DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL Richard Hesketh OR THE
* UNIVERSITY OF KENT AT CANTERBURY BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*
* Author: Richard Hesketh / rlh2@ukc.ac.uk,
* Computing Lab. University of Kent at Canterbury, UK
*/
/* A picapix lookalike under X11 */
/*
* xcoloredit - a colour palette mixer. Allows existing colormap entries
* to be edited.
*/
#include <stdio.h>
#include <X11/Xatom.h>
#include <X11/X.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/Xaw/Toggle.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Scrollbar.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Box.h>
#include <X11/Xmu/Atoms.h>
#include "Xcoloredit.h"
#include "color.h"
#define PRIMARY_COLOR "PRIMARY_COLOR"
#define XA_PRIMARY_COLOR XmuInternAtom(XtDisplay(w),_XA_PRIMARY_COLOR)
static AtomPtr _XA_PRIMARY_COLOR = NULL;
extern void exit();
extern void XukcRegisterApplicationDefaults();
extern Display *XukcToolkitInitialize();
static void OwnSelection();
/* callback routines */
static void Set_Selection();
static void Quit();
static void Thumbed();
static void Scrolled();
static void Load();
static void Store();
static void Update_HSV();
static void Update_Triple();
/* action routines */
static void lock_toggle();
static void pick_memory();
static void draw_boxed();
static void erase_boxed();
static void border();
static void update_triple();
static void set_scroll();
static void stop_scroll();
static void move_scroll();
static void change_text_colour();
#define MEMORY_OFFSET 8
#define NUM_MEMORIES 36
#define NUM_IN_ROW 12
#define MAX_COLORS NUM_MEMORIES+MEMORY_OFFSET
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define COLOR(color_el,rgb) (colors[color_el].rgb/256)
#define CHANGE_RED(element) \
pass_value = 1.0 - (double)(COLOR(element,red)/255.0); \
Thumbed(redScroll, RED, (XtPointer)(&pass_value))
#define CHANGE_GREEN(element) \
pass_value = 1.0 - (double)(COLOR(element,green)/255.0); \
Thumbed(greenScroll, GREEN, (XtPointer)(&pass_value))
#define CHANGE_BLUE(element) \
pass_value = 1.0 - (double)(COLOR(element,blue)/255.0); \
Thumbed(blueScroll, BLUE, (XtPointer)(&pass_value))
static XColor colors[MAX_COLORS];
static Display *dpy;
static Colormap cmap;
static GC boxedGC, boxedChangedGC, unboxedGC;
static RGB rgb_values;
static HSV hsv_values;
static int buttons_down = 0;
static int bars_locked = 0;
static double locked_top = 1.0, red_top, green_top, blue_top;
static float pass_value;
static int last_pos;
static Boolean do_change = TRUE;
static int current_memory = 0;
static Pixel original_background;
static Widget toplevel, mixingForm, mixedColor;
static Widget redLocked, greenLocked, blueLocked, title;
static Widget redIntensity, greenIntensity, blueIntensity, tripleValue;
static Widget redScroll, greenScroll, blueScroll, lockedScroll;
static Widget hueScroll, satScroll, valScroll;
static Widget hueLabel, satLabel, valLabel;
static Widget quit;
static Widget colorMemory[NUM_MEMORIES];
static Boolean colorUsed[NUM_MEMORIES];
#define RED 1
#define GREEN 2
#define BLUE 4
#define LOCKED 8
#define HUE 16
#define SAT 32
#define VAL 64
#define MIX_COLOR 0
#define RED_COLOR 1
#define GREEN_COLOR 2
#define BLUE_COLOR 3
#define PURE_BLACK 4
#define PURE_RED 5
#define PURE_GREEN 6
#define PURE_BLUE 7
struct app_resources {
Boolean silent;
String text;
String format;
} prog_res;
static XtActionsRec actionTable[] = {
{"lock_toggle", lock_toggle},
{"pick_memory", pick_memory},
{"draw_boxed", draw_boxed},
{"erase_boxed", erase_boxed},
{"border", border},
{"update_triple", update_triple},
{"set_scroll", set_scroll},
{"stop_scroll", stop_scroll},
{"move_scroll", move_scroll},
{"change_text_colour", change_text_colour},
};
static XrmOptionDescRec options[] = {
{ "-silent", ".silent", XrmoptionNoArg, (caddr_t)"true" },
{ "-text", ".text", XrmoptionSepArg, (caddr_t)NULL },
{ "-format", ".format", XrmoptionSepArg, (caddr_t)NULL },
};
#define offset(field) XtOffset(struct app_resources *, field)
static XtResource resources[] = {
{ "silent", "Silent", XtRBoolean, sizeof(Boolean),
offset(silent), XtRImmediate, (XtPointer)FALSE },
{ "text", "Text", XtRString, sizeof(String),
offset(text), XtRImmediate, (XtPointer)NULL },
{ "format", "Format", XtRString, sizeof(String),
offset(format), XtRImmediate, (XtPointer)"#%02x%02x%02x" }
};
#undef offset
void main(argc, argv)
unsigned int argc;
char **argv;
{
Status ok;
unsigned long plane_masks;
unsigned long pixels[MAX_COLORS];
Cardinal i, j, k;
XGCValues values;
Widget temp;
dpy = XukcToolkitInitialize((String)NULL, "xcoloredit", "Xcoloredit",
&argc, argv,
(XrmOptionDescRec *)options, XtNumber(options));
XukcRegisterApplicationDefaults(DefaultScreenOfDisplay(dpy),
app_defaults, XtNumber(app_defaults));
toplevel = XtVaAppCreateShell("xcoloredit", "Xcoloredit",
applicationShellWidgetClass, dpy,
NULL);
XtGetApplicationResources(toplevel, &prog_res, resources,
XtNumber(resources), (ArgList)NULL, 0);
cmap = DefaultColormap(dpy, DefaultScreen(dpy));
if(!XAllocColorCells(dpy, cmap, 0, &plane_masks, 0, pixels,
MAX_COLORS-1))
XtError("xcoloredit: Not enough colormap entries available");
/* allocate the standard cells used by the application */
for (j = 0, i = 1; i < MEMORY_OFFSET; i++) {
colors[i].pixel = pixels[j++];
colors[i].flags = DoRed | DoGreen | DoBlue;
}
/* initialize the pixel memory locations */
for (k = 1, i = MEMORY_OFFSET; i < MAX_COLORS; i++) {
colors[i].flags = DoRed | DoGreen | DoBlue;
if (argc > 1) {
/* pull in any colormap entries specified on the
* command line */
colors[i].pixel = atoi(argv[k++]);
colorUsed[i-MEMORY_OFFSET] = TRUE;
argc--;
} else {
colors[i].pixel = pixels[j++];
colors[i].red = colors[i].green = colors[i].blue = 0;
colorUsed[i-MEMORY_OFFSET] = FALSE;
}
}
/* retrieve the given colormap entries current values */
if (k > 1)
XQueryColors(dpy, cmap, &(colors[MEMORY_OFFSET]), k-1);
current_memory = 0;
colors[MIX_COLOR].pixel = colors[MEMORY_OFFSET].pixel;
colors[MIX_COLOR].flags = DoRed | DoGreen | DoBlue;
colors[MIX_COLOR].red = colors[MEMORY_OFFSET].red;
colors[MIX_COLOR].green = colors[MEMORY_OFFSET].green;
colors[MIX_COLOR].blue = colors[MEMORY_OFFSET].blue;
colors[PURE_BLACK].red = colors[PURE_BLACK].green = 0;
colors[PURE_BLACK].blue = 0;
colors[PURE_RED].blue = colors[PURE_RED].green = 0;
colors[RED_COLOR].blue = colors[RED_COLOR].green = 0;
colors[PURE_RED].red = colors[RED_COLOR].red = (short)~0;
/* not as pure as it should be!! looks better like this though 8-) */
colors[PURE_GREEN].red = 0x4f*256;
colors[PURE_GREEN].green = 0xb5*256;
colors[PURE_GREEN].blue = 0x1e*256;
colors[GREEN_COLOR].red = colors[GREEN_COLOR].blue = 0;
colors[GREEN_COLOR].green = (short)~0;
colors[PURE_BLUE].red = colors[PURE_BLUE].green = 0;
colors[BLUE_COLOR].red = colors[BLUE_COLOR].green = 0;
colors[PURE_BLUE].blue = colors[BLUE_COLOR].blue = (short)~0;
XStoreColors(dpy, cmap, colors, MAX_COLORS);
for (i = MEMORY_OFFSET; i < j; i++)
colors[i].flags = DoRed | DoGreen | DoBlue;
XtAppAddActions(XtWidgetToApplicationContext(toplevel),
actionTable, XtNumber(actionTable));
/* create the UI */
mixingForm = XtVaCreateManagedWidget("mixingForm", formWidgetClass,
toplevel, NULL);
redLocked = XtVaCreateManagedWidget("redLocked", labelWidgetClass,
mixingForm, NULL);
greenLocked = XtVaCreateManagedWidget("greenLocked", labelWidgetClass,
mixingForm, NULL);
blueLocked = XtVaCreateManagedWidget("blueLocked", labelWidgetClass,
mixingForm, NULL);
title = XtVaCreateManagedWidget("title", labelWidgetClass,
mixingForm, NULL);
redScroll = XtVaCreateManagedWidget("redScroll", scrollbarWidgetClass,
mixingForm, NULL);
greenScroll = XtVaCreateManagedWidget("greenScroll",
scrollbarWidgetClass, mixingForm, NULL);
blueScroll = XtVaCreateManagedWidget("blueScroll", scrollbarWidgetClass,
mixingForm, NULL);
lockedScroll = XtVaCreateManagedWidget("lockedScroll",
scrollbarWidgetClass, mixingForm, NULL);
mixedColor = XtVaCreateManagedWidget("mixedColor", labelWidgetClass,
mixingForm,
XtVaTypedArg, XtNforeground,
XtRString, "white", 6,
XtNbackground, colors[MIX_COLOR].pixel,
NULL);
if (prog_res.text != NULL)
XtVaSetValues(mixedColor, XtNlabel, prog_res.text, NULL);
redIntensity = XtVaCreateManagedWidget("redIntensity", widgetClass,
mixingForm,
XtNbackground, colors[RED_COLOR].pixel,
NULL);
greenIntensity = XtVaCreateManagedWidget("greenIntensity", widgetClass,
mixingForm,
XtNbackground, colors[GREEN_COLOR].pixel,
NULL);
blueIntensity = XtVaCreateManagedWidget("blueIntensity", widgetClass,
mixingForm,
XtNbackground, colors[BLUE_COLOR].pixel,
NULL);
tripleValue = XtVaCreateManagedWidget("tripleValue", toggleWidgetClass,
mixingForm, NULL);
quit = XtVaCreateManagedWidget("quit", commandWidgetClass, mixingForm,
NULL);
hueLabel = XtVaCreateManagedWidget("hueLabel", labelWidgetClass,
mixingForm, NULL);
satLabel = XtVaCreateManagedWidget("satLabel", labelWidgetClass,
mixingForm, NULL);
valLabel = XtVaCreateManagedWidget("valLabel", labelWidgetClass,
mixingForm, NULL);
hueScroll = XtVaCreateManagedWidget("hueScroll", scrollbarWidgetClass,
mixingForm, NULL);
satScroll = XtVaCreateManagedWidget("satScroll", scrollbarWidgetClass,
mixingForm, NULL);
valScroll = XtVaCreateManagedWidget("valScroll", scrollbarWidgetClass,
mixingForm, NULL);
temp = quit;
for (i = 0; i < NUM_MEMORIES; i++) {
if (i > 0 && i%NUM_IN_ROW == 0)
temp = colorMemory[i-1];
colorMemory[i] = XtVaCreateManagedWidget("colorMemory",
widgetClass, mixingForm,
XtNbackground, colors[i+MEMORY_OFFSET].pixel,
XtNfromVert, temp,
XtNfromHoriz,
(i%NUM_IN_ROW ? colorMemory[i-1] : NULL),
NULL);
}
values.foreground = colors[PURE_RED].pixel;
values.line_width = 2;
values.line_style = LineOnOffDash;
boxedChangedGC = XtGetGC(mixingForm, GCForeground | GCLineWidth,
&values);
boxedGC = XtGetGC(mixingForm, GCForeground | GCLineWidth | GCLineStyle,
&values);
XtVaGetValues(mixingForm, XtNbackground, &(values.foreground), NULL);
unboxedGC = XtGetGC(mixingForm, GCForeground | GCLineWidth, &values);
original_background = values.foreground;
bars_locked = NULL;
XtAddCallback(redScroll, XtNjumpProc, Thumbed, (XtPointer)RED);
XtAddCallback(greenScroll, XtNjumpProc, Thumbed, (XtPointer)GREEN);
XtAddCallback(blueScroll, XtNjumpProc, Thumbed, (XtPointer)BLUE);
XtAddCallback(lockedScroll, XtNjumpProc, Thumbed, (XtPointer)LOCKED);
XtAddCallback(redScroll, XtNscrollProc, Scrolled, (XtPointer)RED);
XtAddCallback(greenScroll, XtNscrollProc, Scrolled, (XtPointer)GREEN);
XtAddCallback(blueScroll, XtNscrollProc, Scrolled, (XtPointer)BLUE);
XtAddCallback(lockedScroll, XtNscrollProc, Scrolled, (XtPointer)LOCKED);
XtAddCallback(hueScroll, XtNscrollProc, Scrolled, (XtPointer)HUE);
XtAddCallback(satScroll, XtNscrollProc, Scrolled, (XtPointer)SAT);
XtAddCallback(valScroll, XtNscrollProc, Scrolled, (XtPointer)VAL);
XtAddCallback(hueScroll, XtNjumpProc, Update_HSV, (XtPointer)HUE);
XtAddCallback(satScroll, XtNjumpProc, Update_HSV, (XtPointer)SAT);
XtAddCallback(valScroll, XtNjumpProc, Update_HSV, (XtPointer)VAL);
XtAddCallback(tripleValue, XtNcallback, Set_Selection,
(XtPointer)PRIMARY_COLOR);
XtAddCallback(quit, XtNcallback, Quit, (XtPointer)toplevel);
XtRealizeWidget(toplevel);
/* set the scrollbars to the initial mixed colour values */
do_change = FALSE;
CHANGE_RED(MIX_COLOR);
CHANGE_GREEN(MIX_COLOR);
CHANGE_BLUE(MIX_COLOR);
do_change = TRUE;
XStoreColors(dpy, cmap, colors, 4);
update_triple((Widget)NULL, (XEvent *)NULL,
(String *)NULL, (Cardinal *)NULL);
XtAppMainLoop(XtWidgetToApplicationContext(toplevel));
}
/* ARGSUSED */
static void
Quit(w, client, call)
Widget w;
XtPointer client, call;
{
Cardinal i;
colors[current_memory+MEMORY_OFFSET].red = colors[MIX_COLOR].red;
colors[current_memory+MEMORY_OFFSET].green = colors[MIX_COLOR].green;
colors[current_memory+MEMORY_OFFSET].blue = colors[MIX_COLOR].blue;
if (!prog_res.silent)
for (i = 0; i < NUM_MEMORIES; i++)
if (colorUsed[i]) {
printf(prog_res.format,
COLOR(i+MEMORY_OFFSET,red),
COLOR(i+MEMORY_OFFSET,green),
COLOR(i+MEMORY_OFFSET,blue));
putchar('\n');
}
XtReleaseGC(mixingForm, boxedGC);
XtReleaseGC(mixingForm, boxedChangedGC);
XtReleaseGC(mixingForm, unboxedGC);
exit(0);
}
static void
lock_toggle(w, event, params, num_params)
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
{
Arg args[1];
int button = WhichButton(params[0]);
args[0].name = XtNbackground;
if (button & bars_locked) {
args[0].value = original_background;
bars_locked -= button;
if (!bars_locked)
XtSetSensitive(lockedScroll, FALSE);
} else {
switch (button) {
case RED:
args[0].value = colors[PURE_RED].pixel;
break;
case GREEN:
args[0].value = colors[PURE_GREEN].pixel;
break;
case BLUE:
args[0].value = colors[PURE_BLUE].pixel;
break;
default:
return;
/* NOT REACHED */
}
bars_locked += button;
XtSetSensitive(lockedScroll, TRUE);
}
move_lock();
XtSetValues(w, (ArgList)args, 1);
}
/* draw a dashed box around the given widget */
static void
draw_a_dotted_box(w, gc)
Widget w;
GC gc;
{
Position x, y;
Dimension width, height, border_width;
Arg args[5];
XtSetArg(args[0], XtNborderWidth, &border_width);
XtSetArg(args[1], XtNx, &x);
XtSetArg(args[2], XtNy, &y);
XtSetArg(args[3], XtNwidth, &width);
XtSetArg(args[4], XtNheight, &height);
XtGetValues(w, (ArgList)args, 5);
x -= border_width + 1;
y -= border_width + 1;
width += border_width*2 + 4;
height += border_width*2 + 4;
XDrawRectangle(XtDisplay(mixingForm), XtWindow(mixingForm), gc,
x, y, width, height);
}
static void
draw_boxed(w, event, params, num_params)
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
{
draw_a_dotted_box(colorMemory[current_memory],
colorUsed[current_memory] ? boxedChangedGC :
boxedGC);
}
static void
erase_boxed(w, event, params, num_params)
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
{
draw_a_dotted_box(colorMemory[current_memory], unboxedGC);
}
static void
pick_memory(w, event, params, num_params)
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
{
int i;
for (i = 0; i < NUM_MEMORIES; i++) {
if (w == colorMemory[i]) {
/* old memory cell */
draw_a_dotted_box(colorMemory[current_memory],
unboxedGC);
colors[current_memory+MEMORY_OFFSET].red =
colors[MIX_COLOR].red;
colors[current_memory+MEMORY_OFFSET].green =
colors[MIX_COLOR].green;
colors[current_memory+MEMORY_OFFSET].blue =
colors[MIX_COLOR].blue;
XStoreColor(dpy, cmap,
&(colors[current_memory+MEMORY_OFFSET]));
/* new memory cell */
current_memory = i;
draw_boxed((Widget)NULL, (XEvent *)NULL,
(String *)NULL, (Cardinal *)NULL);
colors[MIX_COLOR].pixel =
colors[current_memory+MEMORY_OFFSET].pixel;
if (colorUsed[current_memory]) {
do_change = FALSE;
CHANGE_RED(current_memory+MEMORY_OFFSET);
CHANGE_GREEN(current_memory+MEMORY_OFFSET);
CHANGE_BLUE(current_memory+MEMORY_OFFSET);
do_change = TRUE;
XStoreColors(dpy, cmap, colors, 4);
update_triple((Widget)NULL, (XEvent *)NULL,
(String *)NULL, (Cardinal *)NULL);
} else {
colors[current_memory+MEMORY_OFFSET].red =
colors[MIX_COLOR].red;
colors[current_memory+MEMORY_OFFSET].green =
colors[MIX_COLOR].green;
colors[current_memory+MEMORY_OFFSET].blue =
colors[MIX_COLOR].blue;
XStoreColor(dpy, cmap,
&(colors[current_memory+MEMORY_OFFSET]));
}
XtVaSetValues(mixedColor, XtNbackground,
colors[MIX_COLOR].pixel, NULL);
break;
}
}
}
static void
ChangeBorder(button, now_up)
int button;
Boolean now_up;
{
Widget scrollbar;
switch (button) {
case RED:
scrollbar = redScroll;
button = now_up ? PURE_RED : PURE_BLACK;
break;
case GREEN:
scrollbar = greenScroll;
button = now_up ? PURE_GREEN : PURE_BLACK;
break;
case BLUE:
scrollbar = blueScroll;
button = now_up ? PURE_BLUE : PURE_BLACK;
break;
default:
return;
/* NOTREACHED */
}
XtVaSetValues(scrollbar, XtNborderColor, colors[button].pixel, NULL);
}
static void
border(w, event, params, num_params)
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
{
Boolean reset = (Boolean)(*num_params == 1 && strcmp(params[0], "reset") == 0);
if (w == redScroll)
ChangeBorder(RED, reset);
else {
if (w == greenScroll)
ChangeBorder(GREEN, reset);
else {
if (w == blueScroll)
ChangeBorder(BLUE, reset);
else {
if (bars_locked & RED) ChangeBorder(RED, reset);
if (bars_locked & GREEN) ChangeBorder(GREEN, reset);
if (bars_locked & BLUE) ChangeBorder(BLUE, reset);
}
}
}
}
static int
WhichButton(name)
String name;
{
if (strcmp(name, "red") == 0)
return RED;
if (strcmp(name, "blue") == 0)
return BLUE;
if (strcmp(name, "green") == 0)
return GREEN;
return 0;
}
static void
Update_Triple(w, client_data, call_data)
Widget w;
XtPointer client_data, call_data;
{
String old_str;
char old_value[10];
Cardinal r, g, b;
XtVaGetValues(w, XtNlabel, &old_str, NULL);
(void)strncpy(old_str, old_value, 8);
if (sscanf((char *)call_data, prog_res.format, &r, &g, &b) != 3) {
XtVaSetValues(w, XtNlabel, old_value, NULL);
}
}
static void
change_text_colour(w, event, params, num_params)
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
{
XtVaSetValues(mixedColor, XtNforeground,
colors[current_memory+MEMORY_OFFSET].pixel,
NULL);
}
static void
update_triple(w, event, params, num_params)
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
{
Arg args[1];
char hexvalue[10];
(void)sprintf(hexvalue, prog_res.format,
COLOR(MIX_COLOR,red), COLOR(MIX_COLOR,green),
COLOR(MIX_COLOR,blue));
XtVaSetValues(tripleValue, XtNlabel, hexvalue, NULL);
OwnSelection(tripleValue, (XtPointer)FALSE, (XtPointer)TRUE);
rgb_values.r = colors[MIX_COLOR].red;
rgb_values.g = colors[MIX_COLOR].green;
rgb_values.b = colors[MIX_COLOR].blue;
hsv_values = RGBToHSV(rgb_values);
#ifdef SOLID_THUMB
XawScrollbarSetThumb(hueScroll, (float)(1.0 - hsv_values.h),
hsv_values.h);
XawScrollbarSetThumb(satScroll, (float)(1.0 - hsv_values.s),
hsv_values.s);
XawScrollbarSetThumb(valScroll, (float)(1.0 - hsv_values.v),
hsv_values.v);
#else
XawScrollbarSetThumb(hueScroll, (float)(1.0 - hsv_values.h),
(float)0.025);
XawScrollbarSetThumb(satScroll, (float)(1.0 - hsv_values.s),
(float)0.025);
XawScrollbarSetThumb(valScroll, (float)(1.0 - hsv_values.v),
(float)0.025);
#endif SOLID_THUMB
}
static void
set_scroll(w, event, params, num_params)
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
{
int button_down = WhichButton(params[0]);
last_pos = event->xbutton.y;
buttons_down |= button_down;
ChangeBorder(button_down, FALSE);
}
static void
stop_scroll(w, event, params, num_params)
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
{
int button_up = WhichButton(params[0]);
buttons_down &= ~button_up;
ChangeBorder(button_up, TRUE);
if (!buttons_down)
update_triple(w, event, params, num_params);
}
static void
move_scroll(w, event, params, num_params)
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
{
#define ADJUST_CHANGE(color) if (change < 0) { \
if (color + change < 0) \
change = -color; \
} else { \
if (color + change > 255) \
change = 255-color; \
}
int change;
float pass_value;
int red_pos, green_pos, blue_pos;
if (buttons_down == 0)
return;
change = last_pos - event->xmotion.y;
last_pos = event->xmotion.y;
if (buttons_down & RED) {
red_pos = colors[MIX_COLOR].red/256;
ADJUST_CHANGE(red_pos);
}
if (buttons_down & GREEN) {
green_pos = colors[MIX_COLOR].green/256;
ADJUST_CHANGE(green_pos);
}
if (buttons_down & BLUE) {
blue_pos = colors[MIX_COLOR].blue/256;
ADJUST_CHANGE(blue_pos);
}
red_pos += change;
green_pos += change;
blue_pos += change;
/* update the new scroll bar positions and change the color */
do_change = FALSE;
if (buttons_down & RED) {
pass_value = 1.0 - (float)red_pos/255;
Thumbed(redScroll, RED, (XtPointer)(&pass_value));
}
if (buttons_down & GREEN) {
pass_value = 1.0 - (float)green_pos/255;
Thumbed(greenScroll, GREEN, (XtPointer)(&pass_value));
}
if (buttons_down & BLUE) {
pass_value = 1.0 - (float)blue_pos/255;
Thumbed(blueScroll, BLUE, (XtPointer)(&pass_value));
}
do_change = TRUE;
XStoreColors(dpy, cmap, colors, 4);
if (!colorUsed[current_memory]) {
colorUsed[current_memory] = TRUE;
draw_boxed((Widget)NULL, (XEvent *)NULL,
(String *)NULL, (Cardinal *)NULL);
}
update_triple((Widget)NULL, (XEvent *)NULL,
(String *)NULL, (Cardinal *)NULL);
}
static void
Scrolled(w, closure, change)
Widget w;
XtPointer closure, change;
{
Boolean going_up = (int)change < 0;
int which = (int)closure;
int pos = 0;
switch (which) {
case RED:
pos = COLOR(MIX_COLOR,red);
break;
case BLUE:
pos = COLOR(MIX_COLOR,blue);
break;
case GREEN:
pos = COLOR(MIX_COLOR,green);
break;
case LOCKED:
pos = 255 - (int)(locked_top * 255 + 0.5);
break;
case HUE:
case SAT:
case VAL:
/* Not yet implemented */
return;
default:
fprintf(stderr, "Oops Scroll calldata invalid\n");
exit(1);
}
if (going_up) {
if (pos > 0)
pos--;
} else {
if (pos < 255)
pos++;
}
pass_value = 1.0 - (double)pos/255;
Thumbed(w, closure, (XtPointer)(&pass_value));
}
static void
Update_HSV(w, closure, ptr)
Widget w;
XtPointer closure, ptr;
{
int which = (int)closure;
float r, g, b;
float per = *(float*)ptr;
double top = (double)per;
XEvent event;
switch (which) {
case HUE:
hsv_values.h = 1.0 - top;
break;
case SAT:
hsv_values.s = 1.0 - top;
break;
case VAL:
hsv_values.v = 1.0 - top;
break;
}
rgb_values = HSVToRGB(hsv_values);
#ifdef SOLID_THUMB
XawScrollbarSetThumb(w, top, (float)(1.0 - top));
#else
XawScrollbarSetThumb(w, top, (float)0.025);
#endif SOLID_THUMB
do_change = FALSE;
pass_value = 1.0 - rgb_values.r/65536.0;
Thumbed(redScroll, (XtPointer)RED, (XtPointer)(&pass_value));
pass_value = 1.0 - rgb_values.g/65536.0;
Thumbed(greenScroll, (XtPointer)GREEN, (XtPointer)(&pass_value));
do_change = TRUE;
pass_value = 1.0 - rgb_values.b/65536.0;
Thumbed(blueScroll, (XtPointer)BLUE, (XtPointer)(&pass_value));
}
static void
Thumbed(w, closure, ptr)
Widget w;
XtPointer closure, ptr;
{
int which = (int)closure;
int mix;
float per = *(float*)ptr;
double top = (double)per;
XEvent event;
mix = (int) ((1.0 - top) * 256.0 * 256.0);
if (mix > 0xFFFF)
mix = 0xFFFF;
switch (which) {
case RED:
colors[MIX_COLOR].red = colors[RED_COLOR].red = mix;
red_top = top;
break;
case GREEN:
colors[MIX_COLOR].green = colors[GREEN_COLOR].green = mix;
green_top = top;
break;
case BLUE:
colors[MIX_COLOR].blue = colors[BLUE_COLOR].blue = mix;
blue_top = top;
break;
case LOCKED:
buttons_down = bars_locked;
last_pos = (int)((double)locked_top*255);
event.xmotion.y = (int)((double)top*255);
move_scroll(w, &event, (String *)NULL, (Cardinal *)NULL);
buttons_down = 0;
return;
}
if (do_change) {
XStoreColors(dpy, cmap, colors, 4);
if (!colorUsed[current_memory]) {
colorUsed[current_memory] = TRUE;
draw_boxed((Widget)NULL, (XEvent *)NULL,
(String *)NULL, (Cardinal *)NULL);
}
update_triple((Widget)NULL, (XEvent *)NULL,
(String *)NULL, (Cardinal *)NULL);
}
#ifdef SOLID_THUMB
XawScrollbarSetThumb(w, top, (float)(1.0 - top));
#else
XawScrollbarSetThumb(w, top, (float)0.025);
#endif SOLID_THUMB
move_lock();
}
move_lock()
{
locked_top = 1.0;
if (bars_locked & RED)
locked_top = MIN(locked_top, red_top);
if (bars_locked & BLUE)
locked_top = MIN(locked_top, blue_top);
if (bars_locked & GREEN)
locked_top = MIN(locked_top, green_top);
#ifdef SOLID_THUMB
XawScrollbarSetThumb(lockedScroll, locked_top,
(float)(1.0 - locked_top));
#else
XawScrollbarSetThumb(lockedScroll, locked_top, (float)0.025);
#endif SOLID_THUMB
}
/* Set the current selection of the PRIMARY_COLOR property to this colour */
/* ARGSUSED */
static void
Set_Selection(w, client_data, call_data)
Widget w;
XtPointer client_data, call_data;
{
Boolean own;
XtVaGetValues(w, XtNstate, &own, NULL);
OwnSelection(w, (XtPointer)TRUE, (XtPointer)(own ? TRUE : FALSE));
}
static Boolean
ConvertSelection(w, selection, target, type, value, length, format)
Widget w;
Atom *selection, *target, *type;
XtPointer *value;
unsigned long *length;
int *format;
{
if (XmuConvertStandardSelection(w, selection, target, type, value,
length, format))
return TRUE;
if (*target == XA_STRING) {
String color_str;
XtVaGetValues(tripleValue, XtNlabel, &color_str, NULL);
*type = XA_STRING;
*value = color_str;
*length = strlen(*value);
*format = 8;
return (TRUE);
}
return (FALSE);
}
/* ARGSUSED */
static void
LoseSelection(w, selection)
Widget w;
Atom *selection;
{
XtVaSetValues(w, XtNstate, FALSE, NULL);
}
/* ARGSUSED */
static void
DoneSelection(w, selection, target)
Widget w;
Atom *selection, *target;
{
/* we don't need to do anything here */
}
/* ARGSUSED */
static void
OwnSelection(w, client_data, call_data)
Widget w;
XtPointer client_data, call_data;
{
Time time = XtLastTimestampProcessed(XtDisplay(w));
Boolean primary = (Boolean)client_data;
Boolean own = (Boolean)call_data;
if (_XA_PRIMARY_COLOR == NULL)
_XA_PRIMARY_COLOR = XmuMakeAtom(PRIMARY_COLOR);
if (own) {
XtOwnSelection(w, XA_PRIMARY_COLOR, time,
ConvertSelection, LoseSelection, DoneSelection);
if (primary)
XtOwnSelection(w, XA_PRIMARY, time,
ConvertSelection, LoseSelection, DoneSelection);
} else {
XtDisownSelection(w, XA_PRIMARY_COLOR, time);
if (primary)
XtDisownSelection(w, XA_PRIMARY, time);
}
}