1 |
/* |
2 |
* PearPC |
3 |
* sysbeos.cc |
4 |
* |
5 |
* Copyright (C) 1999-2002 Stefan Weyergraf (stefan@weyergraf.de) |
6 |
* Copyright (C) 1999-2004 Sebastian Biallas (sb@biallas.net) |
7 |
* Copyright (C) 2004 Francois Revol (revol@free.fr) |
8 |
* |
9 |
* This program is free software; you can redistribute it and/or modify |
10 |
* it under the terms of the GNU General Public License version 2 as |
11 |
* published by the Free Software Foundation. |
12 |
* |
13 |
* This program is distributed in the hope that it will be useful, |
14 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 |
* GNU General Public License for more details. |
17 |
* |
18 |
* You should have received a copy of the GNU General Public License |
19 |
* along with this program; if not, write to the Free Software |
20 |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
21 |
*/ |
22 |
|
23 |
#include <csignal> |
24 |
#include <cstdlib> |
25 |
#include <unistd.h> |
26 |
#include <cstring> |
27 |
|
28 |
#include <AppDefs.h> |
29 |
#include <Application.h> |
30 |
#include <Bitmap.h> |
31 |
#include <Cursor.h> |
32 |
#include <GraphicsDefs.h> |
33 |
#include <InterfaceDefs.h> |
34 |
#include <List.h> |
35 |
#include <Locker.h> |
36 |
#include <Message.h> |
37 |
#include <Screen.h> |
38 |
#include <View.h> |
39 |
#include <Window.h> |
40 |
#include <WindowScreen.h> |
41 |
|
42 |
#include "system/display.h" |
43 |
#include "system/keyboard.h" |
44 |
#include "system/mouse.h" |
45 |
#include "system/types.h" |
46 |
#include "system/systhread.h" |
47 |
#include "system/sysexcept.h" |
48 |
#include "tools/data.h" |
49 |
#include "tools/snprintf.h" |
50 |
|
51 |
// for stopping the CPU |
52 |
#include "cpu/cpu.h" |
53 |
|
54 |
#include "sysbeos.h" |
55 |
|
56 |
//#define DPRINTF(a...) |
57 |
#define DPRINTF(a...) ht_printf(a) |
58 |
|
59 |
//XXX:DEL uint gDamageAreaFirstAddr, gDamageAreaLastAddr; |
60 |
|
61 |
/*XXX:DEL |
62 |
struct { |
63 |
uint64 r_mask; |
64 |
uint64 g_mask; |
65 |
uint64 b_mask; |
66 |
} PACKED gPosixRGBMask;*/ |
67 |
|
68 |
//extern "C" void __attribute__((regparm (3))) posix_vaccel_15_to_15(uint32 pixel, byte *input, byte *output); |
69 |
//extern "C" void __attribute__((regparm (3))) posix_vaccel_15_to_32(uint32 pixel, byte *input, byte *output); |
70 |
|
71 |
static uint8 beos_key_to_adb_key[] = { |
72 |
/* ESC F1-F12 PRTSCR SLOCK */ |
73 |
0x35, 0x7a,0x78,0x63,0x76,0x60,0x61,0x62,0x64,0x65,0x6d,0x67,0x6f, 0xff, 0x6b,0x71, |
74 |
/* ` 1-0 - = BSPACE INS HOME P_UP NLOCK / * - */ |
75 |
0x32,0x12,0x13,0x14,0x15,0x17,0x16,0x1a,0x1c,0x19,0x1d,0x1b,0x18, 0x33, 0x72,0x73,0x74, 0x47,0x4b,0x43,0x4e, |
76 |
/* TAB qwerty... \ DEL END P_DN 7 8 9 + */ |
77 |
0x30, 0x0c,0x0d,0x0e,0x0f,0x11,0x10,0x20,0x22,0x1f,0x23,0x21,0x1e, 0x2a, 0x75,0x77,0x79, 0x59,0x5b,0x5c,0x45, |
78 |
/* CLOCK ... ENTR 4 5 6 */ |
79 |
0x39,0x00,0x01,0x02,0x03,0x05,0x04,0x26,0x28,0x25,0x29,0x27, 0x24, 0x56,0x57,0x58,/*107*/ |
80 |
/* SHIFT ... SHIFT UP 1 2 3 ENTR */ |
81 |
0x38, 0x06,0x07,0x08,0x09,0x0b,0x2d,0x2e,0x2b,0x2f,0x2c, 0x38, 0x3e, 0x53,0x54,0x55,0x4c, |
82 |
/* CTRL /WIN/ ALT SPACE ALTGR /WIN MENU/ CTRL LEFT DOWN RIGHT 0 DEL */ |
83 |
0x36,/*0,*/ 0x37, 0x31, 0x3a, /*0, 0,*/ 0x36, 0x3b, 0x3d, 0x3c, 0x52, 0x41 |
84 |
|
85 |
|
86 |
}; |
87 |
|
88 |
|
89 |
|
90 |
SDWindow::SDWindow(BRect frame, const char *name) |
91 |
: BWindow(frame, name, B_TITLED_WINDOW, B_NOT_RESIZABLE|B_NOT_ZOOMABLE) |
92 |
{ |
93 |
} |
94 |
|
95 |
SDWindow::~SDWindow() |
96 |
{ |
97 |
} |
98 |
|
99 |
bool SDWindow::QuitRequested() |
100 |
{ |
101 |
ppc_cpu_stop(); |
102 |
/* |
103 |
SDView *view = dynamic_cast<SDView *>(FindView("framebuffer")); |
104 |
|
105 |
if (view) { |
106 |
BMessage *msg = new BMessage(B_QUIT_REQUESTED); |
107 |
view->QueueMessage(msg); |
108 |
} |
109 |
*/ |
110 |
return false; |
111 |
} |
112 |
|
113 |
void SDWindow::Show() |
114 |
{ |
115 |
BWindow::Show(); |
116 |
//gDisplay->setExposed(!IsMinimized() && !IsHidden()); |
117 |
//gDisplay->setExposed(true); |
118 |
} |
119 |
|
120 |
void SDWindow::Hide() |
121 |
{ |
122 |
BWindow::Hide(); |
123 |
//gDisplay->setExposed(!IsMinimized() && !IsHidden()); |
124 |
} |
125 |
|
126 |
void SDWindow::Minimize(bool minimize) |
127 |
{ |
128 |
BWindow::Minimize(minimize); |
129 |
gDisplay->setExposed(!minimize && !IsHidden()); |
130 |
} |
131 |
|
132 |
SDView::SDView(BeOSSystemDisplay *sd, BRect frame, const char *name) |
133 |
: BView(frame, name, B_FOLLOW_ALL_SIDES, B_PULSE_NEEDED|B_WILL_DRAW) |
134 |
{ |
135 |
fSystemDisplay = sd; |
136 |
sd->fbBitmap; |
137 |
fMsgList.MakeEmpty(); |
138 |
//SetViewColor(0,255,0); |
139 |
SetViewColor(B_TRANSPARENT_32_BIT); |
140 |
fMsgSem = create_sem(1, "PearPC MessageList sem"); |
141 |
// here we don't use the View's looper to lock the msg list, |
142 |
// so the window thread and main thread aren't interleaved |
143 |
// just because they are playing with the msg list. |
144 |
// much better on my dual :)) |
145 |
fMsgListLock = new BLocker("PearPC MessageList lock", true); |
146 |
} |
147 |
|
148 |
SDView::~SDView() |
149 |
{ |
150 |
delete_sem(fMsgSem); |
151 |
delete fMsgListLock; |
152 |
} |
153 |
|
154 |
void SDView::MessageReceived(BMessage *msg) |
155 |
{ |
156 |
BMessage *event; |
157 |
switch (msg->what) { |
158 |
case B_UNMAPPED_KEY_DOWN: |
159 |
case B_UNMAPPED_KEY_UP: |
160 |
event = Window()->DetachCurrentMessage(); |
161 |
QueueMessage(event); |
162 |
return; |
163 |
} |
164 |
BView::MessageReceived(msg); |
165 |
} |
166 |
|
167 |
void SDView::Draw(BRect updateRect) |
168 |
{ |
169 |
//fSystemDisplay->convertDisplayClientToServer(); |
170 |
#ifdef BMP_MENU |
171 |
BRect r(updateRect); |
172 |
r.bottom = MIN(fSystemDisplay->mMenuHeight-1, r.bottom); |
173 |
if (fSystemDisplay->fMenuBitmap && (r.top <= fSystemDisplay->mMenuHeight)) |
174 |
DrawBitmap(fSystemDisplay->fMenuBitmap, r, r); |
175 |
BRect src(updateRect); |
176 |
src.OffsetBySelf(0,-fSystemDisplay->mMenuHeight); |
177 |
//src.top = MAX(0, src.top); |
178 |
DrawBitmap(fSystemDisplay->fbBitmap, src, updateRect); |
179 |
#else |
180 |
DrawBitmap(fSystemDisplay->fbBitmap, updateRect, updateRect); |
181 |
#endif |
182 |
if (fSystemDisplay->mHWCursorVisible) { |
183 |
//XPutImage(gXDisplay, gXWindow, gGC, gMouseXImage, 0, 0, |
184 |
// mHWCursorX, mHWCursorY, 2, 2); |
185 |
} |
186 |
} |
187 |
|
188 |
void SDView::MouseDown(BPoint where) |
189 |
{ |
190 |
BMessage *event = Window()->CurrentMessage(); |
191 |
SystemEvent ev; |
192 |
int32 buttons; |
193 |
ev.type = sysevMouse; |
194 |
//if (!mMouseEnabled) break; |
195 |
if (event->FindInt32("buttons", (int32 *)&buttons) < B_OK) |
196 |
buttons = 0; |
197 |
ev.mouse.type = sme_buttonPressed; |
198 |
ev.mouse.x = gDisplay->mCurMouseX; |
199 |
ev.mouse.y = gDisplay->mCurMouseY; |
200 |
ev.mouse.relx = 0; |
201 |
ev.mouse.rely = 0; |
202 |
ev.mouse.button1 = (buttons & B_PRIMARY_MOUSE_BUTTON) != 0; |
203 |
ev.mouse.button2 = (buttons & B_SECONDARY_MOUSE_BUTTON) != 0; |
204 |
ev.mouse.button3 = (buttons & B_TERTIARY_MOUSE_BUTTON) != 0; |
205 |
|
206 |
gMouse->handleEvent(ev); |
207 |
} |
208 |
|
209 |
void SDView::MouseUp(BPoint where) |
210 |
{ |
211 |
BMessage *event = Window()->CurrentMessage(); |
212 |
SystemEvent ev; |
213 |
int32 buttons; |
214 |
ev.type = sysevMouse; |
215 |
//if (!mMouseEnabled) break; |
216 |
if (event->FindInt32("buttons", (int32 *)&buttons) < B_OK) |
217 |
buttons = 0; |
218 |
ev.mouse.type = sme_buttonReleased; |
219 |
ev.mouse.x = gDisplay->mCurMouseX; |
220 |
ev.mouse.y = gDisplay->mCurMouseY; |
221 |
ev.mouse.relx = 0; |
222 |
ev.mouse.rely = 0; |
223 |
ev.mouse.button1 = (buttons & B_PRIMARY_MOUSE_BUTTON) != 0; |
224 |
ev.mouse.button2 = (buttons & B_SECONDARY_MOUSE_BUTTON) != 0; |
225 |
ev.mouse.button3 = (buttons & B_TERTIARY_MOUSE_BUTTON) != 0; |
226 |
|
227 |
gMouse->handleEvent(ev); |
228 |
} |
229 |
|
230 |
void SDView::MouseMoved(BPoint where, uint32 code, const BMessage *a_message) |
231 |
{ |
232 |
BMessage *event = Window()->CurrentMessage(); |
233 |
SystemEvent ev; |
234 |
int32 buttons; |
235 |
if (code == B_OUTSIDE_VIEW) |
236 |
return; |
237 |
if (event->FindInt32("buttons", (int32 *)&buttons) < B_OK) |
238 |
buttons = 0; |
239 |
gDisplay->mCurMouseX = ev.mouse.x = (int)where.x; |
240 |
gDisplay->mCurMouseY = ev.mouse.y = (int)where.y; |
241 |
if (gDisplay->mCurMouseX == gDisplay->mHomeMouseX && gDisplay->mCurMouseY == gDisplay->mHomeMouseY) return; |
242 |
if (gDisplay->mCurMouseX == -1) return; |
243 |
ev.type = sysevMouse; |
244 |
ev.mouse.type = sme_motionNotify; |
245 |
ev.mouse.button1 = (buttons & B_PRIMARY_MOUSE_BUTTON) != 0; |
246 |
ev.mouse.button2 = (buttons & B_SECONDARY_MOUSE_BUTTON) != 0; |
247 |
ev.mouse.button3 = (buttons & B_TERTIARY_MOUSE_BUTTON) != 0; |
248 |
ev.mouse.dbutton = 0; |
249 |
ev.mouse.relx = gDisplay->mCurMouseX - gDisplay->mHomeMouseX; |
250 |
ev.mouse.rely = gDisplay->mCurMouseY - gDisplay->mHomeMouseY; |
251 |
if (gDisplay->isMouseGrabbed()) { |
252 |
BPoint p(gDisplay->mHomeMouseX, gDisplay->mHomeMouseY); |
253 |
//printf("nukemouse %f %f\n", p.x, p.y); |
254 |
ConvertToScreen(&p); |
255 |
//printf("nukemouses %f %f\n", p.x, p.y); |
256 |
set_mouse_position((int32)p.x, (int32)p.y); |
257 |
} |
258 |
if (code == B_EXITED_VIEW) { |
259 |
if (gDisplay->isMouseGrabbed()) gDisplay->setMouseGrab(false); |
260 |
} |
261 |
gMouse->handleEvent(ev); |
262 |
} |
263 |
|
264 |
void SDView::KeyDown(const char *bytes, int32 numBytes) |
265 |
{ |
266 |
BMessage *event = Window()->CurrentMessage(); |
267 |
char buffer[4]; |
268 |
uint32 modifiers; |
269 |
int32 key; |
270 |
int32 raw_char; |
271 |
SystemEvent ev; |
272 |
if (event->FindInt32("key", &key) < B_OK) |
273 |
key = 0; |
274 |
if (event->FindInt32("raw_char", &raw_char) < B_OK) |
275 |
raw_char = 0; |
276 |
if (!key || (key > 255)) return; |
277 |
ev.key.keycode = beos_key_to_adb_key[key-1]; |
278 |
DPRINTF("keys[%d-1]=%d, 0x%x\n", key, beos_key_to_adb_key[key-1], beos_key_to_adb_key[key-1]); |
279 |
if (ev.key.keycode == KEY_F12) return; |
280 |
if ((ev.key.keycode & 0xff) == 0xff) return; |
281 |
ev.type = sysevKey; |
282 |
ev.key.pressed = true; |
283 |
ev.key.chr = (char)raw_char; |
284 |
gKeyboard->handleEvent(ev); |
285 |
} |
286 |
|
287 |
void SDView::KeyUp(const char *bytes, int32 numBytes) |
288 |
{ |
289 |
BMessage *event = Window()->CurrentMessage(); |
290 |
char buffer[4]; |
291 |
uint32 modifiers; |
292 |
int32 key; |
293 |
int32 raw_char; |
294 |
SystemEvent ev; |
295 |
if (event->FindInt32("key", &key) < B_OK) |
296 |
key = 0; |
297 |
if (event->FindInt32("raw_char", &raw_char) < B_OK) |
298 |
raw_char = 0; |
299 |
if (!key || (key > 255)) return; |
300 |
ev.key.keycode = beos_key_to_adb_key[key-1]; |
301 |
DPRINTF("keys[%d-1]=%d, 0x%x\n", key, beos_key_to_adb_key[key-1], beos_key_to_adb_key[key-1]); |
302 |
if (ev.key.keycode == KEY_F12) return; |
303 |
if ((ev.key.keycode & 0xff) == 0xff) return; |
304 |
ev.type = sysevKey; |
305 |
ev.key.pressed = false; |
306 |
ev.key.chr = (char)raw_char; |
307 |
gKeyboard->handleEvent(ev); |
308 |
} |
309 |
|
310 |
void SDView::Pulse() |
311 |
{ |
312 |
BWindow *w = Window(); |
313 |
if (w && !w->IsHidden() && !w->IsMinimized()) |
314 |
fSystemDisplay->displayShow(); |
315 |
//Invalidate(Bounds()); /* cause a redraw */ |
316 |
} |
317 |
|
318 |
void SDView::QueueMessage(BMessage *msg) |
319 |
{ |
320 |
fMsgListLock->Lock(); /* BList not threadsafe */ |
321 |
fMsgList.AddItem(msg, fMsgList.CountItems()); |
322 |
fMsgListLock->Unlock(); |
323 |
release_sem(fMsgSem); |
324 |
} |
325 |
|
326 |
BMessage *SDView::UnqueueMessage(bool sync) |
327 |
{ |
328 |
BMessage *msg; |
329 |
acquire_sem_etc(fMsgSem, 1, sync?0:B_RELATIVE_TIMEOUT, 0LL); |
330 |
//LockLooper(); |
331 |
fMsgListLock->Lock(); /* BList not threadsafe */ |
332 |
msg = (BMessage *)fMsgList.RemoveItem(0L); |
333 |
//UnlockLooper(); |
334 |
fMsgListLock->Unlock(); |
335 |
/* if (msg) |
336 |
msg->PrintToStream();*/ |
337 |
return msg; |
338 |
} |
339 |
|
340 |
extern SystemDisplay *allocSystemDisplay(const char *title, const DisplayCharacteristics &chr, int redraw_ms); |
341 |
extern SystemMouse *allocSystemMouse(); |
342 |
extern SystemKeyboard *allocSystemKeyboard(); |
343 |
|
344 |
|
345 |
void initUI(const char *title, const DisplayCharacteristics &aCharacteristics, int redraw_ms, KeyboardCharacteristics const &keyConfig, bool fullscreen) |
346 |
{ |
347 |
gDisplay = allocSystemDisplay(title, aCharacteristics, redraw_ms); |
348 |
gMouse = allocSystemMouse(); |
349 |
gKeyboard = allocSystemKeyboard(); |
350 |
if(!gKeyboard->setKeyConfig(keyConfig)) { |
351 |
ht_printf("no keyConfig, or is empty"); |
352 |
exit(1); |
353 |
} |
354 |
gDisplay->updateTitle(); |
355 |
} |
356 |
|
357 |
void doneUI() |
358 |
{ |
359 |
delete gDisplay; |
360 |
delete gKeyboard; |
361 |
delete gMouse; |
362 |
} |