1a966c04fSmrg/* 2a966c04fSmrg * Copyright (C) 19896 Lorens Younes 3a966c04fSmrg * 4a966c04fSmrg * Permission is hereby granted, free of charge, to any person obtaining a copy 5a966c04fSmrg * of this software and associated documentation files (the "Software"), to 6a966c04fSmrg * deal in the Software without restriction, including without limitation the 7a966c04fSmrg * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8a966c04fSmrg * sell copies of the Software, and to permit persons to whom the Software is 9a966c04fSmrg * furnished to do so, subject to the following conditions: 10a966c04fSmrg * 11a966c04fSmrg * The above copyright notice and this permission notice shall be included in 12a966c04fSmrg * all copies or substantial portions of the Software. 13a966c04fSmrg * 14a966c04fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15a966c04fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16a966c04fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17a966c04fSmrg * Lorens Younes BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 18a966c04fSmrg * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19a966c04fSmrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20a966c04fSmrg * 21a966c04fSmrg * Except as contained in this notice, the name of Lorens Younes shall not be 22a966c04fSmrg * used in advertising or otherwise to promote the sale, use or other dealings 23a966c04fSmrg * in this Software without prior written authorization from Lorens Younes. 24a966c04fSmrg */ 25a966c04fSmrg 26a966c04fSmrg/*****************************************************************************\ 27a966c04fSmrg* amigax.c: * 28a966c04fSmrg* * 29a966c04fSmrg* XPM library * 30a966c04fSmrg* Emulates some Xlib functionality for Amiga. * 31a966c04fSmrg* * 32a966c04fSmrg* Developed by Lorens Younes (d93-hyo@nada.kth.se) 7/95 * 33a966c04fSmrg* Revised 4/96 * 34a966c04fSmrg\*****************************************************************************/ 35a966c04fSmrg 36a966c04fSmrg#ifdef HAVE_CONFIG_H 37a966c04fSmrg#include <config.h> 38a966c04fSmrg#endif 39a966c04fSmrg#include "XpmI.h" 40a966c04fSmrg#include "amigax.h" 41a966c04fSmrg 42a966c04fSmrg#include <graphics/gfxbase.h> 43a966c04fSmrg#include <intuition/screens.h> 44a966c04fSmrg 45a966c04fSmrg#include <proto/exec.h> 46a966c04fSmrg 47a966c04fSmrg 48a966c04fSmrgstatic struct RastPort * 49a966c04fSmrgAllocRastPort (unsigned int, unsigned int, unsigned int); 50a966c04fSmrgstatic void 51a966c04fSmrgFreeRastPort (struct RastPort *, unsigned int,unsigned int); 52a966c04fSmrg 53a966c04fSmrg 54a966c04fSmrgstatic struct RastPort * 55a966c04fSmrgAllocRastPort ( 56a966c04fSmrg unsigned int width, 57a966c04fSmrg unsigned int height, 58a966c04fSmrg unsigned int depth) 59a966c04fSmrg{ 60a966c04fSmrg struct RastPort *rp; 6197cf2ee2Smrg 62a966c04fSmrg rp = XpmMalloc (sizeof (*rp)); 63a966c04fSmrg if (rp != NULL) 64a966c04fSmrg { 65a966c04fSmrg InitRastPort (rp); 66a966c04fSmrg if (GfxBase->LibNode.lib_Version >= 39) 67a966c04fSmrg { 68a966c04fSmrg rp->BitMap = AllocBitMap (width, height, depth, BMF_CLEAR, NULL); 69a966c04fSmrg if (rp->BitMap == NULL) 70a966c04fSmrg { 71a966c04fSmrg FreeRastPort (rp, width, height); 72a966c04fSmrg return NULL; 73a966c04fSmrg } 74a966c04fSmrg } 75a966c04fSmrg else 76a966c04fSmrg { 77a966c04fSmrg unsigned int i; 7897cf2ee2Smrg 79a966c04fSmrg rp->BitMap = XpmMalloc (sizeof (*rp->BitMap)); 80a966c04fSmrg if (rp->BitMap == NULL) 81a966c04fSmrg { 82a966c04fSmrg FreeRastPort (rp, width, height); 83a966c04fSmrg return NULL; 84a966c04fSmrg } 8597cf2ee2Smrg 86a966c04fSmrg InitBitMap (rp->BitMap, depth, width, height); 87a966c04fSmrg for (i = 0; i < depth; ++i) 88a966c04fSmrg rp->BitMap->Planes[i] = NULL; 89a966c04fSmrg for (i = 0; i < depth; ++i) 90a966c04fSmrg { 91a966c04fSmrg rp->BitMap->Planes[i] = (PLANEPTR)AllocRaster (width, height); 92a966c04fSmrg if (rp->BitMap->Planes[i] == NULL) 93a966c04fSmrg { 94a966c04fSmrg FreeRastPort (rp, width, height); 95a966c04fSmrg return NULL; 96a966c04fSmrg } 97a966c04fSmrg } 98a966c04fSmrg } 99a966c04fSmrg } 10097cf2ee2Smrg 101a966c04fSmrg return rp; 102a966c04fSmrg} 103a966c04fSmrg 104a966c04fSmrg 105a966c04fSmrgstatic void 106a966c04fSmrgFreeRastPort ( 107a966c04fSmrg struct RastPort *rp, 108a966c04fSmrg unsigned int width, 109a966c04fSmrg unsigned int height) 110a966c04fSmrg{ 111a966c04fSmrg if (rp != NULL) 112a966c04fSmrg { 113a966c04fSmrg if (rp->BitMap != NULL) 114a966c04fSmrg { 115a966c04fSmrg WaitBlit (); 116a966c04fSmrg if (GfxBase->LibNode.lib_Version >= 39) 117a966c04fSmrg FreeBitMap (rp->BitMap); 118a966c04fSmrg else 119a966c04fSmrg { 120a966c04fSmrg unsigned int i; 12197cf2ee2Smrg 122a966c04fSmrg for (i = 0; i < rp->BitMap->Depth; ++i) 123a966c04fSmrg { 124a966c04fSmrg if (rp->BitMap->Planes[i] != NULL) 125a966c04fSmrg FreeRaster (rp->BitMap->Planes[i], width, height); 126a966c04fSmrg } 127a966c04fSmrg XpmFree (rp->BitMap); 128a966c04fSmrg } 129a966c04fSmrg } 130a966c04fSmrg XpmFree (rp); 131a966c04fSmrg } 132a966c04fSmrg} 133a966c04fSmrg 134a966c04fSmrg 135a966c04fSmrgXImage * 136a966c04fSmrgAllocXImage ( 137a966c04fSmrg unsigned int width, 138a966c04fSmrg unsigned int height, 139a966c04fSmrg unsigned int depth) 140a966c04fSmrg{ 141a966c04fSmrg XImage *img; 14297cf2ee2Smrg 143a966c04fSmrg img = XpmMalloc (sizeof (*img)); 144a966c04fSmrg if (img != NULL) 145a966c04fSmrg { 146a966c04fSmrg img->width = width; 147a966c04fSmrg img->height = height; 148a966c04fSmrg img->rp = AllocRastPort (img->width, img->height, depth); 149a966c04fSmrg if (img->rp == NULL) 150a966c04fSmrg { 151a966c04fSmrg FreeXImage (img); 152a966c04fSmrg return NULL; 153a966c04fSmrg } 154a966c04fSmrg } 15597cf2ee2Smrg 156a966c04fSmrg return img; 157a966c04fSmrg} 158a966c04fSmrg 159a966c04fSmrg 160a966c04fSmrgint 161a966c04fSmrgFreeXImage ( 162a966c04fSmrg XImage *ximage) 163a966c04fSmrg{ 164a966c04fSmrg if (ximage != NULL) 165a966c04fSmrg { 166a966c04fSmrg FreeRastPort (ximage->rp, ximage->width, ximage->height); 167a966c04fSmrg XpmFree (ximage); 168a966c04fSmrg } 16997cf2ee2Smrg 170a966c04fSmrg return Success; 171a966c04fSmrg} 172a966c04fSmrg 173a966c04fSmrg 174a966c04fSmrgint 175a966c04fSmrgXPutPixel ( 176a966c04fSmrg XImage *ximage, 177a966c04fSmrg int x, 178a966c04fSmrg int y, 179a966c04fSmrg unsigned long pixel) 180a966c04fSmrg{ 181a966c04fSmrg SetAPen (ximage->rp, pixel); 182a966c04fSmrg WritePixel (ximage->rp, x, y); 18397cf2ee2Smrg 184a966c04fSmrg return Success; 185a966c04fSmrg} 186a966c04fSmrg 187a966c04fSmrg 188a966c04fSmrgStatus 189a966c04fSmrgAllocBestPen ( 190a966c04fSmrg Colormap colormap, 191a966c04fSmrg XColor *screen_in_out, 192a966c04fSmrg unsigned long precision, 193a966c04fSmrg Bool fail_if_bad) 194a966c04fSmrg{ 195a966c04fSmrg if (GfxBase->LibNode.lib_Version >= 39) 196a966c04fSmrg { 197a966c04fSmrg unsigned long r, g, b; 19897cf2ee2Smrg 199a966c04fSmrg r = screen_in_out->red * 0x00010001; 200a966c04fSmrg g = screen_in_out->green * 0x00010001; 201a966c04fSmrg b = screen_in_out->blue * 0x00010001; 202a966c04fSmrg screen_in_out->pixel = ObtainBestPen (colormap, r, g, b, 203a966c04fSmrg OBP_Precision, precision, 204a966c04fSmrg OBP_FailIfBad, fail_if_bad, 205a966c04fSmrg TAG_DONE); 206a966c04fSmrg if (screen_in_out->pixel == -1) 207a966c04fSmrg return False; 20897cf2ee2Smrg 209a966c04fSmrg QueryColor (colormap, screen_in_out); 210a966c04fSmrg } 211a966c04fSmrg else 212a966c04fSmrg { 213a966c04fSmrg XColor nearest, trial; 214a966c04fSmrg long nearest_delta, trial_delta; 215a966c04fSmrg int num_cells, i; 21697cf2ee2Smrg 217a966c04fSmrg num_cells = colormap->Count; 218a966c04fSmrg nearest.pixel = 0; 219a966c04fSmrg QueryColor (colormap, &nearest); 220a966c04fSmrg nearest_delta = ((((screen_in_out->red >> 8) - (nearest.red >> 8)) 221a966c04fSmrg * ((screen_in_out->red >> 8) - (nearest.red >> 8))) 222a966c04fSmrg + 223a966c04fSmrg (((screen_in_out->green >> 8) - (nearest.green >> 8)) 224a966c04fSmrg * ((screen_in_out->green >> 8) - (nearest.green >> 8))) 225a966c04fSmrg + 226a966c04fSmrg (((screen_in_out->blue >> 8) - (nearest.blue >> 8)) 227a966c04fSmrg * ((screen_in_out->blue >> 8) - (nearest.blue >> 8)))); 228a966c04fSmrg for (i = 1; i < num_cells; i++) 229a966c04fSmrg { 230a966c04fSmrg /* precision and fail_if_bad is ignored under pre V39 */ 231a966c04fSmrg trial.pixel = i; 232a966c04fSmrg QueryColor (colormap, &trial); 233a966c04fSmrg trial_delta = ((((screen_in_out->red >> 8) - (trial.red >> 8)) 234a966c04fSmrg * ((screen_in_out->red >> 8) - (trial.red >> 8))) 235a966c04fSmrg + 236a966c04fSmrg (((screen_in_out->green >> 8) - (trial.green >> 8)) 237a966c04fSmrg * ((screen_in_out->green >> 8) - (trial.green >> 8))) 238a966c04fSmrg + 239a966c04fSmrg (((screen_in_out->blue >> 8) - (trial.blue >> 8)) 240a966c04fSmrg * ((screen_in_out->blue >> 8) - (trial.blue >> 8)))); 241a966c04fSmrg if (trial_delta < nearest_delta) 242a966c04fSmrg { 243a966c04fSmrg nearest = trial; 244a966c04fSmrg nearest_delta = trial_delta; 245a966c04fSmrg } 246a966c04fSmrg } 247a966c04fSmrg screen_in_out->pixel = nearest.pixel; 248a966c04fSmrg screen_in_out->red = nearest.red; 249a966c04fSmrg screen_in_out->green = nearest.green; 250a966c04fSmrg screen_in_out->blue = nearest.blue; 251a966c04fSmrg } 25297cf2ee2Smrg 253a966c04fSmrg return True; 254a966c04fSmrg} 255a966c04fSmrg 256a966c04fSmrg 257a966c04fSmrgint 258a966c04fSmrgFreePens ( 259a966c04fSmrg Colormap colormap, 260a966c04fSmrg unsigned long *pixels, 261a966c04fSmrg int npixels) 262a966c04fSmrg{ 263a966c04fSmrg if (GfxBase->LibNode.lib_Version >= 39) 264a966c04fSmrg { 265a966c04fSmrg int i; 26697cf2ee2Smrg 267a966c04fSmrg for (i = 0; i < npixels; i++) 268a966c04fSmrg ReleasePen (colormap, pixels[i]); 269a966c04fSmrg } 27097cf2ee2Smrg 271a966c04fSmrg return Success; 272a966c04fSmrg} 273a966c04fSmrg 274a966c04fSmrg 275a966c04fSmrgStatus 276a966c04fSmrgParseColor ( 277a966c04fSmrg char *spec, 278a966c04fSmrg XColor *exact_def_return) 279a966c04fSmrg{ 280a966c04fSmrg int spec_length; 28197cf2ee2Smrg 282a966c04fSmrg if (spec == 0) 283a966c04fSmrg return False; 28497cf2ee2Smrg 285a966c04fSmrg spec_length = strlen(spec); 286a966c04fSmrg if (spec[0] == '#') 287a966c04fSmrg { 288a966c04fSmrg int hexlen; 289a966c04fSmrg char hexstr[10]; 29097cf2ee2Smrg 291a966c04fSmrg hexlen = (spec_length - 1) / 3; 292a966c04fSmrg if (hexlen < 1 || hexlen > 4 || hexlen * 3 != spec_length - 1) 293a966c04fSmrg return False; 29497cf2ee2Smrg 295a966c04fSmrg hexstr[hexlen] = '\0'; 296a966c04fSmrg strncpy (hexstr, spec + 1, hexlen); 297a966c04fSmrg exact_def_return->red = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen); 298a966c04fSmrg strncpy (hexstr, spec + 1 + hexlen, hexlen); 299a966c04fSmrg exact_def_return->green = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen); 300a966c04fSmrg strncpy (hexstr, spec + 1 + 2 * hexlen, hexlen); 301a966c04fSmrg exact_def_return->blue = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen); 30297cf2ee2Smrg 303a966c04fSmrg return True; 304a966c04fSmrg } 305a966c04fSmrg else 306a966c04fSmrg { 307a966c04fSmrg FILE *rgbf; 308a966c04fSmrg int items, red, green, blue; 309a966c04fSmrg char line[512], name[512]; 310a966c04fSmrg Bool success = False; 31197cf2ee2Smrg 312a966c04fSmrg rgbf = fopen ("LIBS:rgb.txt", "r"); 313a966c04fSmrg if (rgbf == NULL) 314a966c04fSmrg return False; 31597cf2ee2Smrg 316a966c04fSmrg while (fgets(line, sizeof (line), rgbf) && !success) 317a966c04fSmrg { 318a966c04fSmrg items = sscanf (line, "%d %d %d %[^\n]\n", 319a966c04fSmrg &red, &green, &blue, name); 320a966c04fSmrg if (items != 4) 321a966c04fSmrg continue; 32297cf2ee2Smrg 323a966c04fSmrg if (red < 0 || red > 0xFF 324a966c04fSmrg || green < 0 || green > 0xFF 325a966c04fSmrg || blue < 0 || blue > 0xFF) 326a966c04fSmrg { 327a966c04fSmrg continue; 328a966c04fSmrg } 32997cf2ee2Smrg 330a966c04fSmrg if (0 == xpmstrcasecmp (spec, name)) 331a966c04fSmrg { 332a966c04fSmrg exact_def_return->red = red * 0x0101; 333a966c04fSmrg exact_def_return->green = green * 0x0101; 334a966c04fSmrg exact_def_return->blue = blue * 0x0101; 335a966c04fSmrg success = True; 336a966c04fSmrg } 337a966c04fSmrg } 338a966c04fSmrg fclose (rgbf); 33997cf2ee2Smrg 340a966c04fSmrg return success; 341a966c04fSmrg } 342a966c04fSmrg} 343a966c04fSmrg 344a966c04fSmrg 345a966c04fSmrgint 346a966c04fSmrgQueryColor ( 347a966c04fSmrg Colormap colormap, 348a966c04fSmrg XColor *def_in_out) 349a966c04fSmrg{ 350a966c04fSmrg if (GfxBase->LibNode.lib_Version >= 39) 351a966c04fSmrg { 352a966c04fSmrg unsigned long rgb[3]; 35397cf2ee2Smrg 354a966c04fSmrg GetRGB32 (colormap, def_in_out->pixel, 1, rgb); 355a966c04fSmrg def_in_out->red = rgb[0] >> 16; 356a966c04fSmrg def_in_out->green = rgb[1] >> 16; 357a966c04fSmrg def_in_out->blue = rgb[2] >> 16; 358a966c04fSmrg } 359a966c04fSmrg else 360a966c04fSmrg { 361a966c04fSmrg unsigned short rgb; 36297cf2ee2Smrg 363a966c04fSmrg rgb = GetRGB4 (colormap, def_in_out->pixel); 364a966c04fSmrg def_in_out->red = ((rgb >> 8) & 0xF) * 0x1111; 365a966c04fSmrg def_in_out->green = ((rgb >> 4) & 0xF) * 0x1111; 366a966c04fSmrg def_in_out->blue = (rgb & 0xF) * 0x1111; 367a966c04fSmrg } 36897cf2ee2Smrg 369a966c04fSmrg return Success; 370a966c04fSmrg} 371a966c04fSmrg 372a966c04fSmrg 373a966c04fSmrgint 374a966c04fSmrgQueryColors ( 375a966c04fSmrg Colormap colormap, 376a966c04fSmrg XColor *defs_in_out, 377a966c04fSmrg int ncolors) 378a966c04fSmrg{ 379a966c04fSmrg int i; 38097cf2ee2Smrg 381a966c04fSmrg for (i = 0; i < ncolors; i++) 382a966c04fSmrg QueryColor (colormap, &defs_in_out[i]); 38397cf2ee2Smrg 384a966c04fSmrg return Success; 385a966c04fSmrg} 386