Rename GP_Context -> GP_Pixmap
[gfxprim.git] / libs / backends / GP_AALib.c
blob228809877ef2a191a8ea391f475fc1f3ff054926
1 /*****************************************************************************
2 * This file is part of gfxprim library. *
3 * *
4 * Gfxprim is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU Lesser General Public *
6 * License as published by the Free Software Foundation; either *
7 * version 2.1 of the License, or (at your option) any later version. *
8 * *
9 * Gfxprim is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
12 * Lesser General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU Lesser General Public *
15 * License along with gfxprim; if not, write to the Free Software *
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
17 * Boston, MA 02110-1301 USA *
18 * *
19 * Copyright (C) 2009-2013 Cyril Hrubis <metan@ucw.cz> *
20 * *
21 *****************************************************************************/
23 #include <errno.h>
25 #include "core/GP_Debug.h"
26 #include "core/GP_Pixmap.h"
27 #include "backends/GP_AALib.h"
28 #include "input/GP_Input.h"
30 #include "../config.h"
32 #ifdef HAVE_AALIB
34 #include <aalib.h>
35 #include <pthread.h>
38 * Guards AALib library calls.
40 * In case we run under X the underlying xcb connection is not initialized with
41 * XInitThreads() and thus not multithread safe.
43 static pthread_mutex_t aalib_mutex = PTHREAD_MUTEX_INITIALIZER;
45 struct aalib_priv {
46 aa_context *c;
47 GP_Pixmap pixmap;
50 /* ascii mapped keys */
51 static const uint16_t keymap[] = {
52 0, 0, 0, 0,
53 0, 0, 0, GP_KEY_BACKSPACE,
54 GP_KEY_TAB, 0, 0, 0,
55 GP_KEY_ENTER, 0, 0, 0,
56 0, 0, GP_KEY_PAUSE, 0,
57 0, 0, 0, 0,
58 0, 0, GP_KEY_ESC, 0,
59 0, 0, 0, GP_KEY_SPACE,
60 0, 0, 0, 0,
61 0, 0, GP_KEY_APOSTROPHE, 0,
62 0, 0, 0, GP_KEY_COMMA,
63 GP_KEY_MINUS, GP_KEY_DOT, GP_KEY_SLASH, GP_KEY_0,
64 GP_KEY_1, GP_KEY_2, GP_KEY_3, GP_KEY_4,
65 GP_KEY_5, GP_KEY_6, GP_KEY_7, GP_KEY_8,
66 GP_KEY_9, 0, GP_KEY_SEMICOLON, 0,
67 GP_KEY_EQUAL, 0, 0, 0,
68 0, 0, 0, 0,
69 0, 0, 0, 0,
70 0, 0, 0, 0,
71 0, 0, 0, 0,
72 0, 0, 0, 0,
73 0, 0, 0, 0,
74 0, 0, GP_KEY_LEFT_BRACE, GP_KEY_BACKSLASH,
75 GP_KEY_RIGHT_BRACE, 0, 0, GP_KEY_GRAVE,
76 GP_KEY_A, GP_KEY_B, GP_KEY_C, GP_KEY_D,
77 GP_KEY_E, GP_KEY_F, GP_KEY_G, GP_KEY_H,
78 GP_KEY_I, GP_KEY_J, GP_KEY_K, GP_KEY_L,
79 GP_KEY_M, GP_KEY_N, GP_KEY_O, GP_KEY_P,
80 GP_KEY_Q, GP_KEY_R, GP_KEY_S, GP_KEY_T,
81 GP_KEY_U, GP_KEY_V, GP_KEY_W, GP_KEY_X,
82 GP_KEY_Y, GP_KEY_Z, 0, 0,
83 0, 0, GP_KEY_DELETE,
86 /* special keys mapped from 300 to 305 */
87 static const uint16_t keymap2[] = {
88 GP_KEY_UP, GP_KEY_DOWN,
89 GP_KEY_LEFT, GP_KEY_RIGHT,
90 GP_KEY_BACKSPACE, GP_KEY_ESC,
93 static void aalib_exit(GP_Backend *self)
95 struct aalib_priv *aa = GP_BACKEND_PRIV(self);
97 GP_DEBUG(1, "Closing AALib");
98 aa_close(aa->c);
101 static void aalib_flip(GP_Backend *self)
103 struct aalib_priv *aa = GP_BACKEND_PRIV(self);
105 GP_DEBUG(4, "Rendering and flipping screen");
107 aa_render(aa->c, &aa_defrenderparams,
108 0, 0, aa_scrwidth(aa->c), aa_scrheight(aa->c));
110 pthread_mutex_lock(&aalib_mutex);
111 aa_flush(aa->c);
112 pthread_mutex_unlock(&aalib_mutex);
115 static void aalib_update_rect(GP_Backend *self, GP_Coord x0, GP_Coord y0,
116 GP_Coord x1, GP_Coord y1)
118 struct aalib_priv *aa = GP_BACKEND_PRIV(self);
120 GP_DEBUG(4, "Updating rect %ix%i-%ix%i", x0, y0, x1, y1);
123 * TODO: Map screen coordinates to bitmap coordinates.
125 int w = aa_scrwidth(aa->c);
126 int h = aa_scrheight(aa->c);
128 aa_render(aa->c, &aa_defrenderparams,
129 0, 0, w, h);
131 pthread_mutex_lock(&aalib_mutex);
132 aa_flush(aa->c);
133 pthread_mutex_unlock(&aalib_mutex);
136 static int aalib_resize_ack(GP_Backend *self)
138 struct aalib_priv *aa = GP_BACKEND_PRIV(self);
140 if (!aa_resize(aa->c)) {
141 GP_WARN("aa_resize() failed");
142 return 1;
145 int w = aa_imgwidth(aa->c);
146 int h = aa_imgheight(aa->c);
148 GP_DEBUG(1, "Reinitializing Pixmap %ix%i", w, h);
150 GP_PixmapInit(&aa->pixmap, w, h, GP_PIXEL_G8, aa_image(aa->c));
152 return 0;
155 static void parse_event(GP_Backend *self, int ev)
157 unsigned int key;
159 if (ev == 0)
160 return;
162 if (ev == AA_RESIZE) {
163 GP_DEBUG(1, "Resize event");
164 //TODO: Can we get the new size somehow?
165 GP_EventQueuePushResize(&self->event_queue, 0, 0, NULL);
166 return;
169 if (ev <= (int)GP_ARRAY_SIZE(keymap)) {
170 key = keymap[ev - 1];
171 } else {
172 if (ev >= 300 && ev <= 305) {
173 key = keymap2[ev - 300];
174 } else {
175 GP_DEBUG(1, "Unhandled event %i", ev);
176 return;
180 /* emulate keyup events */
181 GP_EventQueuePushKey(&self->event_queue, key, 1, NULL);
182 GP_EventQueuePushKey(&self->event_queue, key, 0, NULL);
185 static void aalib_poll(GP_Backend *self)
187 struct aalib_priv *aa = GP_BACKEND_PRIV(self);
188 int key;
190 pthread_mutex_lock(&aalib_mutex);
191 key = aa_getevent(aa->c, 0);
192 pthread_mutex_unlock(&aalib_mutex);
194 parse_event(self, key);
197 static void aalib_wait(GP_Backend *self)
199 /* We cannot wait due to possible lockup, so we poll */
200 for (;;) {
201 aalib_poll(self);
203 if (GP_EventQueueEventsQueued(&self->event_queue))
204 return;
206 usleep(10000);
210 GP_Backend *GP_BackendAALibInit(void)
212 GP_Backend *backend;
213 struct aalib_priv *aa;
214 int w, h;
216 backend = malloc(sizeof(GP_Backend) + sizeof(struct aalib_priv));
218 if (backend == NULL)
219 return NULL;
221 aa = GP_BACKEND_PRIV(backend);
223 GP_DEBUG(1, "Initializing aalib");
225 aa->c = aa_autoinit(&aa_defparams);
227 if (!aa->c) {
228 GP_DEBUG(1, "Failed to initialize aalib");
229 goto err1;
232 GP_DEBUG(1, "AALib driver %s %s %ix%i", aa->c->driver->name,
233 aa->c->driver->shortname,
234 aa->c->params.width, aa->c->params.height);
236 if (!aa_autoinitkbd(aa->c, 0)) {
237 GP_DEBUG(1, "Failed to initialize aalib keyboard");
238 goto err2;
241 w = aa_imgwidth(aa->c);
242 h = aa_imgheight(aa->c);
244 GP_DEBUG(1, "Initializing Pixmap %ix%i", w, h);
246 GP_PixmapInit(&aa->pixmap, w, h, GP_PIXEL_G8, aa_image(aa->c));
248 /* update API */
249 backend->name = "AALib";
250 backend->pixmap = &aa->pixmap;
251 backend->Flip = aalib_flip;
252 backend->UpdateRect = aalib_update_rect;
253 backend->Exit = aalib_exit;
254 backend->SetAttributes = NULL;
255 backend->ResizeAck = aalib_resize_ack;
256 backend->Poll = aalib_poll;
257 backend->Wait = aalib_wait;
258 backend->fd = -1;
259 backend->timers = NULL;
261 GP_EventQueueInit(&backend->event_queue, w, h, 0);
263 return backend;
264 err2:
265 aa_close(aa->c);
266 err1:
267 free(backend);
268 return NULL;
271 #else
273 GP_Backend *GP_BackendAALibInit(void)
275 GP_FATAL("AALib support not compiled in!");
276 errno = ENOSYS;
277 return NULL;
280 #endif /* HAVE_AALIB */