AcessNative - Mouse implimented, woot!
[tpg/acess2.git] / AcessNative / acesskernel_src / ui_sdl.c
1 /*
2  * Acess2 Native Kernel
3  * 
4  * SDL User Interface
5  */
6 #include <SDL/SDL.h>
7 #define const
8 #include "ui.h"
9 #undef const
10 #include <api_drv_keyboard.h>
11
12 // === IMPORTS ===
13 extern void     AcessNative_Exit(void);
14
15 // === PROTOTYPES ===
16  int    UI_Initialise(int MaxWidth, int MaxHeight);
17 void    UI_BlitBitmap(int DstX, int DstY, int SrcW, int SrcH, Uint32 *Bitmap);
18 void    UI_BlitFramebuffer(int DstX, int DstY, int SrcX, int SrcY, int W, int H);
19 void    UI_FillBitmap(int X, int Y, int W, int H, Uint32 Value);
20 void    UI_Redraw(void);
21
22 // === GLOBALS ===
23 SDL_Surface     *gScreen;
24 SDL_Thread      *gInputThread;
25  int    giUI_Width = 0;
26  int    giUI_Height = 0;
27  int    giUI_Pitch = 0;
28 tUI_KeybardCallback     gUI_KeyboardCallback;
29 Uint32  gUI_Keymap[2][SDLK_LAST];       // Upper/Lower case
30
31 // === FUNCTIONS ===
32 int UI_Initialise(int MaxWidth, int MaxHeight)
33 {       
34         // Changed when the video mode is set
35         giUI_Width = MaxWidth;
36         giUI_Height = MaxHeight;
37         
38         // Set up video
39         SDL_Init(SDL_INIT_VIDEO);
40         printf("UI attempting %ix%i %ibpp\n", giUI_Width, giUI_Height, 32);
41         gScreen = SDL_SetVideoMode(giUI_Width, giUI_Height, 32, SDL_DOUBLEBUF);
42         if( !gScreen ) {
43                 fprintf(stderr, "Couldn't set %ix%i video mode: %s\n", giUI_Width, giUI_Height, SDL_GetError());
44                 SDL_Quit();
45                 exit(2);
46         }
47         SDL_WM_SetCaption("Acess2", "Acess2");
48         
49         giUI_Width = gScreen->w;
50         giUI_Height = gScreen->h;
51         giUI_Pitch = gScreen->pitch;
52
53         printf("UI window %ix%i %i bytes per line\n", giUI_Width, giUI_Height, giUI_Pitch);
54         
55         SDL_EnableUNICODE(1);
56
57         return 0;
58 }
59
60 Uint32 UI_GetAcessKeyFromSDL(SDLKey Sym)
61 {
62         Uint8   *keystate = SDL_GetKeyState(NULL);
63          int    shiftState = 0;
64         Uint32  ret = 0;
65         
66         if( keystate[SDLK_RSHIFT] || keystate[SDLK_LSHIFT] )
67                 shiftState = 1;
68         
69         // Fast return
70         if( gUI_Keymap[shiftState][Sym] )
71                 return gUI_Keymap[shiftState][Sym];
72
73         switch(Sym)
74         {
75         case SDLK_a ... SDLK_z:
76                 ret = Sym - SDLK_a + KEYSYM_a;
77                 break;
78         case SDLK_0 ... SDLK_9:
79                 ret = Sym - SDLK_0 + KEYSYM_0;
80                 break;
81         case SDLK_CAPSLOCK:     ret = KEYSYM_CAPS;      break;
82         case SDLK_TAB:  ret = KEYSYM_TAB;       break;
83         case SDLK_UP:   ret = KEYSYM_UPARROW;   break;
84         case SDLK_DOWN: ret = KEYSYM_DOWNARROW; break;
85         case SDLK_LEFT: ret = KEYSYM_LEFTARROW; break;
86         case SDLK_RIGHT:ret = KEYSYM_RIGHTARROW;break;
87         case SDLK_F1:   ret = KEYSYM_F1;        break;
88         case SDLK_F2:   ret = KEYSYM_F2;        break;
89         case SDLK_F3:   ret = KEYSYM_F3;        break;
90         case SDLK_F4:   ret = KEYSYM_F4;        break;
91         case SDLK_F5:   ret = KEYSYM_F5;        break;
92         case SDLK_F6:   ret = KEYSYM_F6;        break;
93         case SDLK_F7:   ret = KEYSYM_F7;        break;
94         case SDLK_F8:   ret = KEYSYM_F8;        break;
95         case SDLK_F9:   ret = KEYSYM_F9;        break;
96         case SDLK_F10:  ret = KEYSYM_F10;       break;
97         case SDLK_F11:  ret = KEYSYM_F11;       break;
98         case SDLK_F12:  ret = KEYSYM_F12;       break;
99         case SDLK_RETURN:       ret = KEYSYM_RETURN;    break;
100         case SDLK_LALT:         ret = KEYSYM_LEFTALT;   break;
101         case SDLK_LCTRL:        ret = KEYSYM_LEFTCTRL;  break;
102         case SDLK_LSHIFT:       ret = KEYSYM_LEFTSHIFT; break;
103         case SDLK_LSUPER:       ret = KEYSYM_LEFTGUI;   break;
104         case SDLK_RALT:         ret = KEYSYM_RIGHTALT;  break;
105         case SDLK_RCTRL:        ret = KEYSYM_RIGHTCTRL; break;
106         case SDLK_RSHIFT:       ret = KEYSYM_RIGHTSHIFT;        break;
107         case SDLK_RSUPER:       ret = KEYSYM_RIGHTGUI;  break;
108         default:
109                 printf("Unhandled key code %i\n", Sym);
110                 break;
111         }
112         
113         gUI_Keymap[shiftState][Sym] = ret;
114         return ret;
115 }
116
117 Uint32 UI_GetButtonBits(Uint8 sdlstate)
118 {
119         Uint32  rv = 0;
120         rv |= sdlstate & SDL_BUTTON(SDL_BUTTON_LEFT)    ? (1 << 0) : 0;
121         rv |= sdlstate & SDL_BUTTON(SDL_BUTTON_RIGHT)   ? (1 << 1) : 0;
122         rv |= sdlstate & SDL_BUTTON(SDL_BUTTON_MIDDLE)  ? (1 << 2) : 0;
123         rv |= sdlstate & SDL_BUTTON(SDL_BUTTON_X1)      ? (1 << 3) : 0;
124         rv |= sdlstate & SDL_BUTTON(SDL_BUTTON_X2)      ? (1 << 4) : 0;
125         return rv;
126 }
127
128 void UI_MainLoop(void)
129 {
130         SDL_Event       event;
131         Uint32  acess_sym;
132
133         for( ;; )
134         {
135                 while(SDL_PollEvent(&event))
136                 {
137                         switch(event.type)
138                         {
139                         case SDL_QUIT:
140                                 AcessNative_Exit();
141                                 return ;
142                                 
143                         case SDL_KEYDOWN:
144                                 acess_sym = UI_GetAcessKeyFromSDL(event.key.keysym.sym);
145                                 // Enter key on acess returns \n, but SDL returns \r
146                                 if(event.key.keysym.sym == SDLK_RETURN)
147                                         event.key.keysym.unicode = '\n';                                
148
149                                 if( gUI_KeyboardCallback ) {
150                                         gUI_KeyboardCallback(KEY_ACTION_RAWSYM|acess_sym);
151                                         gUI_KeyboardCallback(KEY_ACTION_PRESS|event.key.keysym.unicode);
152                                 }
153                                 break;
154                         
155                         case SDL_KEYUP:
156                                 acess_sym = UI_GetAcessKeyFromSDL(event.key.keysym.sym);
157                                 
158                                 if( gUI_KeyboardCallback ) {
159                                         gUI_KeyboardCallback(KEY_ACTION_RAWSYM|acess_sym);
160                                         gUI_KeyboardCallback(KEY_ACTION_RELEASE|0);
161                                 }
162                                 break;
163
164                         case SDL_USEREVENT:
165                                 SDL_UpdateRect(gScreen, 0, 0, giUI_Width, giUI_Height);
166                                 SDL_Flip(gScreen);
167                                 break;
168                         
169                         case SDL_MOUSEMOTION: {
170                                 int abs[] = {event.motion.x, event.motion.y};
171                                 int delta[] = {event.motion.xrel, event.motion.yrel};
172                                 Mouse_HandleEvent(UI_GetButtonBits(SDL_GetMouseState(NULL, NULL)), delta, abs);
173                                 break; }
174                         case SDL_MOUSEBUTTONUP:
175                         case SDL_MOUSEBUTTONDOWN: {
176                                 int abs[] = {event.button.x, event.button.y};
177                                 Mouse_HandleEvent(UI_GetButtonBits(SDL_GetMouseState(NULL, NULL)), NULL, abs);
178                                 break; }
179         
180                         default:
181                                 break;
182                         }
183                 }
184         }
185 }
186
187 void UI_BlitBitmap(int DstX, int DstY, int SrcW, int SrcH, Uint32 *Bitmap)
188 {
189         SDL_Surface     *tmp;
190         SDL_Rect        dstRect;
191         
192 //      printf("UI_BlitBitmap: Blit to (%i,%i) from %p (%ix%i 32bpp bitmap)\n",
193 //              DstX, DstY, Bitmap, SrcW, SrcH);
194         
195         tmp = SDL_CreateRGBSurfaceFrom(Bitmap, SrcW, SrcH, 32, SrcW*4,
196                 0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000);
197         SDL_SetAlpha(tmp, 0, SDL_ALPHA_OPAQUE);
198         
199         dstRect.x = DstX;       dstRect.y = DstY;
200         dstRect.w = -1; dstRect.h = -1;
201         
202         SDL_BlitSurface(tmp, NULL, gScreen, &dstRect);
203         //SDL_BlitSurface(tmp, NULL, gScreen, NULL);
204         
205         SDL_FreeSurface(tmp);
206 //      SDL_Flip(gScreen);
207 }
208
209 void UI_BlitFramebuffer(int DstX, int DstY, int SrcX, int SrcY, int W, int H)
210 {
211         SDL_Rect        srcRect;
212         SDL_Rect        dstRect;
213         
214         srcRect.x = SrcX;       srcRect.y = SrcY;
215         srcRect.w = W;  srcRect.h = H;
216         dstRect.x = DstX;       dstRect.y = DstY;
217         
218         SDL_BlitSurface(gScreen, &srcRect, gScreen, &dstRect); 
219 }
220
221 void UI_FillBitmap(int X, int Y, int W, int H, Uint32 Value)
222 {
223         SDL_Rect        dstRect;
224         
225         dstRect.x = X;  dstRect.y = Y;
226         dstRect.w = W;  dstRect.h = H;
227         
228 //      printf("UI_FillBitmap: gScreen = %p\n", gScreen);
229         SDL_FillRect(gScreen, &dstRect, Value);
230 }
231
232 void UI_Redraw(void)
233 {
234         // TODO: Keep track of changed rectangle
235 //      SDL_UpdateRect(gScreen, 0, 0, giUI_Width, giUI_Height);
236         SDL_Event       e;
237
238         e.type = SDL_USEREVENT;
239         e.user.code = 0;
240         e.user.data1 = 0;
241         e.user.data2 = 0;       
242
243         SDL_PushEvent( &e );
244 }

UCC git Repository :: git.ucc.asn.au