PageRenderTime 35ms CodeModel.GetById 15ms app.highlight 17ms RepoModel.GetById 1ms 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/*****************************************************************************\
 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}