PageRenderTime 35ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/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. * amigax.c: *
  27. * *
  28. * XPM library *
  29. * Emulates some Xlib functionality for Amiga. *
  30. * *
  31. * Developed by Lorens Younes (d93-hyo@nada.kth.se) 7/95 *
  32. * Revised 4/96 *
  33. \*****************************************************************************/
  34. #ifdef HAVE_CONFIG_H
  35. #include <config.h>
  36. #endif
  37. #include "XpmI.h"
  38. #include "amigax.h"
  39. #include <graphics/gfxbase.h>
  40. #include <intuition/screens.h>
  41. #include <proto/exec.h>
  42. static struct RastPort *
  43. AllocRastPort (unsigned int, unsigned int, unsigned int);
  44. static void
  45. FreeRastPort (struct RastPort *, unsigned int,unsigned int);
  46. static struct RastPort *
  47. AllocRastPort (
  48. unsigned int width,
  49. unsigned int height,
  50. unsigned int depth)
  51. {
  52. struct RastPort *rp;
  53. rp = XpmMalloc (sizeof (*rp));
  54. if (rp != NULL)
  55. {
  56. InitRastPort (rp);
  57. if (GfxBase->LibNode.lib_Version >= 39)
  58. {
  59. rp->BitMap = AllocBitMap (width, height, depth, BMF_CLEAR, NULL);
  60. if (rp->BitMap == NULL)
  61. {
  62. FreeRastPort (rp, width, height);
  63. return NULL;
  64. }
  65. }
  66. else
  67. {
  68. unsigned int i;
  69. rp->BitMap = XpmMalloc (sizeof (*rp->BitMap));
  70. if (rp->BitMap == NULL)
  71. {
  72. FreeRastPort (rp, width, height);
  73. return NULL;
  74. }
  75. InitBitMap (rp->BitMap, depth, width, height);
  76. for (i = 0; i < depth; ++i)
  77. rp->BitMap->Planes[i] = NULL;
  78. for (i = 0; i < depth; ++i)
  79. {
  80. rp->BitMap->Planes[i] = (PLANEPTR)AllocRaster (width, height);
  81. if (rp->BitMap->Planes[i] == NULL)
  82. {
  83. FreeRastPort (rp, width, height);
  84. return NULL;
  85. }
  86. }
  87. }
  88. }
  89. return rp;
  90. }
  91. static void
  92. FreeRastPort (
  93. struct RastPort *rp,
  94. unsigned int width,
  95. unsigned int height)
  96. {
  97. if (rp != NULL)
  98. {
  99. if (rp->BitMap != NULL)
  100. {
  101. WaitBlit ();
  102. if (GfxBase->LibNode.lib_Version >= 39)
  103. FreeBitMap (rp->BitMap);
  104. else
  105. {
  106. unsigned int i;
  107. for (i = 0; i < rp->BitMap->Depth; ++i)
  108. {
  109. if (rp->BitMap->Planes[i] != NULL)
  110. FreeRaster (rp->BitMap->Planes[i], width, height);
  111. }
  112. XpmFree (rp->BitMap);
  113. }
  114. }
  115. XpmFree (rp);
  116. }
  117. }
  118. XImage *
  119. AllocXImage (
  120. unsigned int width,
  121. unsigned int height,
  122. unsigned int depth)
  123. {
  124. XImage *img;
  125. img = XpmMalloc (sizeof (*img));
  126. if (img != NULL)
  127. {
  128. img->width = width;
  129. img->height = height;
  130. img->rp = AllocRastPort (img->width, img->height, depth);
  131. if (img->rp == NULL)
  132. {
  133. FreeXImage (img);
  134. return NULL;
  135. }
  136. }
  137. return img;
  138. }
  139. int
  140. FreeXImage (
  141. XImage *ximage)
  142. {
  143. if (ximage != NULL)
  144. {
  145. FreeRastPort (ximage->rp, ximage->width, ximage->height);
  146. XpmFree (ximage);
  147. }
  148. return Success;
  149. }
  150. int
  151. XPutPixel (
  152. XImage *ximage,
  153. int x,
  154. int y,
  155. unsigned long pixel)
  156. {
  157. SetAPen (ximage->rp, pixel);
  158. WritePixel (ximage->rp, x, y);
  159. return Success;
  160. }
  161. Status
  162. AllocBestPen (
  163. Colormap colormap,
  164. XColor *screen_in_out,
  165. unsigned long precision,
  166. Bool fail_if_bad)
  167. {
  168. if (GfxBase->LibNode.lib_Version >= 39)
  169. {
  170. unsigned long r, g, b;
  171. r = screen_in_out->red * 0x00010001;
  172. g = screen_in_out->green * 0x00010001;
  173. b = screen_in_out->blue * 0x00010001;
  174. screen_in_out->pixel = ObtainBestPen (colormap, r, g, b,
  175. OBP_Precision, precision,
  176. OBP_FailIfBad, fail_if_bad,
  177. TAG_DONE);
  178. if (screen_in_out->pixel == -1)
  179. return False;
  180. QueryColor (colormap, screen_in_out);
  181. }
  182. else
  183. {
  184. XColor nearest, trial;
  185. long nearest_delta, trial_delta;
  186. int num_cells, i;
  187. num_cells = colormap->Count;
  188. nearest.pixel = 0;
  189. QueryColor (colormap, &nearest);
  190. nearest_delta = ((((screen_in_out->red >> 8) - (nearest.red >> 8))
  191. * ((screen_in_out->red >> 8) - (nearest.red >> 8)))
  192. +
  193. (((screen_in_out->green >> 8) - (nearest.green >> 8))
  194. * ((screen_in_out->green >> 8) - (nearest.green >> 8)))
  195. +
  196. (((screen_in_out->blue >> 8) - (nearest.blue >> 8))
  197. * ((screen_in_out->blue >> 8) - (nearest.blue >> 8))));
  198. for (i = 1; i < num_cells; i++)
  199. {
  200. /* precision and fail_if_bad is ignored under pre V39 */
  201. trial.pixel = i;
  202. QueryColor (colormap, &trial);
  203. trial_delta = ((((screen_in_out->red >> 8) - (trial.red >> 8))
  204. * ((screen_in_out->red >> 8) - (trial.red >> 8)))
  205. +
  206. (((screen_in_out->green >> 8) - (trial.green >> 8))
  207. * ((screen_in_out->green >> 8) - (trial.green >> 8)))
  208. +
  209. (((screen_in_out->blue >> 8) - (trial.blue >> 8))
  210. * ((screen_in_out->blue >> 8) - (trial.blue >> 8))));
  211. if (trial_delta < nearest_delta)
  212. {
  213. nearest = trial;
  214. nearest_delta = trial_delta;
  215. }
  216. }
  217. screen_in_out->pixel = nearest.pixel;
  218. screen_in_out->red = nearest.red;
  219. screen_in_out->green = nearest.green;
  220. screen_in_out->blue = nearest.blue;
  221. }
  222. return True;
  223. }
  224. int
  225. FreePens (
  226. Colormap colormap,
  227. unsigned long *pixels,
  228. int npixels)
  229. {
  230. if (GfxBase->LibNode.lib_Version >= 39)
  231. {
  232. int i;
  233. for (i = 0; i < npixels; i++)
  234. ReleasePen (colormap, pixels[i]);
  235. }
  236. return Success;
  237. }
  238. Status
  239. ParseColor (
  240. char *spec,
  241. XColor *exact_def_return)
  242. {
  243. int spec_length;
  244. if (spec == 0)
  245. return False;
  246. spec_length = strlen(spec);
  247. if (spec[0] == '#')
  248. {
  249. int hexlen;
  250. char hexstr[10];
  251. hexlen = (spec_length - 1) / 3;
  252. if (hexlen < 1 || hexlen > 4 || hexlen * 3 != spec_length - 1)
  253. return False;
  254. hexstr[hexlen] = '\0';
  255. strncpy (hexstr, spec + 1, hexlen);
  256. exact_def_return->red = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen);
  257. strncpy (hexstr, spec + 1 + hexlen, hexlen);
  258. exact_def_return->green = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen);
  259. strncpy (hexstr, spec + 1 + 2 * hexlen, hexlen);
  260. exact_def_return->blue = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen);
  261. return True;
  262. }
  263. else
  264. {
  265. FILE *rgbf;
  266. int items, red, green, blue;
  267. char line[512], name[512];
  268. Bool success = False;
  269. rgbf = fopen ("LIBS:rgb.txt", "r");
  270. if (rgbf == NULL)
  271. return False;
  272. while (fgets(line, sizeof (line), rgbf) && !success)
  273. {
  274. items = sscanf (line, "%d %d %d %[^\n]\n",
  275. &red, &green, &blue, name);
  276. if (items != 4)
  277. continue;
  278. if (red < 0 || red > 0xFF
  279. || green < 0 || green > 0xFF
  280. || blue < 0 || blue > 0xFF)
  281. {
  282. continue;
  283. }
  284. if (0 == xpmstrcasecmp (spec, name))
  285. {
  286. exact_def_return->red = red * 0x0101;
  287. exact_def_return->green = green * 0x0101;
  288. exact_def_return->blue = blue * 0x0101;
  289. success = True;
  290. }
  291. }
  292. fclose (rgbf);
  293. return success;
  294. }
  295. }
  296. int
  297. QueryColor (
  298. Colormap colormap,
  299. XColor *def_in_out)
  300. {
  301. if (GfxBase->LibNode.lib_Version >= 39)
  302. {
  303. unsigned long rgb[3];
  304. GetRGB32 (colormap, def_in_out->pixel, 1, rgb);
  305. def_in_out->red = rgb[0] >> 16;
  306. def_in_out->green = rgb[1] >> 16;
  307. def_in_out->blue = rgb[2] >> 16;
  308. }
  309. else
  310. {
  311. unsigned short rgb;
  312. rgb = GetRGB4 (colormap, def_in_out->pixel);
  313. def_in_out->red = ((rgb >> 8) & 0xF) * 0x1111;
  314. def_in_out->green = ((rgb >> 4) & 0xF) * 0x1111;
  315. def_in_out->blue = (rgb & 0xF) * 0x1111;
  316. }
  317. return Success;
  318. }
  319. int
  320. QueryColors (
  321. Colormap colormap,
  322. XColor *defs_in_out,
  323. int ncolors)
  324. {
  325. int i;
  326. for (i = 0; i < ncolors; i++)
  327. QueryColor (colormap, &defs_in_out[i]);
  328. return Success;
  329. }