1 /*****************************************************************************
2 * This file is part of gfxprim library. *
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. *
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. *
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 *
19 * Copyright (C) 2009-2013 Cyril Hrubis <metan@ucw.cz> *
21 *****************************************************************************/
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"
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
;
50 /* ascii mapped keys */
51 static const uint16_t keymap
[] = {
53 0, 0, 0, GP_KEY_BACKSPACE
,
55 GP_KEY_ENTER
, 0, 0, 0,
56 0, 0, GP_KEY_PAUSE
, 0,
59 0, 0, 0, GP_KEY_SPACE
,
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,
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,
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");
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
);
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
,
131 pthread_mutex_lock(&aalib_mutex
);
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");
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
));
155 static void parse_event(GP_Backend
*self
, int ev
)
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
);
169 if (ev
<= (int)GP_ARRAY_SIZE(keymap
)) {
170 key
= keymap
[ev
- 1];
172 if (ev
>= 300 && ev
<= 305) {
173 key
= keymap2
[ev
- 300];
175 GP_DEBUG(1, "Unhandled event %i", ev
);
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
);
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 */
203 if (GP_EventQueueEventsQueued(&self
->event_queue
))
210 GP_Backend
*GP_BackendAALibInit(void)
213 struct aalib_priv
*aa
;
216 backend
= malloc(sizeof(GP_Backend
) + sizeof(struct aalib_priv
));
221 aa
= GP_BACKEND_PRIV(backend
);
223 GP_DEBUG(1, "Initializing aalib");
225 aa
->c
= aa_autoinit(&aa_defparams
);
228 GP_DEBUG(1, "Failed to initialize aalib");
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");
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
));
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
;
259 backend
->timers
= NULL
;
261 GP_EventQueueInit(&backend
->event_queue
, w
, h
, 0);
273 GP_Backend
*GP_BackendAALibInit(void)
275 GP_FATAL("AALib support not compiled in!");
280 #endif /* HAVE_AALIB */