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