ain@j.cc.purdue.edu (Patrick White) (12/18/87)
Program Name: colour Submitted By: john13@garfield.mun.edu (John Russell) Summary: This program allows loading/setting/saving/adjusting of screen colors. It can also be compiled to not allow *adjusting* of colors (although setting, loading, and saving still work) -- saves ~6K. Poster Boy: Pat White (ain@j.cc.purdue.edu) Untested (meaning that I didn't try and compile it). NOTES: The built-in help for the un'FANCY' version tells about the "adjust" mode which is not available in it -- a simple code change that I didn't make. The binary copies of these two programs were posted to comp.binaries.amiga. -- Pat White (co-moderator comp.sources/binaries.amiga) UUCP: k.cc.purdue.edu!ain BITNET: PATWHITE@PURCCVM PHONE: (317) 743-8421 U.S. Mail: 320 Brown St. apt. 406, West Lafayette, IN 47906 ---------------------------------------- # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # README # colour.doc # colorreq.c # colour.c # amber.col # cyan.col # gray.col # green.col # lace.col # modem.col # pastel.col # red.col # royal.col # silver.col # silver2.col # wb.col # This archive created: Thu Dec 17 10:16:28 1987 # By: Patrick White (PUCC Land, USA) cat << \SHAR_EOF > README Please note that there are 2 versions of this program, a "large model" with all features implemented, and a "small model" that doesn't incorporate the colour requester. You can decide which one you want by making sure that the symbol FANCY is either defined or undefined during compilation. If you don't want the colour requester in your version (ie you compile with FANCY undefined) you don't need to compile the file colorreq.c or link with colorreq.o. John SHAR_EOF if test 462 -ne "`wc -c README`" then echo shar: error transmitting README '(should have been 462 characters)' fi cat << \SHAR_EOF > colour.doc /*------------------------------------------------------------------------*/ Colour - make a screen any colour you like, and load & save colour sets. ------ Copyright 1987, John Russell 5 Alderdice Place St. John's, Newfoundland Canada A1B 2P8 (709) 726-7847 UseNet: john13@garfield.uucp john13@garfield.mun.cdn Freely redistributable. /*------------------------------------------------------------------------*/ This program has 4 uses: First, you can experiment with different colour combinations by actually specifying numeric parameters for Red, Green, and Blue. You can also do the same with numerous programs which use "slider gadgets", but I include the capability for completeness. Note there's also a slider-gadget option in this program which you can enable at compile time. Second, once you have found a colour combination you like, whether it's on your Workbench screen, or on the screen of some other program, you can save it to disk. The format of the saved file is very simple - for a screen with N colours, there are N lines with 3 integer values each, for Red, Green, and Blue which combine to any of the Amiga's 4096 possible colours. Third, you can instantly load this definition back in, and specify the screen whose colours you want to change. You can thus have special colours to use when running a word processor, terminal program, CLI session, etc. I personally have about 5 sets of colours I use depending on my mood, if my eyes are tired, if my monitor will be on for a long time and I want to save a few phosphor molecules, etc. Fourth, if you want to experiment with different colour combinations interactively, you can bring up a colour window requestor on a specified screen. This has the standard slider gadgets for adjusting colours and also features like copy, undo, and range. The range option is the only one that is not immediately obvious -- after selecting it, choose 2 colours in the palette and all colours in between will be changed to a gradation somewhere between the two endpoints. NB: This last option of the colour requestor may be omitted when the program is compiled (this saves about 5K), since many other programs are available that accomplish the same function. However I prefer to leave it enabled since the code doesn't have to stay in memory at all times as it does in most other similar utilities. ------ SYNTAX ------ To set one particular colour, on one particular screen - colour set <screen> index red green blue To load a group of colours - colour load <screen> [from] <filename> To save a group of colours - colour save <screen> [to] <filename> To adjust colours with the mouse - colour adjust <screen> If the screen has no title, you can specify "-null" in place of the title, in which case the first screen with no title is used. Only the first word of the title is considered, and case is not important. When loading a colour file, the current directory is searched first and then the S: directory. If the S: directory must be searched, the suffix ".col" is assumed to be present; thus the following two forms are equivalent : colour load workbench from black-and-white colour load workbench from s:black-and-white.col Examples - colour set workbench 0 0 0 0 : sets Workbench background to black. colour load vt100 from modem.col : set VT100 seperate screen colours. colour save -null to dpaint.col : saves DPaint palette; screen has no title colour load workbench wb.col : use the old Workbench colours colour save mandelbrot mand.col : save a pretty-looking palette colour adjust workbench : fairly powerful interactive control ------------ DISTRIBUTION ------------ This program is freely redistributable; no fees beyond reasonable charge for media may be charged. Source is included with this initial posting, along with an encoded version of the executable. The source may be informative if you are interested in how colours relate to the structure of the screen they affect. If you pass this program on, please keep at least this documentation with the executable. In the spirit of Canadian nationalism, I ask that you not change the spelling of the excutable -- the "u" is supposed to be there. A portion of the source is derived from a public domain colour manipulation program. This section carries its own copyright notice and distribution conditions, which are present in the file colorreq.c if you have a copy of the source. No donations are solicited; however if you send me a disk with public domain software that you find useful (and possibly hasn't received wide distribution), I'll do the same from this end with some lesser-known programs that I use a lot. John SHAR_EOF if test 4724 -ne "`wc -c colour.doc`" then echo shar: error transmitting colour.doc '(should have been 4724 characters)' fi cat << \SHAR_EOF > colorreq.c /* I had nothing to do with this section other than removing a couple of */ /* Latticisms. -- John */ /* This color requester was hacked out of a Mandelbrot program by RJ Mical, Mike Ballantyne and R French. I'm not sure which one of these deserves most of the credit for the colour requester but I suspect RJ Mical. I merely neatened up the code, fixed it so it wouldn't go glitchy with fast ram, got rid of 33 unnecessary gadgets, put in the numeric display of the rgb values of the current colour, fixed the display so it looks reasonable in less than 5 bit planes (it used to always try to show 32 coloured squares, even if it only had two colours to work with), and made it as easy as possible to call from any program. To access it from your program simply put in the statement DoColorWindow(screen) where screen is a pointer to your screen. That's it. This program (subroutine actually) may be freely distributed as long as this notice giving credit to the four contributing authors is left intact. Pls address any correspondence regarding this program to : Bruce Dawson c/o CantorSoft. 407-1280 Haro St, Vancouver B.C. V6E1E8 */ #include <clib/macros.h> #include <exec/types.h> #include <exec/tasks.h> #include <exec/devices.h> #include <devices/keymap.h> #include <graphics/copper.h> #include <graphics/display.h> #include <graphics/gels.h> #include <graphics/regions.h> #include <hardware/blit.h> #include <intuition/intuition.h> #include <intuition/intuitionbase.h> /* Lattice sticks these two in a subdirectory. -- John */ #include <ctype.h> #include <stdio.h> #include <libraries/dos.h> /* === the definitions for the ColorWindow =============================== */ #define KNOB_BODY 0x1111 #define WINDOW_WIDTH 208 #define WINDOW_HEIGHT 106 #define WINDOW_LEFT (320 - WINDOW_WIDTH) #define WINDOW_TOP (200 - WINDOW_HEIGHT) #define CHARACTER_WIDTH 8 #define CHARACTER_HEIGHT 8 #define CURRENT_LEFT 6 #define CURRENT_TOP 16 #define CURRENT_RIGHT (CURRENT_LEFT + 15) #define CURRENT_BOTTOM (CURRENT_TOP + 29) #define COLORS_TOP 55 #define PROP_LEFT 38 #define PROP_TOP 14 #define PROP_WIDTH 149 #define PROP_HEIGHT 10 #define ACTIONS_LEFT 141 #define ACTIONS_TOP 51 #define ACTIONS_WIDTH (CHARACTER_WIDTH * 6 + 4) #define ACTIONS_HEIGHT 9 /* GREEN and RED are out of order. Do you wonder why? Some day I'll * tell you. =RJ= */ #define COLOR_COPY 0 #define COLOR_RANGE 1 #define COLOR_OK 2 #define COLOR_CANCEL 3 #define COLOR_GREEN 4 #define COLOR_RED 5 #define COLOR_BLUE 6 #define COLOR_GADGETS_COUNT 7 /*************************************************************************** * * Color window template initialization and routines, * for colorwindow and cyclewindow * * Throughout this file, the COLOR_RED and COLOR_GREEN gadgets are in the * opposite order you would expect. * ****************************************************************************/ struct TextAttr safefont = { (UBYTE *)"topaz.font", TOPAZ_EIGHTY, 0, 0, }; struct IntuiText string = { 1, 0, /* frontpen, backpen */ JAM2, /* drawmode */ 0,0, /* leftedge, topedge */ &safefont, /* pointer to font */ NULL, /* pointer to text data */ NULL /* next text */ }; SHORT actions_corners[] = { -1, -1, -1, ACTIONS_HEIGHT, ACTIONS_WIDTH, ACTIONS_HEIGHT, ACTIONS_WIDTH, -1, -1, -1, }; struct Border actions_border = { 0, 0, 1, 0, JAM1, 5, actions_corners, NULL, }; struct IntuiText actions_text[4] = { { /* "COPY" */ 1, 0, JAM2, 2 + CHARACTER_WIDTH, 1, &safefont, (UBYTE *)"COPY", NULL, }, { /* "RANGE" */ 1, 0, JAM2, 2 + (CHARACTER_WIDTH >> 1), 1, &safefont, (UBYTE *)"RANGE", NULL, }, { /* "OK" */ 1, 0, JAM2, 2 + (CHARACTER_WIDTH << 1), 1, &safefont, (UBYTE *)"OK", NULL, }, { /* "CANCEL" */ 1, 0, JAM2, 2, 1, &safefont, (UBYTE *)"CANCEL", NULL, }, }; /* ======================================================================== */ /* ======================================================================== */ /* ======================================================================== */ /* RJM anchor */ struct Image ColorPropsImages[3]; struct Image ColorImage = { CURRENT_LEFT, COLORS_TOP, /* left edge, top edge */ 15, 10, 0, /* width, height, depth */ NULL, /* image data */ 0, /* planepick */ 0, /* planeonoff - set later */ NULL /* NextImage */ }; struct PropInfo ColorPropsInfos[3] = { { /* COLOR_GREEN */ AUTOKNOB | FREEHORIZ, 0, 0, KNOB_BODY, 0, 0, 0, 0, 0, 0, 0, }, { /* COLOR_RED */ AUTOKNOB | FREEHORIZ, 0, 0, KNOB_BODY, 0, 0, 0, 0, 0, 0, 0, }, { /* COLOR_BLUE */ AUTOKNOB | FREEHORIZ, 0, 0, KNOB_BODY, 0, 0, 0, 0, 0, 0, 0, }, }; struct Gadget gadglist[COLOR_GADGETS_COUNT] = { { /* COLOR_COPY */ NULL, ACTIONS_LEFT, ACTIONS_TOP + (0 * (ACTIONS_HEIGHT + 3)), ACTIONS_WIDTH, ACTIONS_HEIGHT, GADGHCOMP, RELVERIFY, BOOLGADGET, (APTR)&actions_border, NULL, &actions_text[0], NULL, NULL, COLOR_COPY, NULL, }, { /* COLOR_RANGE */ &gadglist[COLOR_COPY], ACTIONS_LEFT, ACTIONS_TOP + (01 * (ACTIONS_HEIGHT + 3)), ACTIONS_WIDTH, ACTIONS_HEIGHT, GADGHCOMP, RELVERIFY, BOOLGADGET, (APTR)&actions_border, NULL, &actions_text[01], NULL, NULL, COLOR_RANGE, NULL, }, { /* COLOR_OK */ &gadglist[COLOR_RANGE], ACTIONS_LEFT, ACTIONS_TOP + (02 * (ACTIONS_HEIGHT + 3)), ACTIONS_WIDTH, ACTIONS_HEIGHT, GADGHCOMP, RELVERIFY, BOOLGADGET, (APTR)&actions_border, NULL, &actions_text[02], NULL, NULL, COLOR_OK, NULL, }, { /* COLOR_CANCEL */ &gadglist[COLOR_OK], ACTIONS_LEFT, ACTIONS_TOP + (03 * (ACTIONS_HEIGHT + 3)), ACTIONS_WIDTH, ACTIONS_HEIGHT, GADGHCOMP, RELVERIFY, BOOLGADGET, (APTR)&actions_border, NULL, &actions_text[03], NULL, NULL, COLOR_CANCEL, NULL, }, { /* COLOR_GREEN */ &gadglist[COLOR_CANCEL], PROP_LEFT, PROP_TOP + (01 * (PROP_HEIGHT + 1)), PROP_WIDTH, PROP_HEIGHT, GADGHCOMP | GADGIMAGE, FOLLOWMOUSE, PROPGADGET, (APTR)&ColorPropsImages[01], NULL, NULL, NULL, (APTR)&ColorPropsInfos[01], COLOR_GREEN, NULL, }, { /* COLOR_RED */ &gadglist[COLOR_GREEN], PROP_LEFT, PROP_TOP + (00 * (PROP_HEIGHT + 1)), PROP_WIDTH, PROP_HEIGHT, GADGHCOMP | GADGIMAGE, FOLLOWMOUSE, PROPGADGET, (APTR)&ColorPropsImages[00], NULL, NULL, NULL, (APTR)&ColorPropsInfos[00], COLOR_RED, NULL, }, { /* COLOR_BLUE */ &gadglist[COLOR_RED], PROP_LEFT, PROP_TOP + (02 * (PROP_HEIGHT + 1)), PROP_WIDTH, PROP_HEIGHT, GADGHCOMP | GADGIMAGE, FOLLOWMOUSE, PROPGADGET, (APTR)&ColorPropsImages[02], NULL, NULL, NULL, (APTR)&ColorPropsInfos[02], COLOR_BLUE, NULL, }, }; /*----------------------*/ /* Graphics definitions */ struct RastPort *rstport; struct ViewPort *vp; struct Window *ColorWindow; /***************************************************************************** * * Color initialization and routines * ****************************************************************************/ #define COPYCOLOR 1 #define RANGE_FIRST 2 #define RANGE_SECOND 3 USHORT ColorMode; USHORT SavePalette[32]; #define COLOR_IDCMP_FLAGS (GADGETDOWN | GADGETUP | MOUSEBUTTONS \ | MENUPICK | MOUSEMOVE | ACTIVEWINDOW | INACTIVEWINDOW) struct NewWindow ColorNewWindow = { WINDOW_LEFT, WINDOW_TOP, WINDOW_WIDTH, WINDOW_HEIGHT, -1, -1, COLOR_IDCMP_FLAGS, WINDOWDRAG | SMART_REFRESH | NOCAREREFRESH | ACTIVATE, NULL, /* struct Gadget *FirstGadget; */ NULL, /* struct Image *CheckMark; */ "Modify Colours.", /* the title text for this window */ NULL, /* struct Screen *Screen; */ NULL, /* struct BitMap *BitMap; */ 0, 0, 0, 0, CUSTOMSCREEN, /* USHORT Type; */ }; USHORT RangeFirst; /* the first selection of the range-color pair */ /* ======================================================================== */ /* ======================================================================== */ BOOL OpenColorWindow(screen, colours) struct Screen *screen; short colours; { REGISTER LONG i; ColorNewWindow.Screen = screen; ColorNewWindow.FirstGadget=&gadglist[COLOR_GADGETS_COUNT - 1]; ColorMode = NULL; if ( ! (ColorWindow = (struct Window *)OpenWindow(&ColorNewWindow))) return(FALSE); rstport = ColorWindow->RPort; SetAPen(rstport, 1); SetColorProps(); for (i = 0; i < 32; i++) SavePalette[i] = GetRGB4(vp->ColorMap, i); DrawColorWindow(colours); return(TRUE); } VOID CloseColorWindow(accept) BOOL accept; { if ( NOT ColorWindow) return; CloseWindow(ColorWindow); ColorWindow = NULL; if (NOT accept) LoadRGB4(vp, &SavePalette[0], 32L); } VOID ColorRange(first, last) SHORT first, last; { REGISTER SHORT i; LONG whole, redfraction, greenfraction, bluefraction; REGISTER USHORT rgb; SHORT firstred, firstgreen, firstblue; SHORT lastred, lastgreen, lastblue; SHORT workred, workgreen, workblue; if (first > last) { i = first; first = last; last = i; } /* I need to see a spread of at least two, where there's at least one * spot between the endpoints, else there's no work to do so I * might as well just return now. */ if (first >= last - 1) return; rgb = GetRGB4(vp->ColorMap, (LONG)first); firstred = (rgb >> 8) & 0xF; firstgreen = (rgb >> 4) & 0xF; firstblue = (rgb >> 0) & 0xF; rgb = GetRGB4(vp->ColorMap, (LONG)last); lastred = (rgb >> 8) & 0xF; lastgreen = (rgb >> 4) & 0xF; lastblue = (rgb >> 0) & 0xF; whole = ((LONG) (lastred - firstred)) << 16; redfraction = whole / (last - first); whole = ((LONG)(lastgreen - firstgreen)) << 16; greenfraction = whole / (last - first); whole = ((LONG)(lastblue - firstblue)) << 16; bluefraction = whole / (last - first); for (i = first + 1; i < last; i++) { lastred = (redfraction * (i - first) + 0x8000) >> 16; workred = firstred + lastred; lastgreen = (greenfraction * (i - first) + 0x8000) >> 16; workgreen = firstgreen + lastgreen; lastblue = (bluefraction * (i - first) + 0x8000) >> 16; workblue = firstblue + lastblue; SetRGB4(vp, (LONG) i,(LONG)workred,(LONG)workgreen,(LONG)workblue); } } BOOL colorchosen(pen) short pen; { REGISTER USHORT rgb; complementbox(rstport, rstport->FgPen); complementbox(rstport, pen); if (ColorMode == COPYCOLOR) { rgb = GetRGB4(vp->ColorMap, (LONG)rstport->FgPen); SetRGB4(vp, pen, (rgb >> 8), (rgb >> 4), rgb ); ColorMode = NULL; } if (ColorMode == RANGE_FIRST) { ColorMode = RANGE_SECOND; RangeFirst = pen; } else if (ColorMode == RANGE_SECOND) { ColorMode = NULL; ColorRange(RangeFirst, pen); } SetAPen(rstport, (LONG)pen); rgb = GetRGB4(vp->ColorMap, (LONG)pen); ColorRectFill((LONG)pen); SetColorProps(); } BOOL GadgetGotten(gadgetnum) short gadgetnum; { switch (gadgetnum) { case COLOR_OK: CloseColorWindow(TRUE); return(FALSE); case COLOR_CANCEL: CloseColorWindow(FALSE); return(FALSE); case COLOR_COPY: ColorMode = COPYCOLOR; break; case COLOR_RANGE: ColorMode = RANGE_FIRST; break; } return(TRUE); } ModifyColors() { USHORT pen; REGISTER USHORT newred, newgreen, newblue; pen = rstport->FgPen; newred = ((struct PropInfo *) gadglist[COLOR_RED].SpecialInfo)->HorizPot >> 12; newgreen = ((struct PropInfo *) gadglist[COLOR_GREEN].SpecialInfo)->HorizPot >> 12; newblue = ((struct PropInfo *) gadglist[COLOR_BLUE].SpecialInfo)->HorizPot >> 12; SetRGB4(vp, (LONG)pen, (LONG)newred, (LONG)newgreen, (LONG)newblue); printcolors(newred, newgreen, newblue); } printcolors(red, green, blue) USHORT red, green, blue; { char *buffer = " "; sprintf(buffer, "%2d", red); printtext(buffer, PROP_WIDTH + PROP_LEFT+2, CURRENT_TOP); sprintf(buffer, "%2d", green); printtext(buffer, PROP_WIDTH + PROP_LEFT+2, CURRENT_TOP+(PROP_HEIGHT+1)); sprintf(buffer, "%2d", blue); printtext(buffer, PROP_WIDTH + PROP_LEFT+2, CURRENT_TOP + (PROP_HEIGHT+1) * 2); } DrawColorWindow(colours) { REGISTER SHORT i; ColorRectFill((LONG)rstport->FgPen); DrawBox(rstport, CURRENT_LEFT-2,CURRENT_TOP-2,CURRENT_RIGHT+2,CURRENT_BOTTOM+2); DrawBox(rstport, CURRENT_LEFT-2, COLORS_TOP-2, CURRENT_LEFT+(8 * 15)+1, COLORS_TOP + (4 * 10) + 1); printtext("R", CURRENT_RIGHT + 6, CURRENT_TOP); printtext("G", CURRENT_RIGHT + 6, CURRENT_TOP + PROP_HEIGHT+1); printtext("B", CURRENT_RIGHT + 6, CURRENT_TOP + (PROP_HEIGHT+1)* 2); for (i = 0; i < colours; i++) { ColorImage.PlaneOnOff = i; DrawImage(rstport, &ColorImage, (i % 8) * 15, (i / 8) * 10); } complementbox(rstport, 1); /* starting colour is colour 1 */ } SetColorProps() { USHORT rgb; REGISTER USHORT red, green, blue; SHORT greenpos, redpos, bluepos; redpos = RemoveGadget(ColorWindow, &gadglist[COLOR_RED]); greenpos = RemoveGadget(ColorWindow, &gadglist[COLOR_GREEN]); bluepos = RemoveGadget(ColorWindow, &gadglist[COLOR_BLUE]); rgb = GetRGB4(vp->ColorMap, (LONG)rstport->FgPen); red = (rgb >> 8) & 0xF; green = (rgb >> 4) & 0xF; blue = (rgb >> 0) & 0xF; ((struct PropInfo *)gadglist[COLOR_RED].SpecialInfo)->HorizPot = (red << 12) | (red << 8) | (red << 4) | red; ((struct PropInfo *)gadglist[COLOR_GREEN].SpecialInfo)->HorizPot = (green << 12) | (green << 8) | (green << 4) | green; ((struct PropInfo *)gadglist[COLOR_BLUE].SpecialInfo)->HorizPot = (blue << 12) | (blue << 8) | (blue << 4) | blue; AddGadget(ColorWindow,&gadglist[COLOR_BLUE], (LONG)bluepos); AddGadget(ColorWindow,&gadglist[COLOR_GREEN],(LONG)greenpos); AddGadget(ColorWindow,&gadglist[COLOR_RED], (LONG)redpos); RefreshGadgets(&gadglist[COLOR_GADGETS_COUNT-1],ColorWindow); printcolors(red, green, blue); } ColorRectFill( pen) LONG pen; { SetAPen(rstport, pen); SetDrMd(rstport, JAM2); WaitBOVP(vp); RectFill(rstport, CURRENT_LEFT, CURRENT_TOP, CURRENT_RIGHT, CURRENT_BOTTOM); } VOID DoColorWindow(screen) struct Screen *screen; { BOOL GadgetGotten(), OpenColorWindow(); REGISTER struct IntuiMessage *message; REGISTER ULONG class; REGISTER struct Gadget *gadget; USHORT bitplanes, colours, code; short number, x, y; vp = &screen->ViewPort; bitplanes = screen->BitMap.Depth; for (colours = 1; bitplanes; bitplanes--) colours *= 2; if (colours > 32) colours = 32; if (NOT OpenColorWindow(screen, colours)) return; FOREVER { Wait((1L << ColorWindow->UserPort->mp_SigBit)); while (message = (struct IntuiMessage *)GetMsg(ColorWindow->UserPort)) { class = message->Class; code = message->Code; x = message->MouseX; y = message->MouseY; if (class != MOUSEBUTTONS) gadget = (struct Gadget *)(message->IAddress); ReplyMsg(message); switch (class) { case GADGETDOWN: case GADGETUP: if ( NOT GadgetGotten(gadget->GadgetID)) return; break; case MOUSEBUTTONS: if ( x >= CURRENT_LEFT && x < CURRENT_LEFT + 8 * 15) if (y >= COLORS_TOP && y < COLORS_TOP + 4 * 10) { number = (x-CURRENT_LEFT)/15 + ((y-COLORS_TOP)/10)*8; if (number < colours && code == SELECTDOWN) colorchosen(number); } break; case MOUSEMOVE: ModifyColors(); break; default: break; } } } } DrawBox(rp, x1, y1, x2, y2) struct RastPort *rp; short x1, y1, x2, y2; /* draws a box without overlapping the edges (in case of complement mode) */ { Move(rp, x1, y1 + SIGN(y2 - y1)); Draw(rp, x1, y2); Move(rp, x1 + SIGN(x2 - x1), y2); Draw(rp, x2, y2); Move(rp, x2, y2 - SIGN(y2 - y1)); Draw(rp, x2, y1); Move(rp, x2 - SIGN(x2 - x1), y1); Draw(rp, x1, y1); } complementbox(rp, colours) short colours; { short x, y; x = CURRENT_LEFT + (colours % 8) * 15; y = COLORS_TOP + (colours / 8) * 10; SetDrMd(rp, COMPLEMENT); DrawBox(rp, x, y, x + 14, y + 9); SetDrMd(rp, JAM1); } printtext(text, x, y) char *text; short x, y; { string.IText = text; PrintIText(rstport, &string, x, y); } SHAR_EOF if test 17372 -ne "`wc -c colorreq.c`" then echo shar: error transmitting colorreq.c '(should have been 17372 characters)' fi cat << \SHAR_EOF > colour.c /* * Colour.c - a program for manipulating the colours of screens. * * Written because I like one set of colours in a CLI and another in * my terminal window, and can't always afford the memory for another * screen. Plus, I like a more direct way of changing colours than * twiddling a bunch of slider gadgets (although that way has its uses * too, so I include the capability). Lastly, Americans don't know * how to spell "colour" :-). * * Features include: * - save all colours from a given screen * - load a set of colours into a given screen * - set a particular colour register in a given screen * - adjust screen colours interactively (OPTIONAL) * * Copyright 1987, John Russell * * 5 Alderdice Place * St. John's, Newfoundland * Canada A1B 2P8 * (709) 726-7847 * * Freely redistributable. */ /* Manx users compile with "+l" just in case */ /* These includes might not be enough, I use precompiled includes. */ /* anything to do with screens & viewports may be required */ #include <intuition/intuition.h> #include <intuition/intuitionbase.h> #include <stdio.h> #include "ctype.h" #define LOAD 1 #define SAVE 2 #define SET 3 #define ADJUST 4 /* if "fancy" is defined, you have the option to adjust on-the-fly */ #define FANCY 1 /* debug = "puts" to enable tracing, leave blank to disable */ #define debug(x) struct IntuitionBase *IntuitionBase=NULL; struct GfxBase *GfxBase=NULL; char *usage = "\n\ Bad syntax.\n\n\ Usage 1: colour load <screen | \"-null\"> [from] <filename>.\n\ Usage 2: colour save <screen | \"-null\"> [to] <filename>.\n\ Usage 3: colour set <screen | \"-null\"> index R G B.\n\ Usage 4: colour adjust <screen | \"-null\">.\n\n\ Note - Specify screen by first word of title (case doesn't matter).\n\ Note - Load file is searched for as \"file\" and \"s:file.col\".\n"; main(argc,argv) int argc; char *argv[]; { struct Screen *screen; /* which screen to consider */ struct ViewPort *vp; /* controlling viewport for screen */ FILE *fp; /* for loading & saving */ short good_args = 0; /* right # arguments for syntax? */ short mode = 0; /* what type of command is it? */ int r,g,b; int i,n,fname,depth; /* depth == number of colours in screen */ UWORD colour; /* I only remember these typedefs */ struct ColorMap *map; /* when reading includes :-) */ char name[80]; /* check for valid arguments and commands */ if (argc < 3) /* always need at least 3 */ { puts(usage); exit(0); } else if (!compare(argv[1],"load")) { debug("Asked to load a colour set."); mode = LOAD; if (argc == 4 || (!compare(argv[3],"from") && argc == 5)) good_args = 1; } else if (!compare(argv[1],"save")) { debug("Asked to save a colour set."); mode = SAVE; if (argc == 4 || (!compare(argv[3],"to") && argc == 5)) good_args = 1; } else if (!compare(argv[1],"set")) { debug("Asked to set a single colour."); mode = SET; if (argc == 7) good_args = 1; } #ifdef FANCY else if (!compare(argv[1],"adjust")) { debug("Asked to adjust screen colours."); mode = ADJUST; if (argc == 3) good_args = 1; } #endif fname = argc - 1; /* argv[fname] = file for load & save */ if (!good_args) { puts(usage); exit(0); } debug("Arguments are legal."); if (! (IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",33L))) { puts("Please use Kickstart/Workbench V1.2 for latest Intuition."); exit(0); } if (! (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",33L))) { puts("Please use Kickstart/Workbench V1.2 for latest Graphics."); exit(0); } screen = IntuitionBase->FirstScreen; /* the target screen is found when the first word of the title matches the 2nd argument specified, OR if the 2nd argument is -null, the first screen with NO title is matched (eg the DPaint screen) */ LockIBase(NULL); /* prevent window list from changing while in loop */ while (screen) /* do all screens */ { if (!compare(argv[2],screen->Title) || ((screen->Title == NULL) && (!compare(argv[2],"-null")))) { UnlockIBase(NULL); debug("Found the indicated screen."); vp = &screen->ViewPort; /* don't like 'em much myself */ map = vp->ColorMap; depth = 1 << screen->BitMap.Depth; /* no easier way? */ switch (mode) { case SET: i = atoi(argv[3]); /* colour index */ r = atoi(argv[4]); /* RGB values */ g = atoi(argv[5]); b = atoi(argv[6]); if (i < depth) { SetRGB4(vp,i,r,g,b); debug("Set single colour."); } else puts("Illegal colour index for this screen."); break; case LOAD: /* (LA Law is on in the background) */ /* search current directory and S: for file */ /* look for for file as "file" and "s:file.col" */ if (!(fp = fopen(argv[fname],"r"))) { /* Boy do I hate C string functions! */ strcpy(name,"s:"); strcat(name,argv[fname]); strcat(name,".col"); debug("Searching for file in S: directory."); fp = fopen(name,"r"); } if (!fp) { puts("Unable to open load file!"); goto QUIT; } debug("Opened file successfully."); /* This is an *ugly* loop condition! */ for (i=0; (i < depth) && (fscanf(fp,"%d %d %d\n",&r,&g,&b)==3); i++) { SetRGB4(vp,i,r,g,b); debug("Set a colour."); } fclose(fp); break; case SAVE: fp = fopen(argv[fname],"w"); if (!fp) { puts("Unable to open save file!"); goto QUIT; } for (i=0; i < depth; i++) { colour = GetRGB4(map,i); /* each colour component encoded by 4 bits */ r = (colour & 0xf00) >> 8; g = (colour & 0x0f0) >> 4; b = (colour & 0x00f); fprintf(fp,"%d %d %d\n",r,g,b); debug("Saved a colour."); } fclose(fp); break; #ifdef FANCY case ADJUST: ScreenToFront(screen); DoColorWindow(screen); /* I can't take credit for */ break; /* this section */ #endif default: debug("Illegal instruction mode."); break; } goto QUIT; /* only match 1 screen */ } screen = screen->NextScreen; } UnlockIBase(NULL); /* didn't find the screen at all */ debug("Didn't find indicated screen."); QUIT: CloseLibrary(IntuitionBase); CloseLibrary(GfxBase); } /* case-insensitive string comparison, with \0 and space as end conditions */ compare(string1,string2) char *string1,*string2; { while ((*string1 != '\0') && (*string1 != ' ')) { if (toupper(*(string1++)) != toupper(*(string2++))) return(1); } return(0); /* return weird values like strcmp() */ } SHAR_EOF if test 6787 -ne "`wc -c colour.c`" then echo shar: error transmitting colour.c '(should have been 6787 characters)' fi cat << \SHAR_EOF > amber.col 0 0 1 13 13 2 0 0 8 15 15 15 SHAR_EOF if test 29 -ne "`wc -c amber.col`" then echo shar: error transmitting amber.col '(should have been 29 characters)' fi cat << \SHAR_EOF > cyan.col 0 0 0 0 15 15 0 0 7 15 15 0 SHAR_EOF if test 28 -ne "`wc -c cyan.col`" then echo shar: error transmitting cyan.col '(should have been 28 characters)' fi cat << \SHAR_EOF > gray.col 3 3 3 15 15 15 0 0 0 15 15 0 SHAR_EOF if test 29 -ne "`wc -c gray.col`" then echo shar: error transmitting gray.col '(should have been 29 characters)' fi cat << \SHAR_EOF > green.col 0 2 0 0 13 0 0 0 6 11 11 11 SHAR_EOF if test 28 -ne "`wc -c green.col`" then echo shar: error transmitting green.col '(should have been 28 characters)' fi cat << \SHAR_EOF > lace.col 5 5 5 0 0 0 0 2 7 8 8 0 SHAR_EOF if test 24 -ne "`wc -c lace.col`" then echo shar: error transmitting lace.col '(should have been 24 characters)' fi cat << \SHAR_EOF > modem.col 0 0 0 10 10 10 12 12 12 12 0 0 SHAR_EOF if test 31 -ne "`wc -c modem.col`" then echo shar: error transmitting modem.col '(should have been 31 characters)' fi cat << \SHAR_EOF > pastel.col 6 0 10 15 14 7 4 4 7 13 9 7 SHAR_EOF if test 28 -ne "`wc -c pastel.col`" then echo shar: error transmitting pastel.col '(should have been 28 characters)' fi cat << \SHAR_EOF > red.col 6 0 0 13 9 0 0 2 4 15 15 15 SHAR_EOF if test 28 -ne "`wc -c red.col`" then echo shar: error transmitting red.col '(should have been 28 characters)' fi cat << \SHAR_EOF > royal.col 2 0 4 15 14 0 0 0 8 15 15 15 SHAR_EOF if test 29 -ne "`wc -c royal.col`" then echo shar: error transmitting royal.col '(should have been 29 characters)' fi cat << \SHAR_EOF > silver.col 6 8 9 0 0 0 0 0 8 15 15 15 SHAR_EOF if test 27 -ne "`wc -c silver.col`" then echo shar: error transmitting silver.col '(should have been 27 characters)' fi cat << \SHAR_EOF > silver2.col 6 8 9 15 15 15 0 0 11 0 0 0 SHAR_EOF if test 28 -ne "`wc -c silver2.col`" then echo shar: error transmitting silver2.col '(should have been 28 characters)' fi cat << \SHAR_EOF > wb.col 0 0 7 15 15 15 0 0 2 15 8 0 SHAR_EOF if test 28 -ne "`wc -c wb.col`" then echo shar: error transmitting wb.col '(should have been 28 characters)' fi # End of shell archive exit 0