/* * Copyright (C) 19896 Lorens Younes * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * Lorens Younes BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name of Lorens Younes shall not be * used in advertising or otherwise to promote the sale, use or other dealings * in this Software without prior written authorization from Lorens Younes. */ /*****************************************************************************\ * amigax.c: * * * * XPM library * * Emulates some Xlib functionality for Amiga. * * * * Developed by Lorens Younes (d93-hyo@nada.kth.se) 7/95 * * Revised 4/96 * \*****************************************************************************/ #ifdef HAVE_CONFIG_H #include #endif #include "XpmI.h" #include "amigax.h" #include #include #include static struct RastPort * AllocRastPort (unsigned int, unsigned int, unsigned int); static void FreeRastPort (struct RastPort *, unsigned int,unsigned int); static struct RastPort * AllocRastPort ( unsigned int width, unsigned int height, unsigned int depth) { struct RastPort *rp; rp = XpmMalloc (sizeof (*rp)); if (rp != NULL) { InitRastPort (rp); if (GfxBase->LibNode.lib_Version >= 39) { rp->BitMap = AllocBitMap (width, height, depth, BMF_CLEAR, NULL); if (rp->BitMap == NULL) { FreeRastPort (rp, width, height); return NULL; } } else { unsigned int i; rp->BitMap = XpmMalloc (sizeof (*rp->BitMap)); if (rp->BitMap == NULL) { FreeRastPort (rp, width, height); return NULL; } InitBitMap (rp->BitMap, depth, width, height); for (i = 0; i < depth; ++i) rp->BitMap->Planes[i] = NULL; for (i = 0; i < depth; ++i) { rp->BitMap->Planes[i] = (PLANEPTR)AllocRaster (width, height); if (rp->BitMap->Planes[i] == NULL) { FreeRastPort (rp, width, height); return NULL; } } } } return rp; } static void FreeRastPort ( struct RastPort *rp, unsigned int width, unsigned int height) { if (rp != NULL) { if (rp->BitMap != NULL) { WaitBlit (); if (GfxBase->LibNode.lib_Version >= 39) FreeBitMap (rp->BitMap); else { unsigned int i; for (i = 0; i < rp->BitMap->Depth; ++i) { if (rp->BitMap->Planes[i] != NULL) FreeRaster (rp->BitMap->Planes[i], width, height); } XpmFree (rp->BitMap); } } XpmFree (rp); } } XImage * AllocXImage ( unsigned int width, unsigned int height, unsigned int depth) { XImage *img; img = XpmMalloc (sizeof (*img)); if (img != NULL) { img->width = width; img->height = height; img->rp = AllocRastPort (img->width, img->height, depth); if (img->rp == NULL) { FreeXImage (img); return NULL; } } return img; } int FreeXImage ( XImage *ximage) { if (ximage != NULL) { FreeRastPort (ximage->rp, ximage->width, ximage->height); XpmFree (ximage); } return Success; } int XPutPixel ( XImage *ximage, int x, int y, unsigned long pixel) { SetAPen (ximage->rp, pixel); WritePixel (ximage->rp, x, y); return Success; } Status AllocBestPen ( Colormap colormap, XColor *screen_in_out, unsigned long precision, Bool fail_if_bad) { if (GfxBase->LibNode.lib_Version >= 39) { unsigned long r, g, b; r = screen_in_out->red * 0x00010001; g = screen_in_out->green * 0x00010001; b = screen_in_out->blue * 0x00010001; screen_in_out->pixel = ObtainBestPen (colormap, r, g, b, OBP_Precision, precision, OBP_FailIfBad, fail_if_bad, TAG_DONE); if (screen_in_out->pixel == -1) return False; QueryColor (colormap, screen_in_out); } else { XColor nearest, trial; long nearest_delta, trial_delta; int num_cells, i; num_cells = colormap->Count; nearest.pixel = 0; QueryColor (colormap, &nearest); nearest_delta = ((((screen_in_out->red >> 8) - (nearest.red >> 8)) * ((screen_in_out->red >> 8) - (nearest.red >> 8))) + (((screen_in_out->green >> 8) - (nearest.green >> 8)) * ((screen_in_out->green >> 8) - (nearest.green >> 8))) + (((screen_in_out->blue >> 8) - (nearest.blue >> 8)) * ((screen_in_out->blue >> 8) - (nearest.blue >> 8)))); for (i = 1; i < num_cells; i++) { /* precision and fail_if_bad is ignored under pre V39 */ trial.pixel = i; QueryColor (colormap, &trial); trial_delta = ((((screen_in_out->red >> 8) - (trial.red >> 8)) * ((screen_in_out->red >> 8) - (trial.red >> 8))) + (((screen_in_out->green >> 8) - (trial.green >> 8)) * ((screen_in_out->green >> 8) - (trial.green >> 8))) + (((screen_in_out->blue >> 8) - (trial.blue >> 8)) * ((screen_in_out->blue >> 8) - (trial.blue >> 8)))); if (trial_delta < nearest_delta) { nearest = trial; nearest_delta = trial_delta; } } screen_in_out->pixel = nearest.pixel; screen_in_out->red = nearest.red; screen_in_out->green = nearest.green; screen_in_out->blue = nearest.blue; } return True; } int FreePens ( Colormap colormap, unsigned long *pixels, int npixels) { if (GfxBase->LibNode.lib_Version >= 39) { int i; for (i = 0; i < npixels; i++) ReleasePen (colormap, pixels[i]); } return Success; } Status ParseColor ( char *spec, XColor *exact_def_return) { int spec_length; if (spec == 0) return False; spec_length = strlen(spec); if (spec[0] == '#') { int hexlen; char hexstr[10]; hexlen = (spec_length - 1) / 3; if (hexlen < 1 || hexlen > 4 || hexlen * 3 != spec_length - 1) return False; hexstr[hexlen] = '\0'; strncpy (hexstr, spec + 1, hexlen); exact_def_return->red = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen); strncpy (hexstr, spec + 1 + hexlen, hexlen); exact_def_return->green = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen); strncpy (hexstr, spec + 1 + 2 * hexlen, hexlen); exact_def_return->blue = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen); return True; } else { FILE *rgbf; int items, red, green, blue; char line[512], name[512]; Bool success = False; rgbf = fopen ("LIBS:rgb.txt", "r"); if (rgbf == NULL) return False; while (fgets(line, sizeof (line), rgbf) && !success) { items = sscanf (line, "%d %d %d %[^\n]\n", &red, &green, &blue, name); if (items != 4) continue; if (red < 0 || red > 0xFF || green < 0 || green > 0xFF || blue < 0 || blue > 0xFF) { continue; } if (0 == xpmstrcasecmp (spec, name)) { exact_def_return->red = red * 0x0101; exact_def_return->green = green * 0x0101; exact_def_return->blue = blue * 0x0101; success = True; } } fclose (rgbf); return success; } } int QueryColor ( Colormap colormap, XColor *def_in_out) { if (GfxBase->LibNode.lib_Version >= 39) { unsigned long rgb[3]; GetRGB32 (colormap, def_in_out->pixel, 1, rgb); def_in_out->red = rgb[0] >> 16; def_in_out->green = rgb[1] >> 16; def_in_out->blue = rgb[2] >> 16; } else { unsigned short rgb; rgb = GetRGB4 (colormap, def_in_out->pixel); def_in_out->red = ((rgb >> 8) & 0xF) * 0x1111; def_in_out->green = ((rgb >> 4) & 0xF) * 0x1111; def_in_out->blue = (rgb & 0xF) * 0x1111; } return Success; } int QueryColors ( Colormap colormap, XColor *defs_in_out, int ncolors) { int i; for (i = 0; i < ncolors; i++) QueryColor (colormap, &defs_in_out[i]); return Success; }