~ubuntu-branches/ubuntu/gutsy/pygame/gutsy

« back to all changes in this revision

Viewing changes to src/surflock.c

  • Committer: Bazaar Package Importer
  • Author(s): Ed Boraas
  • Date: 2002-02-20 06:39:24 UTC
  • Revision ID: james.westby@ubuntu.com-20020220063924-amlzj7tqkeods4eq
Tags: upstream-1.4
ImportĀ upstreamĀ versionĀ 1.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    pygame - Python Game Library
 
3
    Copyright (C) 2000-2001  Pete Shinners
 
4
 
 
5
    This library is free software; you can redistribute it and/or
 
6
    modify it under the terms of the GNU Library General Public
 
7
    License as published by the Free Software Foundation; either
 
8
    version 2 of the License, or (at your option) any later version.
 
9
 
 
10
    This library is distributed in the hope that it will be useful,
 
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
    Library General Public License for more details.
 
14
 
 
15
    You should have received a copy of the GNU Library General Public
 
16
    License along with this library; if not, write to the Free
 
17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
 
 
19
    Pete Shinners
 
20
    pete@shinners.org
 
21
*/
 
22
 
 
23
/*
 
24
 *  internal surface locking support for python objects
 
25
 */
 
26
#define PYGAMEAPI_SURFLOCK_INTERNAL
 
27
#include "pygame.h"
 
28
 
 
29
 
 
30
 
 
31
/*extra Surface documentation*/
 
32
#if 0 /*extra help, only for docs, not docstrings*/
 
33
    /*DOC*/ static char doc_Surface_EXTRA[] =
 
34
    /*DOC*/    "Any functions that directly access a surface's pixel data will\n"
 
35
    /*DOC*/    "need that surface to be lock()'ed. These functions can lock()\n"
 
36
    /*DOC*/    "and unlock() the surfaces themselves without assistance. But, if\n"
 
37
    /*DOC*/    "a function will be called many times, there will be a lot of overhead\n"
 
38
    /*DOC*/    "for multiple locking and unlocking of the surface. It is best to lock\n"
 
39
    /*DOC*/    "the surface manually before making the function call many times, and\n"
 
40
    /*DOC*/    "then unlocking when you are finished. All functions that need a locked\n"
 
41
    /*DOC*/    "surface will say so in their docs.\n"
 
42
    /*DOC*/    "\n"
 
43
    /*DOC*/    "Also remember that you will want to leave the surface locked for the\n"
 
44
    /*DOC*/    "shortest amount of time needed.\n"
 
45
    /*DOC*/    "\n"
 
46
    /*DOC*/    "\n"
 
47
    /*DOC*/    "Here is the quick breakdown of how packed pixels work (don't worry if\n"
 
48
    /*DOC*/    "you don't quite understand this, it is only here for informational\n"
 
49
    /*DOC*/    "purposes, it is not needed). Each colorplane mask can be used to\n"
 
50
    /*DOC*/    "isolate the values for a colorplane from the packed pixel color.\n"
 
51
    /*DOC*/    "Therefore PACKED_COLOR & RED_MASK == REDPLANE. Note that the\n"
 
52
    /*DOC*/    "REDPLANE is not exactly the red color value, but it is the red\n"
 
53
    /*DOC*/    "color value bitwise left shifted a certain amount. The losses and\n"
 
54
    /*DOC*/    "masks can be used to convert back and forth between each\n"
 
55
    /*DOC*/    "colorplane and the actual color for that plane. Here are the\n"
 
56
    /*DOC*/    "final formulas used be map and unmap.\n"
 
57
    /*DOC*/    "PACKED_COLOR = RED>>losses[0]<<shifts[0] |\n"
 
58
    /*DOC*/    "      GREEN>>losses[1]<<shifts[1] | BLUE>>losses[2]<<shifts[2]\n"
 
59
    /*DOC*/    "RED = PACKED_COLOR & masks[0] >> shifts[0] << losses[0]\n"
 
60
    /*DOC*/    "GREEN = PACKED_COLOR & masks[1] >> shifts[1] << losses[1]\n"
 
61
    /*DOC*/    "BLUE = PACKED_COLOR & masks[2] >> shifts[2] << losses[2]\n"
 
62
    /*DOC*/    "There is also an alpha channel for some Surfaces.\n"
 
63
#endif
 
64
 
 
65
 
 
66
 
 
67
 
 
68
 
 
69
 
 
70
 
 
71
static int PySurface_Lock(PyObject* surfobj);
 
72
static int PySurface_Unlock(PyObject* surfobj);
 
73
 
 
74
 
 
75
 
 
76
static void PySurface_Prep(PyObject* surfobj)
 
77
{
 
78
        struct SubSurface_Data* data = ((PySurfaceObject*)surfobj)->subsurface;
 
79
        if(data)
 
80
        {
 
81
                SDL_Surface* surf = PySurface_AsSurface(surfobj);
 
82
                SDL_Surface* owner = PySurface_AsSurface(data->owner);
 
83
                PySurface_Lock(data->owner);
 
84
                surf->pixels = ((char*)owner->pixels) + data->pixeloffset;
 
85
        }
 
86
}
 
87
 
 
88
static void PySurface_Unprep(PyObject* surfobj)
 
89
{
 
90
        struct SubSurface_Data* data = ((PySurfaceObject*)surfobj)->subsurface;
 
91
        if(data)
 
92
                PySurface_Unlock(data->owner);
 
93
}
 
94
 
 
95
static int PySurface_Lock(PyObject* surfobj)
 
96
{
 
97
        PySurfaceObject* surf = (PySurfaceObject*)surfobj;
 
98
        if(surf->subsurface)
 
99
                PySurface_Prep(surfobj);
 
100
        if(!surf->lockcount && (surf->subsurface || !surf->surf->pixels))
 
101
        {
 
102
                if(SDL_LockSurface(surf->surf) == -1)
 
103
                {
 
104
                        PyErr_SetString(PyExc_RuntimeError, "error locking surface");
 
105
                        return 0;
 
106
                }
 
107
                surf->didlock = 1;
 
108
        }
 
109
        surf->lockcount++;
 
110
        return 1;
 
111
}
 
112
 
 
113
 
 
114
static int PySurface_Unlock(PyObject* surfobj)
 
115
{
 
116
        PySurfaceObject* surf = (PySurfaceObject*)surfobj;
 
117
        surf->lockcount--;
 
118
        if(!surf->lockcount && surf->didlock)
 
119
        {
 
120
                surf->didlock = 0;
 
121
                SDL_UnlockSurface(surf->surf);
 
122
        }
 
123
        if(surf->lockcount < 0)
 
124
        {
 
125
                PyErr_SetString(PyExc_RuntimeError, "attempt to unlock an unlocked surface");
 
126
                return 0;
 
127
        }
 
128
        if(surf->subsurface)
 
129
                PySurface_Unprep(surfobj);
 
130
        return 1;
 
131
}
 
132
 
 
133
 
 
134
 
 
135
 
 
136
 
 
137
/* lifetimelock object internals */
 
138
 
 
139
typedef struct {
 
140
        PyObject_HEAD
 
141
        PyObject* surface;
 
142
} PyLifetimeLockObject;
 
143
 
 
144
static void lifelock_dealloc(PyObject* self)
 
145
{
 
146
        PyLifetimeLockObject* lifelock = (PyLifetimeLockObject*)self;
 
147
 
 
148
        PySurface_Unlock(lifelock->surface);
 
149
        Py_DECREF(lifelock->surface);
 
150
 
 
151
        PyObject_DEL(self);     
 
152
}
 
153
 
 
154
static PyTypeObject PyLifetimeLock_Type =
 
155
{
 
156
        PyObject_HEAD_INIT(NULL)
 
157
        0,                                                   /*size*/
 
158
        "SurfLifeLock",              /*name*/
 
159
        sizeof(PyLifetimeLockObject),/*basic size*/
 
160
        0,                                                   /*itemsize*/
 
161
        lifelock_dealloc,                    /*dealloc*/
 
162
};
 
163
 
 
164
 
 
165
static PyObject* PySurface_LockLifetime(PyObject* surf)
 
166
{
 
167
        PyLifetimeLockObject* life;
 
168
        if(!surf) return RAISE(PyExc_SDLError, SDL_GetError());
 
169
 
 
170
        if(!PySurface_Lock(surf))
 
171
                return NULL;
 
172
 
 
173
        life = PyObject_NEW(PyLifetimeLockObject, &PyLifetimeLock_Type);
 
174
        if(life)
 
175
        {
 
176
                life->surface = surf;
 
177
                Py_INCREF(surf);
 
178
        }
 
179
        return (PyObject*)life;
 
180
}
 
181
 
 
182
 
 
183
 
 
184
 
 
185
 
 
186
static PyMethodDef surflock__builtins__[] =
 
187
{
 
188
        {NULL, NULL}
 
189
};
 
190
 
 
191
 
 
192
PYGAME_EXPORT
 
193
void initsurflock(void)
 
194
{
 
195
        PyObject *module, *dict, *apiobj;
 
196
        static void* c_api[PYGAMEAPI_SURFLOCK_NUMSLOTS];
 
197
 
 
198
        PyType_Init(PyLifetimeLock_Type);
 
199
 
 
200
 
 
201
        /* Create the module and add the functions */
 
202
        module = Py_InitModule3("surflock", surflock__builtins__, "Surface locking support");
 
203
        dict = PyModule_GetDict(module);
 
204
 
 
205
        /* export the c api */
 
206
        c_api[0] = PySurface_Prep;
 
207
        c_api[1] = PySurface_Unprep;
 
208
        c_api[2] = PySurface_Lock;
 
209
        c_api[3] = PySurface_Unlock;
 
210
        c_api[4] = PySurface_LockLifetime;
 
211
        apiobj = PyCObject_FromVoidPtr(c_api, NULL);
 
212
        PyDict_SetItemString(dict, PYGAMEAPI_LOCAL_ENTRY, apiobj);
 
213
        Py_DECREF(apiobj);
 
214
}