diff options
Diffstat (limited to 'apps/plugins/sdl/src/video/wscons')
-rw-r--r-- | apps/plugins/sdl/src/video/wscons/SDL_wsconsevents.c | 233 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/wscons/SDL_wsconsevents_c.h | 36 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/wscons/SDL_wsconsmouse.c | 33 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/wscons/SDL_wsconsmouse_c.h | 26 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/wscons/SDL_wsconsvideo.c | 609 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/wscons/SDL_wsconsvideo.h | 76 |
6 files changed, 1013 insertions, 0 deletions
diff --git a/apps/plugins/sdl/src/video/wscons/SDL_wsconsevents.c b/apps/plugins/sdl/src/video/wscons/SDL_wsconsevents.c new file mode 100644 index 0000000000..635b972f0a --- /dev/null +++ b/apps/plugins/sdl/src/video/wscons/SDL_wsconsevents.c | |||
@@ -0,0 +1,233 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #include <sys/types.h> | ||
25 | #include <dev/wscons/wsdisplay_usl_io.h> | ||
26 | #include <sys/ioctl.h> | ||
27 | #include <fcntl.h> | ||
28 | #include <unistd.h> | ||
29 | #include <termios.h> | ||
30 | #include <errno.h> | ||
31 | #include <string.h> | ||
32 | |||
33 | #include "SDL.h" | ||
34 | #include "../../events/SDL_sysevents.h" | ||
35 | #include "../../events/SDL_events_c.h" | ||
36 | #include "SDL_wsconsvideo.h" | ||
37 | #include "SDL_wsconsevents_c.h" | ||
38 | |||
39 | static int posted = 0; | ||
40 | |||
41 | int WSCONS_InitKeyboard(_THIS) | ||
42 | { | ||
43 | struct termios tty; | ||
44 | |||
45 | if (ioctl(private->fd, WSKBDIO_GTYPE, &private->kbdType) == -1) { | ||
46 | WSCONS_ReportError("cannot get keyboard type: %s", strerror(errno)); | ||
47 | return -1; | ||
48 | } | ||
49 | |||
50 | if (tcgetattr(private->fd, &private->saved_tty) == -1) { | ||
51 | WSCONS_ReportError("cannot get terminal attributes: %s", strerror(errno)); | ||
52 | return -1; | ||
53 | } | ||
54 | private->did_save_tty = 1; | ||
55 | tty = private->saved_tty; | ||
56 | tty.c_iflag = IGNPAR | IGNBRK; | ||
57 | tty.c_oflag = 0; | ||
58 | tty.c_cflag = CREAD | CS8; | ||
59 | tty.c_lflag = 0; | ||
60 | tty.c_cc[VTIME] = 0; | ||
61 | tty.c_cc[VMIN] = 1; | ||
62 | cfsetispeed(&tty, 9600); | ||
63 | cfsetospeed(&tty, 9600); | ||
64 | if (tcsetattr(private->fd, TCSANOW, &tty) < 0) { | ||
65 | WSCONS_ReportError("cannot set terminal attributes: %s", strerror(errno)); | ||
66 | return -1; | ||
67 | } | ||
68 | if (ioctl(private->fd, KDSKBMODE, K_RAW) == -1) { | ||
69 | WSCONS_ReportError("cannot set raw keyboard mode: %s", strerror(errno)); | ||
70 | return -1; | ||
71 | } | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | void WSCONS_ReleaseKeyboard(_THIS) | ||
77 | { | ||
78 | if (private->fd != -1) { | ||
79 | if (ioctl(private->fd, KDSKBMODE, K_XLATE) == -1) { | ||
80 | WSCONS_ReportError("cannot restore keyboard to translated mode: %s", | ||
81 | strerror(errno)); | ||
82 | } | ||
83 | if (private->did_save_tty) { | ||
84 | if (tcsetattr(private->fd, TCSANOW, &private->saved_tty) < 0) { | ||
85 | WSCONS_ReportError("cannot restore keynoard attributes: %s", | ||
86 | strerror(errno)); | ||
87 | } | ||
88 | } | ||
89 | } | ||
90 | } | ||
91 | |||
92 | static void updateMouse() | ||
93 | { | ||
94 | } | ||
95 | |||
96 | static SDLKey keymap[128]; | ||
97 | |||
98 | static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym) | ||
99 | { | ||
100 | keysym->scancode = scancode; | ||
101 | keysym->sym = SDLK_UNKNOWN; | ||
102 | keysym->mod = KMOD_NONE; | ||
103 | |||
104 | if (scancode < SDL_arraysize(keymap)) | ||
105 | keysym->sym = keymap[scancode]; | ||
106 | |||
107 | if (keysym->sym == SDLK_UNKNOWN) | ||
108 | printf("Unknown mapping for scancode %d\n", scancode); | ||
109 | |||
110 | return keysym; | ||
111 | } | ||
112 | |||
113 | static void updateKeyboard(_THIS) | ||
114 | { | ||
115 | unsigned char buf[100]; | ||
116 | SDL_keysym keysym; | ||
117 | int n, i; | ||
118 | |||
119 | if ((n = read(private->fd, buf, sizeof(buf))) > 0) { | ||
120 | for (i = 0; i < n; i++) { | ||
121 | unsigned char c = buf[i] & 0x7f; | ||
122 | if (c == 224) // special key prefix -- what should we do with it? | ||
123 | continue; | ||
124 | posted += SDL_PrivateKeyboard((buf[i] & 0x80) ? SDL_RELEASED : SDL_PRESSED, | ||
125 | TranslateKey(c, &keysym)); | ||
126 | } | ||
127 | } | ||
128 | } | ||
129 | |||
130 | void WSCONS_PumpEvents(_THIS) | ||
131 | { | ||
132 | do { | ||
133 | posted = 0; | ||
134 | updateMouse(); | ||
135 | updateKeyboard(this); | ||
136 | } while (posted); | ||
137 | } | ||
138 | |||
139 | void WSCONS_InitOSKeymap(_THIS) | ||
140 | { | ||
141 | int i; | ||
142 | |||
143 | /* Make sure unknown keys are mapped correctly */ | ||
144 | for (i=0; i < SDL_arraysize(keymap); i++) { | ||
145 | keymap[i] = SDLK_UNKNOWN; | ||
146 | } | ||
147 | |||
148 | switch (private->kbdType) { | ||
149 | #ifdef WSKBD_TYPE_ZAURUS | ||
150 | case WSKBD_TYPE_ZAURUS: | ||
151 | /* top row */ | ||
152 | keymap[2] = SDLK_1; | ||
153 | keymap[3] = SDLK_2; | ||
154 | keymap[4] = SDLK_3; | ||
155 | keymap[5] = SDLK_4; | ||
156 | keymap[6] = SDLK_5; | ||
157 | keymap[7] = SDLK_6; | ||
158 | keymap[8] = SDLK_7; | ||
159 | keymap[9] = SDLK_8; | ||
160 | keymap[10] = SDLK_9; | ||
161 | keymap[11] = SDLK_0; | ||
162 | keymap[14] = SDLK_BACKSPACE; | ||
163 | |||
164 | /* second row */ | ||
165 | keymap[16] = SDLK_q; | ||
166 | keymap[17] = SDLK_w; | ||
167 | keymap[18] = SDLK_e; | ||
168 | keymap[19] = SDLK_r; | ||
169 | keymap[20] = SDLK_t; | ||
170 | keymap[21] = SDLK_y; | ||
171 | keymap[22] = SDLK_u; | ||
172 | keymap[23] = SDLK_i; | ||
173 | keymap[24] = SDLK_o; | ||
174 | keymap[25] = SDLK_p; | ||
175 | |||
176 | /* third row */ | ||
177 | keymap[15] = SDLK_TAB; | ||
178 | keymap[30] = SDLK_a; | ||
179 | keymap[31] = SDLK_s; | ||
180 | keymap[32] = SDLK_d; | ||
181 | keymap[33] = SDLK_f; | ||
182 | keymap[34] = SDLK_g; | ||
183 | keymap[35] = SDLK_h; | ||
184 | keymap[36] = SDLK_j; | ||
185 | keymap[37] = SDLK_k; | ||
186 | keymap[38] = SDLK_l; | ||
187 | |||
188 | /* fourth row */ | ||
189 | keymap[42] = SDLK_LSHIFT; | ||
190 | keymap[44] = SDLK_z; | ||
191 | keymap[45] = SDLK_x; | ||
192 | keymap[46] = SDLK_c; | ||
193 | keymap[47] = SDLK_v; | ||
194 | keymap[48] = SDLK_b; | ||
195 | keymap[49] = SDLK_n; | ||
196 | keymap[50] = SDLK_m; | ||
197 | keymap[54] = SDLK_RSHIFT; | ||
198 | keymap[28] = SDLK_RETURN; | ||
199 | |||
200 | /* fifth row */ | ||
201 | keymap[56] = SDLK_LALT; | ||
202 | keymap[29] = SDLK_LCTRL; | ||
203 | /* keymap[56] = ; */ | ||
204 | keymap[0] = SDLK_LSUPER; | ||
205 | keymap[12] = SDLK_MINUS; | ||
206 | keymap[57] = SDLK_SPACE; | ||
207 | keymap[51] = SDLK_COMMA; | ||
208 | keymap[52] = SDLK_PERIOD; | ||
209 | |||
210 | /* misc */ | ||
211 | keymap[59] = SDLK_F1; | ||
212 | keymap[60] = SDLK_F2; | ||
213 | keymap[61] = SDLK_F3; | ||
214 | keymap[62] = SDLK_F4; | ||
215 | keymap[63] = SDLK_F5; | ||
216 | keymap[1] = SDLK_ESCAPE; | ||
217 | /* keymap[28] = SDLK_KP_ENTER; */ | ||
218 | keymap[72] = SDLK_UP; | ||
219 | keymap[75] = SDLK_LEFT; | ||
220 | keymap[77] = SDLK_RIGHT; | ||
221 | keymap[80] = SDLK_DOWN; | ||
222 | break; | ||
223 | #endif /* WSKBD_TYPE_ZAURUS */ | ||
224 | |||
225 | default: | ||
226 | WSCONS_ReportError("Unable to map keys for keyboard type %u", | ||
227 | private->kbdType); | ||
228 | break; | ||
229 | } | ||
230 | } | ||
231 | |||
232 | /* end of SDL_wsconsevents.c ... */ | ||
233 | |||
diff --git a/apps/plugins/sdl/src/video/wscons/SDL_wsconsevents_c.h b/apps/plugins/sdl/src/video/wscons/SDL_wsconsevents_c.h new file mode 100644 index 0000000000..f68ee6e119 --- /dev/null +++ b/apps/plugins/sdl/src/video/wscons/SDL_wsconsevents_c.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #include "SDL_wsconsvideo.h" | ||
25 | |||
26 | int WSCONS_InitKeyboard(_THIS); | ||
27 | void WSCONS_ReleaseKeyboard(_THIS); | ||
28 | |||
29 | /* Variables and functions exported by SDL_sysevents.c to other parts | ||
30 | of the native video subsystem (SDL_sysvideo.c) | ||
31 | */ | ||
32 | extern void WSCONS_InitOSKeymap(_THIS); | ||
33 | extern void WSCONS_PumpEvents(_THIS); | ||
34 | |||
35 | /* end of SDL_wsconsevents_c.h ... */ | ||
36 | |||
diff --git a/apps/plugins/sdl/src/video/wscons/SDL_wsconsmouse.c b/apps/plugins/sdl/src/video/wscons/SDL_wsconsmouse.c new file mode 100644 index 0000000000..b69e0c5f48 --- /dev/null +++ b/apps/plugins/sdl/src/video/wscons/SDL_wsconsmouse.c | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #include "SDL_mouse.h" | ||
25 | #include "../../events/SDL_events_c.h" | ||
26 | |||
27 | #include "SDL_wsconsmouse_c.h" | ||
28 | |||
29 | |||
30 | /* The implementation dependent data for the window manager cursor */ | ||
31 | struct WMcursor { | ||
32 | int unused; | ||
33 | }; | ||
diff --git a/apps/plugins/sdl/src/video/wscons/SDL_wsconsmouse_c.h b/apps/plugins/sdl/src/video/wscons/SDL_wsconsmouse_c.h new file mode 100644 index 0000000000..875437bcd4 --- /dev/null +++ b/apps/plugins/sdl/src/video/wscons/SDL_wsconsmouse_c.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #include "SDL_wsconsvideo.h" | ||
25 | |||
26 | /* Functions to be exported */ | ||
diff --git a/apps/plugins/sdl/src/video/wscons/SDL_wsconsvideo.c b/apps/plugins/sdl/src/video/wscons/SDL_wsconsvideo.c new file mode 100644 index 0000000000..0e850d13e0 --- /dev/null +++ b/apps/plugins/sdl/src/video/wscons/SDL_wsconsvideo.c | |||
@@ -0,0 +1,609 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #include <sys/time.h> | ||
25 | #include <sys/mman.h> | ||
26 | #include <sys/ioctl.h> | ||
27 | #include <dev/wscons/wsdisplay_usl_io.h> | ||
28 | #include <fcntl.h> | ||
29 | #include <unistd.h> | ||
30 | #include <errno.h> | ||
31 | |||
32 | #include "SDL_video.h" | ||
33 | #include "SDL_mouse.h" | ||
34 | #include "../SDL_sysvideo.h" | ||
35 | #include "../SDL_pixels_c.h" | ||
36 | #include "../../events/SDL_events_c.h" | ||
37 | |||
38 | #include "SDL_wsconsvideo.h" | ||
39 | #include "SDL_wsconsevents_c.h" | ||
40 | #include "SDL_wsconsmouse_c.h" | ||
41 | |||
42 | #define WSCONSVID_DRIVER_NAME "wscons" | ||
43 | enum { | ||
44 | WSCONS_ROTATE_NONE = 0, | ||
45 | WSCONS_ROTATE_CCW = 90, | ||
46 | WSCONS_ROTATE_UD = 180, | ||
47 | WSCONS_ROTATE_CW = 270 | ||
48 | }; | ||
49 | |||
50 | #define min(a,b) ((a)<(b)?(a):(b)) | ||
51 | |||
52 | /* Initialization/Query functions */ | ||
53 | static int WSCONS_VideoInit(_THIS, SDL_PixelFormat *vformat); | ||
54 | static SDL_Rect **WSCONS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); | ||
55 | static SDL_Surface *WSCONS_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); | ||
56 | static int WSCONS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); | ||
57 | static void WSCONS_VideoQuit(_THIS); | ||
58 | |||
59 | /* Hardware surface functions */ | ||
60 | static int WSCONS_AllocHWSurface(_THIS, SDL_Surface *surface); | ||
61 | static int WSCONS_LockHWSurface(_THIS, SDL_Surface *surface); | ||
62 | static void WSCONS_UnlockHWSurface(_THIS, SDL_Surface *surface); | ||
63 | static void WSCONS_FreeHWSurface(_THIS, SDL_Surface *surface); | ||
64 | |||
65 | /* etc. */ | ||
66 | static WSCONS_bitBlit WSCONS_blit16; | ||
67 | static WSCONS_bitBlit WSCONS_blit16blocked; | ||
68 | static void WSCONS_UpdateRects(_THIS, int numrects, SDL_Rect *rects); | ||
69 | |||
70 | void WSCONS_ReportError(char *fmt, ...) | ||
71 | { | ||
72 | char message[200]; | ||
73 | va_list vaArgs; | ||
74 | |||
75 | message[199] = '\0'; | ||
76 | |||
77 | va_start(vaArgs, fmt); | ||
78 | vsnprintf(message, 199, fmt, vaArgs); | ||
79 | va_end(vaArgs); | ||
80 | |||
81 | SDL_SetError(message); | ||
82 | fprintf(stderr, "WSCONS error: %s\n", message); | ||
83 | } | ||
84 | |||
85 | /* WSCONS driver bootstrap functions */ | ||
86 | |||
87 | static int WSCONS_Available(void) | ||
88 | { | ||
89 | return 1; | ||
90 | } | ||
91 | |||
92 | static void WSCONS_DeleteDevice(SDL_VideoDevice *device) | ||
93 | { | ||
94 | SDL_free(device->hidden); | ||
95 | SDL_free(device); | ||
96 | } | ||
97 | |||
98 | static SDL_VideoDevice *WSCONS_CreateDevice(int devindex) | ||
99 | { | ||
100 | SDL_VideoDevice *device; | ||
101 | |||
102 | /* Initialize all variables that we clean on shutdown */ | ||
103 | device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); | ||
104 | if (device == NULL) { | ||
105 | SDL_OutOfMemory(); | ||
106 | return 0; | ||
107 | } | ||
108 | SDL_memset(device, 0, (sizeof *device)); | ||
109 | device->hidden = | ||
110 | (struct SDL_PrivateVideoData *)SDL_malloc((sizeof *device->hidden)); | ||
111 | if (device->hidden == NULL) { | ||
112 | SDL_OutOfMemory(); | ||
113 | SDL_free(device); | ||
114 | return(0); | ||
115 | } | ||
116 | SDL_memset(device->hidden, 0, (sizeof *device->hidden)); | ||
117 | device->hidden->fd = -1; | ||
118 | |||
119 | /* Set the function pointers */ | ||
120 | device->VideoInit = WSCONS_VideoInit; | ||
121 | device->ListModes = WSCONS_ListModes; | ||
122 | device->SetVideoMode = WSCONS_SetVideoMode; | ||
123 | device->SetColors = WSCONS_SetColors; | ||
124 | device->UpdateRects = WSCONS_UpdateRects; | ||
125 | device->VideoQuit = WSCONS_VideoQuit; | ||
126 | device->AllocHWSurface = WSCONS_AllocHWSurface; | ||
127 | device->LockHWSurface = WSCONS_LockHWSurface; | ||
128 | device->UnlockHWSurface = WSCONS_UnlockHWSurface; | ||
129 | device->FreeHWSurface = WSCONS_FreeHWSurface; | ||
130 | device->InitOSKeymap = WSCONS_InitOSKeymap; | ||
131 | device->PumpEvents = WSCONS_PumpEvents; | ||
132 | device->free = WSCONS_DeleteDevice; | ||
133 | |||
134 | return device; | ||
135 | } | ||
136 | |||
137 | VideoBootStrap WSCONS_bootstrap = { | ||
138 | WSCONSVID_DRIVER_NAME, | ||
139 | "SDL wscons video driver", | ||
140 | WSCONS_Available, | ||
141 | WSCONS_CreateDevice | ||
142 | }; | ||
143 | |||
144 | #define WSCONSDEV_FORMAT "/dev/ttyC%01x" | ||
145 | |||
146 | int WSCONS_VideoInit(_THIS, SDL_PixelFormat *vformat) | ||
147 | { | ||
148 | char devnamebuf[30]; | ||
149 | char *devname; | ||
150 | char *rotation; | ||
151 | int wstype; | ||
152 | int wsmode = WSDISPLAYIO_MODE_DUMBFB; | ||
153 | size_t len, mapsize; | ||
154 | int pagemask; | ||
155 | int width, height; | ||
156 | |||
157 | devname = SDL_getenv("SDL_WSCONSDEV"); | ||
158 | if (devname == NULL) { | ||
159 | int activeVT; | ||
160 | if (ioctl(STDIN_FILENO, VT_GETACTIVE, &activeVT) == -1) { | ||
161 | WSCONS_ReportError("Unable to determine active terminal: %s", | ||
162 | strerror(errno)); | ||
163 | return -1; | ||
164 | } | ||
165 | SDL_snprintf(devnamebuf, sizeof(devnamebuf), WSCONSDEV_FORMAT, activeVT - 1); | ||
166 | devname = devnamebuf; | ||
167 | } | ||
168 | |||
169 | private->fd = open(devname, O_RDWR | O_NONBLOCK, 0); | ||
170 | if (private->fd == -1) { | ||
171 | WSCONS_ReportError("open %s: %s", devname, strerror(errno)); | ||
172 | return -1; | ||
173 | } | ||
174 | if (ioctl(private->fd, WSDISPLAYIO_GINFO, &private->info) == -1) { | ||
175 | WSCONS_ReportError("ioctl WSDISPLAY_GINFO: %s", strerror(errno)); | ||
176 | return -1; | ||
177 | } | ||
178 | if (ioctl(private->fd, WSDISPLAYIO_GTYPE, &wstype) == -1) { | ||
179 | WSCONS_ReportError("ioctl WSDISPLAY_GTYPE: %s", strerror(errno)); | ||
180 | return -1; | ||
181 | } | ||
182 | if (ioctl(private->fd, WSDISPLAYIO_LINEBYTES, &private->physlinebytes) == -1) { | ||
183 | WSCONS_ReportError("ioctl WSDISPLAYIO_LINEBYTES: %s", strerror(errno)); | ||
184 | return -1; | ||
185 | } | ||
186 | if (private->info.depth > 8) { | ||
187 | if (wstype == WSDISPLAY_TYPE_SUN24 || | ||
188 | wstype == WSDISPLAY_TYPE_SUNCG12 || | ||
189 | wstype == WSDISPLAY_TYPE_SUNCG14 || | ||
190 | wstype == WSDISPLAY_TYPE_SUNTCX || | ||
191 | wstype == WSDISPLAY_TYPE_SUNFFB) { | ||
192 | private->redMask = 0x0000ff; | ||
193 | private->greenMask = 0x00ff00; | ||
194 | private->blueMask = 0xff0000; | ||
195 | #ifdef WSDISPLAY_TYPE_PXALCD | ||
196 | } else if (wstype == WSDISPLAY_TYPE_PXALCD) { | ||
197 | private->redMask = 0x1f << 11; | ||
198 | private->greenMask = 0x3f << 5; | ||
199 | private->blueMask = 0x1f; | ||
200 | #endif | ||
201 | } else { | ||
202 | WSCONS_ReportError("Unknown video hardware"); | ||
203 | return -1; | ||
204 | } | ||
205 | } else { | ||
206 | WSCONS_ReportError("Displays with 8 bpp or less are not supported"); | ||
207 | return -1; | ||
208 | } | ||
209 | |||
210 | private->rotate = WSCONS_ROTATE_NONE; | ||
211 | rotation = SDL_getenv("SDL_VIDEO_WSCONS_ROTATION"); | ||
212 | if (rotation != NULL) { | ||
213 | if (SDL_strlen(rotation) == 0) { | ||
214 | private->shadowFB = 0; | ||
215 | private->rotate = WSCONS_ROTATE_NONE; | ||
216 | printf("Not rotating, no shadow\n"); | ||
217 | } else if (!SDL_strcmp(rotation, "NONE")) { | ||
218 | private->shadowFB = 1; | ||
219 | private->rotate = WSCONS_ROTATE_NONE; | ||
220 | printf("Not rotating, but still using shadow\n"); | ||
221 | } else if (!SDL_strcmp(rotation, "CW")) { | ||
222 | private->shadowFB = 1; | ||
223 | private->rotate = WSCONS_ROTATE_CW; | ||
224 | printf("Rotating screen clockwise\n"); | ||
225 | } else if (!SDL_strcmp(rotation, "CCW")) { | ||
226 | private->shadowFB = 1; | ||
227 | private->rotate = WSCONS_ROTATE_CCW; | ||
228 | printf("Rotating screen counter clockwise\n"); | ||
229 | } else if (!SDL_strcmp(rotation, "UD")) { | ||
230 | private->shadowFB = 1; | ||
231 | private->rotate = WSCONS_ROTATE_UD; | ||
232 | printf("Rotating screen upside down\n"); | ||
233 | } else { | ||
234 | WSCONS_ReportError("\"%s\" is not a valid value for " | ||
235 | "SDL_VIDEO_WSCONS_ROTATION", rotation); | ||
236 | return -1; | ||
237 | } | ||
238 | } | ||
239 | |||
240 | switch (private->info.depth) { | ||
241 | case 1: | ||
242 | case 4: | ||
243 | case 8: | ||
244 | len = private->physlinebytes * private->info.height; | ||
245 | break; | ||
246 | case 16: | ||
247 | if (private->physlinebytes == private->info.width) { | ||
248 | len = private->info.width * private->info.height * sizeof(short); | ||
249 | } else { | ||
250 | len = private->physlinebytes * private->info.height; | ||
251 | } | ||
252 | if (private->rotate == WSCONS_ROTATE_NONE || | ||
253 | private->rotate == WSCONS_ROTATE_UD) { | ||
254 | private->blitFunc = WSCONS_blit16; | ||
255 | } else { | ||
256 | private->blitFunc = WSCONS_blit16blocked; | ||
257 | } | ||
258 | break; | ||
259 | case 32: | ||
260 | if (private->physlinebytes == private->info.width) { | ||
261 | len = private->info.width * private->info.height * sizeof(int); | ||
262 | } else { | ||
263 | len = private->physlinebytes * private->info.height; | ||
264 | } | ||
265 | break; | ||
266 | default: | ||
267 | WSCONS_ReportError("unsupported depth %d", private->info.depth); | ||
268 | return -1; | ||
269 | } | ||
270 | |||
271 | if (private->shadowFB && private->blitFunc == NULL) { | ||
272 | WSCONS_ReportError("Using software buffer, but no blitter function is " | ||
273 | "available for this %d bpp.", private->info.depth); | ||
274 | return -1; | ||
275 | } | ||
276 | |||
277 | if (ioctl(private->fd, WSDISPLAYIO_SMODE, &wsmode) == -1) { | ||
278 | WSCONS_ReportError("ioctl SMODE"); | ||
279 | return -1; | ||
280 | } | ||
281 | |||
282 | pagemask = getpagesize() - 1; | ||
283 | mapsize = ((int)len + pagemask) & ~pagemask; | ||
284 | private->physmem = (Uint8 *)mmap(NULL, mapsize, | ||
285 | PROT_READ | PROT_WRITE, MAP_SHARED, | ||
286 | private->fd, (off_t)0); | ||
287 | if (private->physmem == (Uint8 *)MAP_FAILED) { | ||
288 | private->physmem = NULL; | ||
289 | WSCONS_ReportError("mmap: %s", strerror(errno)); | ||
290 | return -1; | ||
291 | } | ||
292 | private->fbmem_len = len; | ||
293 | |||
294 | if (private->rotate == WSCONS_ROTATE_CW || | ||
295 | private->rotate == WSCONS_ROTATE_CCW) { | ||
296 | width = private->info.height; | ||
297 | height = private->info.width; | ||
298 | } else { | ||
299 | width = private->info.width; | ||
300 | height = private->info.height; | ||
301 | } | ||
302 | |||
303 | this->info.current_w = width; | ||
304 | this->info.current_h = height; | ||
305 | |||
306 | if (private->shadowFB) { | ||
307 | private->shadowmem = (Uint8 *)SDL_malloc(len); | ||
308 | if (private->shadowmem == NULL) { | ||
309 | WSCONS_ReportError("No memory for shadow"); | ||
310 | return -1; | ||
311 | } | ||
312 | private->fbstart = private->shadowmem; | ||
313 | private->fblinebytes = width * ((private->info.depth + 7) / 8); | ||
314 | } else { | ||
315 | private->fbstart = private->physmem; | ||
316 | private->fblinebytes = private->physlinebytes; | ||
317 | } | ||
318 | |||
319 | private->SDL_modelist[0] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect)); | ||
320 | private->SDL_modelist[0]->w = width; | ||
321 | private->SDL_modelist[0]->h = height; | ||
322 | |||
323 | vformat->BitsPerPixel = private->info.depth; | ||
324 | vformat->BytesPerPixel = private->info.depth / 8; | ||
325 | |||
326 | if (WSCONS_InitKeyboard(this) == -1) { | ||
327 | return -1; | ||
328 | } | ||
329 | |||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | SDL_Rect **WSCONS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) | ||
334 | { | ||
335 | if (format->BitsPerPixel == private->info.depth) { | ||
336 | return private->SDL_modelist; | ||
337 | } else { | ||
338 | return NULL; | ||
339 | } | ||
340 | } | ||
341 | |||
342 | SDL_Surface *WSCONS_SetVideoMode(_THIS, SDL_Surface *current, | ||
343 | int width, int height, int bpp, Uint32 flags) | ||
344 | { | ||
345 | if (width != private->SDL_modelist[0]->w || | ||
346 | height != private->SDL_modelist[0]->h) { | ||
347 | WSCONS_ReportError("Requested video mode %dx%d not supported.", | ||
348 | width, height); | ||
349 | return NULL; | ||
350 | } | ||
351 | if (bpp != private->info.depth) { | ||
352 | WSCONS_ReportError("Requested video depth %d bpp not supported.", bpp); | ||
353 | return NULL; | ||
354 | } | ||
355 | |||
356 | if (!SDL_ReallocFormat(current, | ||
357 | bpp, | ||
358 | private->redMask, | ||
359 | private->greenMask, | ||
360 | private->blueMask, | ||
361 | 0)) { | ||
362 | WSCONS_ReportError("Couldn't allocate new pixel format"); | ||
363 | return NULL; | ||
364 | } | ||
365 | |||
366 | current->flags &= SDL_FULLSCREEN; | ||
367 | if (private->shadowFB) { | ||
368 | current->flags |= SDL_SWSURFACE; | ||
369 | } else { | ||
370 | current->flags |= SDL_HWSURFACE; | ||
371 | } | ||
372 | current->w = width; | ||
373 | current->h = height; | ||
374 | current->pitch = private->fblinebytes; | ||
375 | current->pixels = private->fbstart; | ||
376 | |||
377 | SDL_memset(private->fbstart, 0, private->fbmem_len); | ||
378 | |||
379 | return current; | ||
380 | } | ||
381 | |||
382 | static int WSCONS_AllocHWSurface(_THIS, SDL_Surface *surface) | ||
383 | { | ||
384 | return -1; | ||
385 | } | ||
386 | static void WSCONS_FreeHWSurface(_THIS, SDL_Surface *surface) | ||
387 | { | ||
388 | } | ||
389 | |||
390 | static int WSCONS_LockHWSurface(_THIS, SDL_Surface *surface) | ||
391 | { | ||
392 | return 0; | ||
393 | } | ||
394 | |||
395 | static void WSCONS_UnlockHWSurface(_THIS, SDL_Surface *surface) | ||
396 | { | ||
397 | } | ||
398 | |||
399 | static void WSCONS_blit16(Uint8 *byte_src_pos, | ||
400 | int srcRightDelta, | ||
401 | int srcDownDelta, | ||
402 | Uint8 *byte_dst_pos, | ||
403 | int dst_linebytes, | ||
404 | int width, | ||
405 | int height) | ||
406 | { | ||
407 | int w; | ||
408 | Uint16 *src_pos = (Uint16 *)byte_src_pos; | ||
409 | Uint16 *dst_pos = (Uint16 *)byte_dst_pos; | ||
410 | |||
411 | while (height) { | ||
412 | Uint16 *src = src_pos; | ||
413 | Uint16 *dst = dst_pos; | ||
414 | for (w = width; w != 0; w--) { | ||
415 | *dst = *src; | ||
416 | src += srcRightDelta; | ||
417 | dst++; | ||
418 | } | ||
419 | dst_pos = (Uint16 *)((Uint8 *)dst_pos + dst_linebytes); | ||
420 | src_pos += srcDownDelta; | ||
421 | height--; | ||
422 | } | ||
423 | } | ||
424 | |||
425 | #define BLOCKSIZE_W 32 | ||
426 | #define BLOCKSIZE_H 32 | ||
427 | |||
428 | static void WSCONS_blit16blocked(Uint8 *byte_src_pos, | ||
429 | int srcRightDelta, | ||
430 | int srcDownDelta, | ||
431 | Uint8 *byte_dst_pos, | ||
432 | int dst_linebytes, | ||
433 | int width, | ||
434 | int height) | ||
435 | { | ||
436 | int w; | ||
437 | Uint16 *src_pos = (Uint16 *)byte_src_pos; | ||
438 | Uint16 *dst_pos = (Uint16 *)byte_dst_pos; | ||
439 | |||
440 | while (height > 0) { | ||
441 | Uint16 *src = src_pos; | ||
442 | Uint16 *dst = dst_pos; | ||
443 | for (w = width; w > 0; w -= BLOCKSIZE_W) { | ||
444 | WSCONS_blit16((Uint8 *)src, | ||
445 | srcRightDelta, | ||
446 | srcDownDelta, | ||
447 | (Uint8 *)dst, | ||
448 | dst_linebytes, | ||
449 | min(w, BLOCKSIZE_W), | ||
450 | min(height, BLOCKSIZE_H)); | ||
451 | src += srcRightDelta * BLOCKSIZE_W; | ||
452 | dst += BLOCKSIZE_W; | ||
453 | } | ||
454 | dst_pos = (Uint16 *)((Uint8 *)dst_pos + dst_linebytes * BLOCKSIZE_H); | ||
455 | src_pos += srcDownDelta * BLOCKSIZE_H; | ||
456 | height -= BLOCKSIZE_H; | ||
457 | } | ||
458 | } | ||
459 | |||
460 | static void WSCONS_UpdateRects(_THIS, int numrects, SDL_Rect *rects) | ||
461 | { | ||
462 | int width = private->SDL_modelist[0]->w; | ||
463 | int height = private->SDL_modelist[0]->h; | ||
464 | int bytesPerPixel = (private->info.depth + 7) / 8; | ||
465 | int i; | ||
466 | |||
467 | if (!private->shadowFB) { | ||
468 | return; | ||
469 | } | ||
470 | |||
471 | if (private->info.depth != 16) { | ||
472 | WSCONS_ReportError("Shadow copy only implemented for 16 bpp"); | ||
473 | return; | ||
474 | } | ||
475 | |||
476 | for (i = 0; i < numrects; i++) { | ||
477 | int x1, y1, x2, y2; | ||
478 | int scr_x1, scr_y1, scr_x2, scr_y2; | ||
479 | int sha_x1, sha_y1; | ||
480 | int shadowRightDelta; /* Address change when moving right in dest */ | ||
481 | int shadowDownDelta; /* Address change when moving down in dest */ | ||
482 | Uint8 *src_start; | ||
483 | Uint8 *dst_start; | ||
484 | |||
485 | x1 = rects[i].x; | ||
486 | y1 = rects[i].y; | ||
487 | x2 = x1 + rects[i].w; | ||
488 | y2 = y1 + rects[i].h; | ||
489 | |||
490 | if (x1 < 0) { | ||
491 | x1 = 0; | ||
492 | } else if (x1 > width) { | ||
493 | x1 = width; | ||
494 | } | ||
495 | if (x2 < 0) { | ||
496 | x2 = 0; | ||
497 | } else if (x2 > width) { | ||
498 | x2 = width; | ||
499 | } | ||
500 | if (y1 < 0) { | ||
501 | y1 = 0; | ||
502 | } else if (y1 > height) { | ||
503 | y1 = height; | ||
504 | } | ||
505 | if (y2 < 0) { | ||
506 | y2 = 0; | ||
507 | } else if (y2 > height) { | ||
508 | y2 = height; | ||
509 | } | ||
510 | if (x2 <= x1 || y2 <= y1) { | ||
511 | continue; | ||
512 | } | ||
513 | |||
514 | switch (private->rotate) { | ||
515 | case WSCONS_ROTATE_NONE: | ||
516 | sha_x1 = scr_x1 = x1; | ||
517 | sha_y1 = scr_y1 = y1; | ||
518 | scr_x2 = x2; | ||
519 | scr_y2 = y2; | ||
520 | shadowRightDelta = 1; | ||
521 | shadowDownDelta = width; | ||
522 | break; | ||
523 | case WSCONS_ROTATE_CCW: | ||
524 | scr_x1 = y1; | ||
525 | scr_y1 = width - x2; | ||
526 | scr_x2 = y2; | ||
527 | scr_y2 = width - x1; | ||
528 | sha_x1 = x2 - 1; | ||
529 | sha_y1 = y1; | ||
530 | shadowRightDelta = width; | ||
531 | shadowDownDelta = -1; | ||
532 | break; | ||
533 | case WSCONS_ROTATE_UD: | ||
534 | scr_x1 = width - x2; | ||
535 | scr_y1 = height - y2; | ||
536 | scr_x2 = width - x1; | ||
537 | scr_y2 = height - y1; | ||
538 | sha_x1 = x2 - 1; | ||
539 | sha_y1 = y2 - 1; | ||
540 | shadowRightDelta = -1; | ||
541 | shadowDownDelta = -width; | ||
542 | break; | ||
543 | case WSCONS_ROTATE_CW: | ||
544 | scr_x1 = height - y2; | ||
545 | scr_y1 = x1; | ||
546 | scr_x2 = height - y1; | ||
547 | scr_y2 = x2; | ||
548 | sha_x1 = x1; | ||
549 | sha_y1 = y2 - 1; | ||
550 | shadowRightDelta = -width; | ||
551 | shadowDownDelta = 1; | ||
552 | break; | ||
553 | default: | ||
554 | WSCONS_ReportError("Unknown rotation"); | ||
555 | return; | ||
556 | } | ||
557 | |||
558 | src_start = private->shadowmem + (sha_y1 * width + sha_x1) * bytesPerPixel; | ||
559 | dst_start = private->physmem + scr_y1 * private->physlinebytes + | ||
560 | scr_x1 * bytesPerPixel; | ||
561 | |||
562 | private->blitFunc(src_start, | ||
563 | shadowRightDelta, | ||
564 | shadowDownDelta, | ||
565 | dst_start, | ||
566 | private->physlinebytes, | ||
567 | scr_x2 - scr_x1, | ||
568 | scr_y2 - scr_y1); | ||
569 | } | ||
570 | } | ||
571 | |||
572 | int WSCONS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) | ||
573 | { | ||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | /* | ||
578 | * Note: If we are terminated, this could be called in the middle of | ||
579 | * another SDL video routine -- notably UpdateRects. | ||
580 | */ | ||
581 | void WSCONS_VideoQuit(_THIS) | ||
582 | { | ||
583 | int mode = WSDISPLAYIO_MODE_EMUL; | ||
584 | |||
585 | if (private->shadowmem != NULL) { | ||
586 | SDL_free(private->shadowmem); | ||
587 | private->shadowmem = NULL; | ||
588 | } | ||
589 | private->fbstart = NULL; | ||
590 | if (this->screen != NULL) { | ||
591 | this->screen->pixels = NULL; | ||
592 | } | ||
593 | |||
594 | if (private->SDL_modelist[0] != NULL) { | ||
595 | SDL_free(private->SDL_modelist[0]); | ||
596 | private->SDL_modelist[0] = NULL; | ||
597 | } | ||
598 | |||
599 | if (ioctl(private->fd, WSDISPLAYIO_SMODE, &mode) == -1) { | ||
600 | WSCONS_ReportError("ioctl SMODE"); | ||
601 | } | ||
602 | |||
603 | WSCONS_ReleaseKeyboard(this); | ||
604 | |||
605 | if (private->fd != -1) { | ||
606 | close(private->fd); | ||
607 | private->fd = -1; | ||
608 | } | ||
609 | } | ||
diff --git a/apps/plugins/sdl/src/video/wscons/SDL_wsconsvideo.h b/apps/plugins/sdl/src/video/wscons/SDL_wsconsvideo.h new file mode 100644 index 0000000000..9d75c170dc --- /dev/null +++ b/apps/plugins/sdl/src/video/wscons/SDL_wsconsvideo.h | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _SDL_wsconsvideo_h | ||
25 | #define _SDL_wsconsvideo_h | ||
26 | |||
27 | #include <sys/time.h> | ||
28 | #include <termios.h> | ||
29 | #include <dev/wscons/wsconsio.h> | ||
30 | |||
31 | #include "SDL_mouse.h" | ||
32 | #include "SDL_mutex.h" | ||
33 | #include "../SDL_sysvideo.h" | ||
34 | |||
35 | void WSCONS_ReportError(char *fmt, ...); | ||
36 | |||
37 | /* Hidden "this" pointer for the video functions */ | ||
38 | #define _THIS SDL_VideoDevice *this | ||
39 | #define private (this->hidden) | ||
40 | |||
41 | /* Private display data */ | ||
42 | |||
43 | typedef void WSCONS_bitBlit(Uint8 *src_pos, | ||
44 | int srcRightDelta, // pixels, not bytes | ||
45 | int srcDownDelta, // pixels, not bytes | ||
46 | Uint8 *dst_pos, | ||
47 | int dst_linebytes, | ||
48 | int width, | ||
49 | int height); | ||
50 | |||
51 | struct SDL_PrivateVideoData { | ||
52 | int fd; /* file descriptor of open device */ | ||
53 | struct wsdisplay_fbinfo info; /* frame buffer characteristics */ | ||
54 | int physlinebytes; /* number of bytes per row */ | ||
55 | int redMask, greenMask, blueMask; | ||
56 | |||
57 | Uint8 *fbstart; /* These refer to the surface used, */ | ||
58 | int fblinebytes; /* physical frame buffer or shadow. */ | ||
59 | |||
60 | size_t fbmem_len; | ||
61 | Uint8 *physmem; | ||
62 | Uint8 *shadowmem; | ||
63 | int rotate; | ||
64 | int shadowFB; /* Tells whether a shadow is being used. */ | ||
65 | |||
66 | WSCONS_bitBlit *blitFunc; | ||
67 | |||
68 | SDL_Rect *SDL_modelist[2]; | ||
69 | |||
70 | unsigned int kbdType; | ||
71 | int did_save_tty; | ||
72 | struct termios saved_tty; | ||
73 | }; | ||
74 | |||
75 | |||
76 | #endif /* _SDL_wsconsvideo_h */ | ||