~ubuntu-branches/ubuntu/natty/libsdl1.2/natty

« back to all changes in this revision

Viewing changes to src/video/maccommon/SDL_macwm.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-12-05 20:29:43 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20071205202943-ryogi07hodn5cdif
Tags: 1.2.12-1ubuntu1
* Merge with Debian; remaining changes:
  - Remove svgalib support.
  - Prefer libgl1-mesa-dev build-dependency over xlibmesa-gl-dev.
  - Build for lpia as for i386.
* Link using -Wl,-Bsymbolic-functions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
#include <Strings.h>
31
31
#endif
32
32
 
 
33
#if SDL_MACCLASSIC_GAMMA_SUPPORT
 
34
#include <Devices.h>
 
35
#include <Files.h>
 
36
#include <MacTypes.h>
 
37
#include <QDOffscreen.h>
 
38
#include <Quickdraw.h>
 
39
#include <Video.h>
 
40
#endif
 
41
 
33
42
#include "SDL_stdinc.h"
34
43
#include "SDL_macwm_c.h"
35
44
 
42
51
        if (SDL_Window)
43
52
                SetWTitle(SDL_Window, ptitle); /* MJS */
44
53
}
 
54
 
 
55
#if SDL_MACCLASSIC_GAMMA_SUPPORT
 
56
/*
 
57
 * ADC Gamma Ramp support...
 
58
 *
 
59
 * Mac Gamma Ramp code was originally from sample code provided by
 
60
 *  Apple Developer Connection, and not written specifically for SDL:
 
61
 * "Contains: Functions to enable Mac OS device gamma adjustments using 3 channel 256 element 8 bit gamma ramps
 
62
 *  Written by: Geoff Stahl (ggs)
 
63
 *  Copyright: Copyright (c) 1999 Apple Computer, Inc., All Rights Reserved
 
64
 *  Disclaimer: You may incorporate this sample code into your applications without
 
65
 *              restriction, though the sample code has been provided "AS IS" and the
 
66
 *              responsibility for its operation is 100% yours.  However, what you are
 
67
 *              not permitted to do is to redistribute the source as "DSC Sample Code"
 
68
 *              after having made changes. If you're going to re-distribute the source,
 
69
 *              we require that you make it clear in the source that the code was
 
70
 *              descended from Apple Sample Code, but that you've made changes."
 
71
 * (The sample code has been integrated into this file, and thus is modified from the original Apple sources.)
 
72
 */
 
73
 
 
74
typedef struct recDeviceGamma                                                                                   /* storage for device handle and gamma table */
 
75
{
 
76
        GDHandle hGD;                                                                                           /* handle to device */
 
77
        GammaTblPtr pDeviceGamma;                                                                       /* pointer to device gamma table */
 
78
} recDeviceGamma;
 
79
typedef recDeviceGamma * precDeviceGamma;
 
80
 
 
81
typedef struct recSystemGamma                                                                                   /* storage for system devices and gamma tables */
 
82
{
 
83
        short numDevices;                                                                                       /* number of devices */
 
84
        precDeviceGamma * devGamma;                                                                     /* array of pointers to device gamma records */
 
85
} recSystemGamma;
 
86
typedef recSystemGamma * precSystemGamma;
 
87
 
 
88
static Ptr CopyGammaTable (GammaTblPtr pTableGammaIn)
 
89
{
 
90
        GammaTblPtr             pTableGammaOut = NULL;
 
91
        short                   tableSize, dataWidth;
 
92
 
 
93
        if (pTableGammaIn)                                                                                              /* if there is a table to copy  */
 
94
        {
 
95
                dataWidth = (pTableGammaIn->gDataWidth + 7) / 8;                        /* number of bytes per entry */
 
96
                tableSize = sizeof (GammaTbl) + pTableGammaIn->gFormulaSize +
 
97
                                        (pTableGammaIn->gChanCnt * pTableGammaIn->gDataCnt * dataWidth);
 
98
                pTableGammaOut = (GammaTblPtr) NewPtr (tableSize);                      /* allocate new table */
 
99
                if (pTableGammaOut)                                                                                     
 
100
                        BlockMove( (Ptr)pTableGammaIn, (Ptr)pTableGammaOut, tableSize); /* move everything */
 
101
        }
 
102
        return (Ptr)pTableGammaOut;                                                                             /* return whatever we allocated, could be NULL */
 
103
}
 
104
 
 
105
static OSErr GetGammaTable (GDHandle hGD, GammaTblPtr * ppTableGammaOut)
 
106
{
 
107
        VDGammaRecord   DeviceGammaRec;
 
108
        CntrlParam              cParam;
 
109
        OSErr                   err;
 
110
        
 
111
        cParam.ioCompletion = NULL;                                                                             /* set up control params */
 
112
        cParam.ioNamePtr = NULL;
 
113
        cParam.ioVRefNum = 0;
 
114
        cParam.ioCRefNum = (**hGD).gdRefNum;
 
115
        cParam.csCode = cscGetGamma;                                                                    /* Get Gamma commnd to device */
 
116
        *(Ptr *)cParam.csParam = (Ptr) &DeviceGammaRec;                                 /* record for gamma */
 
117
 
 
118
        err = PBStatusSync( (ParmBlkPtr)&cParam );                                              /* get gamma */
 
119
        
 
120
        *ppTableGammaOut = (GammaTblPtr)(DeviceGammaRec.csGTable);              /* pull table out of record */
 
121
        
 
122
        return err;     
 
123
}
 
124
 
 
125
static Ptr GetDeviceGamma (GDHandle hGD)
 
126
{
 
127
        GammaTblPtr             pTableGammaDevice = NULL;
 
128
        GammaTblPtr             pTableGammaReturn = NULL;       
 
129
        OSErr                   err;
 
130
        
 
131
        err = GetGammaTable (hGD, &pTableGammaDevice);                                  /* get a pointer to the devices table */
 
132
        if ((noErr == err) && pTableGammaDevice)                                                /* if succesful */
 
133
                pTableGammaReturn = (GammaTblPtr) CopyGammaTable (pTableGammaDevice); /* copy to global */
 
134
 
 
135
        return (Ptr) pTableGammaReturn;
 
136
}
 
137
 
 
138
static void DisposeGammaTable (Ptr pGamma)
 
139
{
 
140
        if (pGamma)
 
141
                DisposePtr((Ptr) pGamma);                                                                       /* get rid of it */
 
142
}
 
143
 
 
144
static void DisposeSystemGammas (Ptr* ppSystemGammas)
 
145
{
 
146
        precSystemGamma pSysGammaIn;
 
147
        if (ppSystemGammas)
 
148
        {
 
149
                pSysGammaIn = (precSystemGamma) *ppSystemGammas;
 
150
                if (pSysGammaIn)
 
151
                {
 
152
                        short i;
 
153
                        for (i = 0; i < pSysGammaIn->numDevices; i++)           /* for all devices */
 
154
                                if (pSysGammaIn->devGamma [i])                                          /* if pointer is valid */
 
155
                                {
 
156
                                        DisposeGammaTable ((Ptr) pSysGammaIn->devGamma [i]->pDeviceGamma); /* dump gamma table */
 
157
                                        DisposePtr ((Ptr) pSysGammaIn->devGamma [i]);                                      /* dump device info */
 
158
                                }
 
159
                        DisposePtr ((Ptr) pSysGammaIn->devGamma);                               /* dump device pointer array             */
 
160
                        DisposePtr ((Ptr) pSysGammaIn);                                                 /* dump system structure */
 
161
                        *ppSystemGammas = NULL;
 
162
                }       
 
163
        }
 
164
}
 
165
 
 
166
static Boolean GetDeviceGammaRampGD (GDHandle hGD, Ptr pRamp)
 
167
{
 
168
        GammaTblPtr             pTableGammaTemp = NULL;
 
169
        long                    indexChan, indexEntry;
 
170
        OSErr                   err;
 
171
        
 
172
        if (pRamp)                                                                                                                      /* ensure pRamp is allocated */
 
173
        {
 
174
                err = GetGammaTable (hGD, &pTableGammaTemp);                                    /* get a pointer to the current gamma */
 
175
                if ((noErr == err) && pTableGammaTemp)                                                  /* if successful */
 
176
                {                                                                                                                       
 
177
                        /* fill ramp */
 
178
                        unsigned char * pEntry = (unsigned char *) &pTableGammaTemp->gFormulaData + pTableGammaTemp->gFormulaSize; /* base of table */
 
179
                        short bytesPerEntry = (pTableGammaTemp->gDataWidth + 7) / 8; /* size, in bytes, of the device table entries */
 
180
                        short shiftRightValue = pTableGammaTemp->gDataWidth - 8;         /* number of right shifts device -> ramp */
 
181
                        short channels = pTableGammaTemp->gChanCnt;     
 
182
                        short entries = pTableGammaTemp->gDataCnt;                                                                      
 
183
                        if (3 == channels)                                                                                      /* RGB format */
 
184
                        {                                                                                                                       /* note, this will create runs of entries if dest. is bigger (not linear interpolate) */
 
185
                                for (indexChan = 0; indexChan < channels; indexChan++)
 
186
                                        for (indexEntry = 0; indexEntry < 256; indexEntry++)
 
187
                                                *((unsigned char *) pRamp + (indexChan * 256) + indexEntry) = 
 
188
                                                  *(pEntry + indexChan * entries * bytesPerEntry + indexEntry * entries * bytesPerEntry / 256) >> shiftRightValue;
 
189
                        }
 
190
                        else                                                                                                            /* single channel format */
 
191
                        {
 
192
                                for (indexChan = 0; indexChan < 768; indexChan += 256)  /* repeat for all 3 channels (step by ramp size) */
 
193
                                        for (indexEntry = 0; indexEntry < 256; indexEntry++) /* for all entries set vramp value */
 
194
                                                *((unsigned char *) pRamp + indexChan + indexEntry) = 
 
195
                                                  *(pEntry + indexEntry * entries * bytesPerEntry / 256) >> shiftRightValue;
 
196
                        }
 
197
                        return true;
 
198
                }
 
199
        }
 
200
        return false;
 
201
}
 
202
 
 
203
static Ptr GetSystemGammas (void)
 
204
{
 
205
        precSystemGamma pSysGammaOut;                                                                   /* return pointer to system device gamma info */
 
206
        short devCount = 0;                                                                                             /* number of devices attached */
 
207
        Boolean fail = false;
 
208
        GDHandle hGDevice;
 
209
        
 
210
        pSysGammaOut = (precSystemGamma) NewPtr (sizeof (recSystemGamma)); /* allocate for structure */
 
211
        
 
212
        hGDevice = GetDeviceList ();                                                    /* top of device list */
 
213
        do                                                                                                                              /* iterate */
 
214
        {
 
215
                devCount++;                                                                                                     /* count devices                                         */
 
216
                hGDevice = GetNextDevice (hGDevice);                                            /* next device */
 
217
        } while (hGDevice);
 
218
        
 
219
        pSysGammaOut->devGamma = (precDeviceGamma *) NewPtr (sizeof (precDeviceGamma) * devCount); /* allocate for array of pointers to device records */
 
220
        if (pSysGammaOut)
 
221
        {
 
222
                pSysGammaOut->numDevices = devCount;                                            /* stuff count */
 
223
                
 
224
                devCount = 0;                                                                                           /* reset iteration */
 
225
                hGDevice = GetDeviceList ();
 
226
                do
 
227
                {
 
228
                        pSysGammaOut->devGamma [devCount] = (precDeviceGamma) NewPtr (sizeof (recDeviceGamma));   /* new device record */
 
229
                        if (pSysGammaOut->devGamma [devCount])                                  /* if we actually allocated memory */
 
230
                        {
 
231
                                pSysGammaOut->devGamma [devCount]->hGD = hGDevice;                                                                                /* stuff handle */
 
232
                                pSysGammaOut->devGamma [devCount]->pDeviceGamma = (GammaTblPtr)GetDeviceGamma (hGDevice); /* copy gamma table */
 
233
                        }
 
234
                        else                                                                                                    /* otherwise dump record on exit */
 
235
                         fail = true;
 
236
                        devCount++;                                                                                             /* next device */
 
237
                        hGDevice = GetNextDevice (hGDevice);                                            
 
238
                } while (hGDevice);
 
239
        }
 
240
        if (!fail)                                                                                                              /* if we did not fail */
 
241
                return (Ptr) pSysGammaOut;                                                                      /* return pointer to structure */
 
242
        else
 
243
        {
 
244
                DisposeSystemGammas ((Ptr *) &pSysGammaOut);                                    /* otherwise dump the current structures (dispose does error checking) */
 
245
                return NULL;                                                                                            /* could not complete */
 
246
        }
 
247
}
 
248
 
 
249
static void RestoreDeviceGamma (GDHandle hGD, Ptr pGammaTable)
 
250
{
 
251
        VDSetEntryRecord setEntriesRec;
 
252
        VDGammaRecord   gameRecRestore;
 
253
        CTabHandle      hCTabDeviceColors;
 
254
        Ptr                             csPtr;
 
255
        OSErr                   err = noErr;
 
256
        
 
257
        if (pGammaTable)                                                                                                /* if we have a table to restore                                                                 */
 
258
        {
 
259
                gameRecRestore.csGTable = pGammaTable;                                          /* setup restore record */
 
260
                csPtr = (Ptr) &gameRecRestore;
 
261
                err = Control((**hGD).gdRefNum, cscSetGamma, (Ptr) &csPtr);     /* restore gamma */
 
262
 
 
263
                if ((noErr == err) && (8 == (**(**hGD).gdPMap).pixelSize))      /* if successful and on an 8 bit device */
 
264
                {
 
265
                        hCTabDeviceColors = (**(**hGD).gdPMap).pmTable;                 /* do SetEntries to force CLUT update */
 
266
                        setEntriesRec.csTable = (ColorSpec *) &(**hCTabDeviceColors).ctTable;
 
267
                        setEntriesRec.csStart = 0;
 
268
                        setEntriesRec.csCount = (**hCTabDeviceColors).ctSize;
 
269
                        csPtr = (Ptr) &setEntriesRec;
 
270
                        
 
271
                        err = Control((**hGD).gdRefNum, cscSetEntries, (Ptr) &csPtr); /* SetEntries in CLUT */
 
272
                }
 
273
        }
 
274
}
 
275
 
 
276
static void RestoreSystemGammas (Ptr pSystemGammas)
 
277
{
 
278
        short i;
 
279
        precSystemGamma pSysGammaIn = (precSystemGamma) pSystemGammas;
 
280
        if (pSysGammaIn)
 
281
                for (i = 0; i < pSysGammaIn->numDevices; i++)                   /* for all devices */
 
282
                        RestoreDeviceGamma (pSysGammaIn->devGamma [i]->hGD, (Ptr) pSysGammaIn->devGamma [i]->pDeviceGamma);     /* restore gamma */
 
283
}
 
284
 
 
285
static Ptr CreateEmptyGammaTable (short channels, short entries, short bits)
 
286
{
 
287
        GammaTblPtr             pTableGammaOut = NULL;
 
288
        short                   tableSize, dataWidth;
 
289
 
 
290
        dataWidth = (bits + 7) / 8;                                                                             /* number of bytes per entry */
 
291
        tableSize = sizeof (GammaTbl) + (channels * entries * dataWidth);
 
292
        pTableGammaOut = (GammaTblPtr) NewPtrClear (tableSize);                 /* allocate new tabel */
 
293
 
 
294
        if (pTableGammaOut)                                                                                             /* if we successfully allocated */
 
295
        {
 
296
                pTableGammaOut->gVersion = 0;                                                           /* set parameters based on input */
 
297
                pTableGammaOut->gType = 0;
 
298
                pTableGammaOut->gFormulaSize = 0;
 
299
                pTableGammaOut->gChanCnt = channels;
 
300
                pTableGammaOut->gDataCnt = entries;
 
301
                pTableGammaOut->gDataWidth = bits;
 
302
        }
 
303
        return (Ptr)pTableGammaOut;                                                                             /* return whatever we allocated */
 
304
}
 
305
 
 
306
static Boolean SetDeviceGammaRampGD (GDHandle hGD, Ptr pRamp)
 
307
{
 
308
        VDSetEntryRecord setEntriesRec;
 
309
        VDGammaRecord   gameRecRestore;
 
310
        GammaTblPtr             pTableGammaNew;
 
311
        GammaTblPtr             pTableGammaCurrent = NULL;
 
312
        CTabHandle      hCTabDeviceColors;
 
313
        Ptr                             csPtr;
 
314
        OSErr                   err;
 
315
        short                   dataBits, entries, channels = 3;                                                /* force three channels in the gamma table */
 
316
        
 
317
        if (pRamp)                                                                                                                              /* ensure pRamp is allocated */
 
318
        {
 
319
                err= GetGammaTable (hGD, &pTableGammaCurrent);                                          /* get pointer to current table */
 
320
                if ((noErr == err) && pTableGammaCurrent)
 
321
                {
 
322
                        dataBits = pTableGammaCurrent->gDataWidth;                                              /* table must have same data width */
 
323
                        entries = pTableGammaCurrent->gDataCnt;                                                 /* table must be same size */
 
324
                        pTableGammaNew = (GammaTblPtr) CreateEmptyGammaTable (channels, entries, dataBits); /* our new table */
 
325
                        if (pTableGammaNew)                                                                                             /* if successful fill table */
 
326
                        {       
 
327
                                unsigned char * pGammaBase = (unsigned char *) &pTableGammaNew->gFormulaData + pTableGammaNew->gFormulaSize; /* base of table */
 
328
                                if ((256 == entries) && (8 == dataBits))                                                /* simple case: direct mapping */
 
329
                                        BlockMove ((Ptr)pRamp, (Ptr)pGammaBase, channels * entries); /* move everything */
 
330
                                else                                                                                                            /* tough case handle entry, channel and data size disparities */
 
331
                                {
 
332
                                        short indexChan, indexEntry;
 
333
                                        short bytesPerEntry = (dataBits + 7) / 8;                               /* size, in bytes, of the device table entries */
 
334
                                        short shiftRightValue = 8 - dataBits;                                   /* number of right shifts ramp -> device */
 
335
                                        shiftRightValue += ((bytesPerEntry - 1) * 8);                   /* multibyte entries and the need to map a byte at a time most sig. to least sig. */
 
336
                                        for (indexChan = 0; indexChan < channels; indexChan++) /* for all the channels */
 
337
                                                for (indexEntry = 0; indexEntry < entries; indexEntry++) /* for all the entries */
 
338
                                                {
 
339
                                                        short currentShift = shiftRightValue;                   /* reset current bit shift */
 
340
                                                        long temp = *((unsigned char *)pRamp + (indexChan << 8) + (indexEntry << 8) / entries); /* get data from ramp */
 
341
                                                        short indexByte;
 
342
                                                        for (indexByte = 0; indexByte < bytesPerEntry; indexByte++) /* for all bytes */
 
343
                                                        {
 
344
                                                                if (currentShift < 0)                                           /* shift data correctly for current byte */
 
345
                                                                        *(pGammaBase++) = temp << -currentShift;
 
346
                                                                else
 
347
                                                                        *(pGammaBase++) = temp >> currentShift;
 
348
                                                                currentShift -= 8;                                                      /* increment shift to align to next less sig. byte */
 
349
                                                        }
 
350
                                                }
 
351
                                }
 
352
                                
 
353
                                /* set gamma */
 
354
                                gameRecRestore.csGTable = (Ptr) pTableGammaNew;                         /* setup restore record */
 
355
                                csPtr = (Ptr) &gameRecRestore;
 
356
                                err = Control((**hGD).gdRefNum, cscSetGamma, (Ptr) &csPtr);     /* restore gamma (note, display drivers may delay returning from this until VBL) */
 
357
                                
 
358
                                if ((8 == (**(**hGD).gdPMap).pixelSize) && (noErr == err))      /* if successful and on an 8 bit device */
 
359
                                {
 
360
                                        hCTabDeviceColors = (**(**hGD).gdPMap).pmTable;                 /* do SetEntries to force CLUT update */
 
361
                                        setEntriesRec.csTable = (ColorSpec *) &(**hCTabDeviceColors).ctTable;
 
362
                                        setEntriesRec.csStart = 0;
 
363
                                        setEntriesRec.csCount = (**hCTabDeviceColors).ctSize;
 
364
                                        csPtr = (Ptr) &setEntriesRec;
 
365
                                        err = Control((**hGD).gdRefNum, cscSetEntries, (Ptr) &csPtr);   /* SetEntries in CLUT */
 
366
                                }
 
367
                                DisposeGammaTable ((Ptr) pTableGammaNew);                                       /* dump table */
 
368
                                if (noErr == err)
 
369
                                        return true;
 
370
                        }
 
371
                }
 
372
        }
 
373
        else                                                                                                                                    /* set NULL gamma -> results in linear map */
 
374
        {
 
375
                gameRecRestore.csGTable = (Ptr) NULL;                                                           /* setup restore record */
 
376
                csPtr = (Ptr) &gameRecRestore;
 
377
                err = Control((**hGD).gdRefNum, cscSetGamma, (Ptr) &csPtr);                     /* restore gamma */
 
378
                
 
379
                if ((8 == (**(**hGD).gdPMap).pixelSize) && (noErr == err))                      /* if successful and on an 8 bit device */
 
380
                {
 
381
                        hCTabDeviceColors = (**(**hGD).gdPMap).pmTable;                                 /* do SetEntries to force CLUT update */
 
382
                        setEntriesRec.csTable = (ColorSpec *) &(**hCTabDeviceColors).ctTable;
 
383
                        setEntriesRec.csStart = 0;
 
384
                        setEntriesRec.csCount = (**hCTabDeviceColors).ctSize;
 
385
                        csPtr = (Ptr) &setEntriesRec;
 
386
                        err = Control((**hGD).gdRefNum, cscSetEntries, (Ptr) &csPtr);   /* SetEntries in CLUT */
 
387
                }
 
388
                if (noErr == err)
 
389
                        return true;
 
390
        }
 
391
        return false;                                                                                                                   /* memory allocation or device control failed if we get here */
 
392
}
 
393
 
 
394
/* end of ADC Gamma Ramp support code... */
 
395
 
 
396
static Ptr systemGammaPtr;
 
397
 
 
398
void Mac_QuitGamma(_THIS)
 
399
{
 
400
        if (systemGammaPtr)
 
401
        {
 
402
                RestoreSystemGammas(systemGammaPtr);
 
403
                DisposeSystemGammas(&systemGammaPtr);
 
404
        }
 
405
}
 
406
 
 
407
static unsigned char shiftedRamp[3 * 256];
 
408
 
 
409
int Mac_SetGammaRamp(_THIS, Uint16 *ramp)
 
410
{
 
411
        int i;
 
412
        if (!systemGammaPtr)
 
413
                systemGammaPtr = GetSystemGammas();
 
414
        for (i = 0; i < 3 * 256; i++)
 
415
        {
 
416
                shiftedRamp[i] = ramp[i] >> 8;
 
417
        }
 
418
 
 
419
        if (SetDeviceGammaRampGD(GetMainDevice(), (Ptr) shiftedRamp))
 
420
                return 0;
 
421
        else
 
422
                return -1;
 
423
}
 
424
 
 
425
int Mac_GetGammaRamp(_THIS, Uint16 *ramp)
 
426
{
 
427
        if (GetDeviceGammaRampGD(GetMainDevice(), (Ptr) shiftedRamp))
 
428
        {
 
429
                int i;
 
430
                for (i = 0; i < 3 * 256; i++)
 
431
                {
 
432
                        ramp[i] = shiftedRamp[i] << 8;
 
433
                }
 
434
                return 0;
 
435
        }
 
436
        else
 
437
                return -1;
 
438
}
 
439
 
 
440
#endif  /* SDL_MACCLASSIC_GAMMA_SUPPORT */
 
441
 
 
442