ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/BeOS/video_beos.cpp
Revision: 1.1.1.1 (vendor branch)
Committed: 2002-02-04T16:58:13Z (22 years, 9 months ago) by cebix
Branch: cebix
CVS Tags: start
Changes since 1.1: +0 -0 lines
Log Message:
Imported sources

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * video_beos.cpp - Video/graphics emulation, BeOS specific things
3     *
4     * SheepShaver (C) 1997-2002 Marc Hellwig and Christian Bauer
5     *
6     * This program is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19     */
20    
21     #include "sysdeps.h"
22    
23     #include "video.h"
24     #include "video_defs.h"
25     #include "main.h"
26     #include "adb.h"
27     #include "prefs.h"
28     #include "user_strings.h"
29     #include "about_window.h"
30     #include "version.h"
31    
32     #define DEBUG 0
33     #include "debug.h"
34    
35    
36     // Global variables
37     static sem_id video_lock = -1; // Protection during mode changes
38     static sem_id mac_os_lock = -1; // This is used to stop the MacOS thread when the SheepShaver workspace is switched out
39    
40     // Prototypes
41     static filter_result filter_func(BMessage *msg, BHandler **target, BMessageFilter *filter);
42    
43     // From sys_beos.cpp
44     extern void SysCreateVolumeMenu(BMenu *menu, uint32 msg);
45     extern void SysMountVolume(const char *name);
46    
47    
48     #include "video_window.h"
49     #include "video_screen.h"
50    
51    
52     /*
53     * Display manager thread (for opening and closing windows and screens;
54     * this is not safe under R4 when running on the MacOS stack in kernel
55     * space)
56     */
57    
58     // Message constants
59     const uint32 MSG_OPEN_WINDOW = 'owin';
60     const uint32 MSG_CLOSE_WINDOW = 'cwin';
61     const uint32 MSG_OPEN_SCREEN = 'oscr';
62     const uint32 MSG_CLOSE_SCREEN = 'cscr';
63     const uint32 MSG_QUIT_DISPLAY_MANAGER = 'quit';
64    
65     static thread_id dm_thread = -1;
66     static sem_id dm_done_sem = -1;
67    
68     static status_t display_manager(void *arg)
69     {
70     for (;;) {
71    
72     // Receive message
73     thread_id sender;
74     uint32 code = receive_data(&sender, NULL, 0);
75     D(bug("Display manager received %08lx\n", code));
76     switch (code) {
77     case MSG_QUIT_DISPLAY_MANAGER:
78     return 0;
79    
80     case MSG_OPEN_WINDOW:
81     D(bug("Opening window\n"));
82     the_window = new MacWindow(BRect(0, 0, VModes[cur_mode].viXsize-1, VModes[cur_mode].viYsize-1));
83     D(bug("Opened\n"));
84     break;
85    
86     case MSG_CLOSE_WINDOW:
87     if (the_window != NULL) {
88     D(bug("Posting quit to window\n"));
89     the_window->PostMessage(B_QUIT_REQUESTED);
90     D(bug("Posted, waiting\n"));
91     while (the_window)
92     snooze(200000);
93     D(bug("Window closed\n"));
94     }
95     break;
96    
97     case MSG_OPEN_SCREEN: {
98     D(bug("Opening screen\n"));
99     long scr_mode = 0;
100     switch (VModes[cur_mode].viAppleMode) {
101     case APPLE_8_BIT:
102     switch (VModes[cur_mode].viAppleID) {
103     case APPLE_640x480:
104     scr_mode = B_8_BIT_640x480;
105     break;
106     case APPLE_800x600:
107     scr_mode = B_8_BIT_800x600;
108     break;
109     case APPLE_1024x768:
110     scr_mode = B_8_BIT_1024x768;
111     break;
112     case APPLE_1152x900:
113     scr_mode = B_8_BIT_1152x900;
114     break;
115     case APPLE_1280x1024:
116     scr_mode = B_8_BIT_1280x1024;
117     break;
118     case APPLE_1600x1200:
119     scr_mode = B_8_BIT_1600x1200;
120     break;
121     }
122     break;
123     case APPLE_16_BIT:
124     switch (VModes[cur_mode].viAppleID) {
125     case APPLE_640x480:
126     scr_mode = B_15_BIT_640x480;
127     break;
128     case APPLE_800x600:
129     scr_mode = B_15_BIT_800x600;
130     break;
131     case APPLE_1024x768:
132     scr_mode = B_15_BIT_1024x768;
133     break;
134     case APPLE_1152x900:
135     scr_mode = B_15_BIT_1152x900;
136     break;
137     case APPLE_1280x1024:
138     scr_mode = B_15_BIT_1280x1024;
139     break;
140     case APPLE_1600x1200:
141     scr_mode = B_15_BIT_1600x1200;
142     break;
143     }
144     break;
145     case APPLE_32_BIT:
146     switch (VModes[cur_mode].viAppleID) {
147     case APPLE_640x480:
148     scr_mode = B_32_BIT_640x480;
149     break;
150     case APPLE_800x600:
151     scr_mode = B_32_BIT_800x600;
152     break;
153     case APPLE_1024x768:
154     scr_mode = B_32_BIT_1024x768;
155     break;
156     case APPLE_1152x900:
157     scr_mode = B_32_BIT_1152x900;
158     break;
159     case APPLE_1280x1024:
160     scr_mode = B_32_BIT_1280x1024;
161     break;
162     case APPLE_1600x1200:
163     scr_mode = B_32_BIT_1600x1200;
164     break;
165     }
166     break;
167     }
168     the_screen = new MacScreen(GetString(STR_WINDOW_TITLE), scr_mode);
169     D(bug("Opened, error %08lx\n", screen_error));
170     if (screen_error != B_NO_ERROR) {
171     D(bug("Error, posting quit to screen\n"));
172     the_screen->PostMessage(B_QUIT_REQUESTED);
173     D(bug("Posted, waiting\n"));
174     while (the_screen)
175     snooze(200000);
176     D(bug("Screen closed\n"));
177     break;
178     }
179    
180     // Wait for video mem access
181     D(bug("Showing screen\n"));
182     the_screen->Show();
183     D(bug("Shown, waiting for frame buffer access\n"));
184     while (!drawing_enable)
185     snooze(200000);
186     D(bug("Access granted\n"));
187     break;
188     }
189    
190     case MSG_CLOSE_SCREEN:
191     if (the_screen != NULL) {
192     D(bug("Posting quit to screen\n"));
193     the_screen->PostMessage(B_QUIT_REQUESTED);
194     D(bug("Posted, waiting\n"));
195     while (the_screen)
196     snooze(200000);
197     D(bug("Screen closed\n"));
198     }
199     break;
200     }
201    
202     // Acknowledge
203     release_sem(dm_done_sem);
204     }
205     }
206    
207    
208     /*
209     * Open display (window or screen)
210     */
211    
212     static void open_display(void)
213     {
214     D(bug("entering open_display()\n"));
215     display_type = VModes[cur_mode].viType;
216     if (display_type == DIS_SCREEN) {
217     while (send_data(dm_thread, MSG_OPEN_SCREEN, NULL, 0) == B_INTERRUPTED) ;
218     while (acquire_sem(dm_done_sem) == B_INTERRUPTED) ;
219     } else if (display_type == DIS_WINDOW) {
220     while (send_data(dm_thread, MSG_OPEN_WINDOW, NULL, 0) == B_INTERRUPTED) ;
221     while (acquire_sem(dm_done_sem) == B_INTERRUPTED) ;
222     }
223     D(bug("exiting open_display()\n"));
224     }
225    
226    
227     /*
228     * Close display
229     */
230    
231     static void close_display(void)
232     {
233     D(bug("entering close_display()\n"));
234     if (display_type == DIS_SCREEN) {
235     while (send_data(dm_thread, MSG_CLOSE_SCREEN, NULL, 0) == B_INTERRUPTED) ;
236     while (acquire_sem(dm_done_sem) == B_INTERRUPTED) ;
237     } else if (display_type == DIS_WINDOW) {
238     while (send_data(dm_thread, MSG_CLOSE_WINDOW, NULL, 0) == B_INTERRUPTED) ;
239     while (acquire_sem(dm_done_sem) == B_INTERRUPTED) ;
240     }
241     D(bug("exiting close_display()\n"));
242     }
243    
244    
245     /*
246     * Initialization
247     */
248    
249     static void add_mode(VideoInfo *&p, uint32 allow, uint32 test, long apple_mode, long apple_id, int type)
250     {
251     if (allow & test) {
252     p->viType = type;
253     switch (apple_id) {
254     case APPLE_W_640x480:
255     case APPLE_640x480:
256     p->viXsize = 640;
257     p->viYsize = 480;
258     break;
259     case APPLE_W_800x600:
260     case APPLE_800x600:
261     p->viXsize = 800;
262     p->viYsize = 600;
263     break;
264     case APPLE_1024x768:
265     p->viXsize = 1024;
266     p->viYsize = 768;
267     break;
268     case APPLE_1152x900:
269     p->viXsize = 1152;
270     p->viYsize = 900;
271     break;
272     case APPLE_1280x1024:
273     p->viXsize = 1280;
274     p->viYsize = 1024;
275     break;
276     case APPLE_1600x1200:
277     p->viXsize = 1600;
278     p->viYsize = 1200;
279     break;
280     }
281     switch (apple_mode) {
282     case APPLE_8_BIT:
283     p->viRowBytes = p->viXsize;
284     break;
285     case APPLE_16_BIT:
286     p->viRowBytes = p->viXsize * 2;
287     break;
288     case APPLE_32_BIT:
289     p->viRowBytes = p->viXsize * 4;
290     break;
291     }
292     p->viAppleMode = apple_mode;
293     p->viAppleID = apple_id;
294     p++;
295     }
296     }
297    
298     bool VideoInit(void)
299     {
300     // Init variables, create semaphores
301     private_data = NULL;
302     cur_mode = 0; // Window 640x480
303     video_lock = create_sem(1, "Video Lock");
304     mac_os_lock = create_sem(0, "MacOS Frame Buffer Lock");
305     dm_done_sem = create_sem(0, "Display Manager Done");
306    
307     // Construct video mode table
308     VideoInfo *p = VModes;
309     uint32 window_modes = PrefsFindInt32("windowmodes");
310     uint32 screen_modes = PrefsFindInt32("screenmodes");
311     if (window_modes == 0 && screen_modes == 0)
312     window_modes |= B_8_BIT_640x480 | B_8_BIT_800x600; // Allow at least 640x480 and 800x600 window modes
313     add_mode(p, window_modes, B_8_BIT_640x480, APPLE_8_BIT, APPLE_W_640x480, DIS_WINDOW);
314     add_mode(p, window_modes, B_8_BIT_800x600, APPLE_8_BIT, APPLE_W_800x600, DIS_WINDOW);
315     add_mode(p, window_modes, B_15_BIT_640x480, APPLE_16_BIT, APPLE_W_640x480, DIS_WINDOW);
316     add_mode(p, window_modes, B_15_BIT_800x600, APPLE_16_BIT, APPLE_W_800x600, DIS_WINDOW);
317     add_mode(p, window_modes, B_32_BIT_640x480, APPLE_32_BIT, APPLE_W_640x480, DIS_WINDOW);
318     add_mode(p, window_modes, B_32_BIT_800x600, APPLE_32_BIT, APPLE_W_800x600, DIS_WINDOW);
319     add_mode(p, screen_modes, B_8_BIT_640x480, APPLE_8_BIT, APPLE_640x480, DIS_SCREEN);
320     add_mode(p, screen_modes, B_8_BIT_800x600, APPLE_8_BIT, APPLE_800x600, DIS_SCREEN);
321     add_mode(p, screen_modes, B_8_BIT_1024x768, APPLE_8_BIT, APPLE_1024x768, DIS_SCREEN);
322     add_mode(p, screen_modes, B_8_BIT_1152x900, APPLE_8_BIT, APPLE_1152x900, DIS_SCREEN);
323     add_mode(p, screen_modes, B_8_BIT_1280x1024, APPLE_8_BIT, APPLE_1280x1024, DIS_SCREEN);
324     add_mode(p, screen_modes, B_8_BIT_1600x1200, APPLE_8_BIT, APPLE_1600x1200, DIS_SCREEN);
325     add_mode(p, screen_modes, B_15_BIT_640x480, APPLE_16_BIT, APPLE_640x480, DIS_SCREEN);
326     add_mode(p, screen_modes, B_15_BIT_800x600, APPLE_16_BIT, APPLE_800x600, DIS_SCREEN);
327     add_mode(p, screen_modes, B_15_BIT_1024x768, APPLE_16_BIT, APPLE_1024x768, DIS_SCREEN);
328     add_mode(p, screen_modes, B_15_BIT_1152x900, APPLE_16_BIT, APPLE_1152x900, DIS_SCREEN);
329     add_mode(p, screen_modes, B_15_BIT_1280x1024, APPLE_16_BIT, APPLE_1280x1024, DIS_SCREEN);
330     add_mode(p, screen_modes, B_15_BIT_1600x1200, APPLE_16_BIT, APPLE_1600x1200, DIS_SCREEN);
331     add_mode(p, screen_modes, B_32_BIT_640x480, APPLE_32_BIT, APPLE_640x480, DIS_SCREEN);
332     add_mode(p, screen_modes, B_32_BIT_800x600, APPLE_32_BIT, APPLE_800x600, DIS_SCREEN);
333     add_mode(p, screen_modes, B_32_BIT_1024x768, APPLE_32_BIT, APPLE_1024x768, DIS_SCREEN);
334     add_mode(p, screen_modes, B_32_BIT_1152x900, APPLE_32_BIT, APPLE_1152x900, DIS_SCREEN);
335     add_mode(p, screen_modes, B_32_BIT_1280x1024, APPLE_32_BIT, APPLE_1280x1024, DIS_SCREEN);
336     add_mode(p, screen_modes, B_32_BIT_1600x1200, APPLE_32_BIT, APPLE_1600x1200, DIS_SCREEN);
337     p->viType = DIS_INVALID; // End marker
338     p->viRowBytes = 0;
339     p->viXsize = p->viYsize = 0;
340     p->viAppleMode = 0;
341     p->viAppleID = 0;
342    
343     // Start display manager thread
344     dm_thread = spawn_thread(display_manager, "Display Manager", B_NORMAL_PRIORITY, NULL);
345     resume_thread(dm_thread);
346    
347     // Open window/screen
348     open_display();
349     if (display_type == DIS_SCREEN && the_screen == NULL) {
350     char str[256];
351     sprintf(str, GetString(STR_FULL_SCREEN_ERR), strerror(screen_error), screen_error);
352     ErrorAlert(str);
353     return false;
354     }
355     return true;
356     }
357    
358    
359     /*
360     * Deinitialization
361     */
362    
363     void VideoExit(void)
364     {
365     if (dm_thread >= 0) {
366    
367     // Close display
368     acquire_sem(video_lock);
369     close_display();
370     if (private_data != NULL) {
371     delete private_data->gammaTable;
372     delete private_data;
373     }
374    
375     // Stop display manager
376     status_t l;
377     send_data(dm_thread, MSG_QUIT_DISPLAY_MANAGER, NULL, 0);
378     while (wait_for_thread(dm_thread, &l) == B_INTERRUPTED) ;
379     }
380    
381     // Delete semaphores
382     delete_sem(video_lock);
383     delete_sem(mac_os_lock);
384     delete_sem(dm_done_sem);
385     }
386    
387    
388     /*
389     * Close screen in full-screen mode
390     */
391    
392     void VideoQuitFullScreen(void)
393     {
394     D(bug("VideoQuitFullScreen()\n"));
395     if (display_type == DIS_SCREEN) {
396     acquire_sem(video_lock);
397     close_display();
398     release_sem(video_lock);
399     }
400     }
401    
402    
403     /*
404     * Execute video VBL routine
405     */
406    
407     void VideoVBL(void)
408     {
409     release_sem(mac_os_lock);
410     if (private_data != NULL && private_data->interruptsEnabled)
411     VSLDoInterruptService(private_data->vslServiceID);
412     while (acquire_sem(mac_os_lock) == B_INTERRUPTED) ;
413     }
414    
415    
416     /*
417     * Filter function for receiving mouse and keyboard events
418     */
419    
420     #define MENU_IS_POWER 0
421    
422     // Be -> Mac raw keycode translation table
423     static const uint8 keycode2mac[0x80] = {
424     0xff, 0x35, 0x7a, 0x78, 0x63, 0x76, 0x60, 0x61, // inv Esc F1 F2 F3 F4 F5 F6
425     0x62, 0x64, 0x65, 0x6d, 0x67, 0x6f, 0x69, 0x6b, // F7 F8 F9 F10 F11 F12 F13 F14
426     0x71, 0x0a, 0x12, 0x13, 0x14, 0x15, 0x17, 0x16, // F15 ` 1 2 3 4 5 6
427     0x1a, 0x1c, 0x19, 0x1d, 0x1b, 0x18, 0x33, 0x72, // 7 8 9 0 - = BSP INS
428     0x73, 0x74, 0x47, 0x4b, 0x43, 0x4e, 0x30, 0x0c, // HOM PUP NUM / * - TAB Q
429     0x0d, 0x0e, 0x0f, 0x11, 0x10, 0x20, 0x22, 0x1f, // W E R T Y U I O
430     0x23, 0x21, 0x1e, 0x2a, 0x75, 0x77, 0x79, 0x59, // P [ ] \ DEL END PDN 7
431     0x5b, 0x5c, 0x45, 0x39, 0x00, 0x01, 0x02, 0x03, // 8 9 + CAP A S D F
432     0x05, 0x04, 0x26, 0x28, 0x25, 0x29, 0x27, 0x24, // G H J K L ; ' RET
433     0x56, 0x57, 0x58, 0x38, 0x06, 0x07, 0x08, 0x09, // 4 5 6 SHL Z X C V
434     0x0b, 0x2d, 0x2e, 0x2b, 0x2f, 0x2c, 0x38, 0x3e, // B N M , . / SHR CUP
435     0x53, 0x54, 0x55, 0x4c, 0x36, 0x37, 0x31, 0x37, // 1 2 3 ENT CTL ALT SPC ALT
436     0x36, 0x3b, 0x3d, 0x3c, 0x52, 0x41, 0x3a, 0x3a, // CTR CLF CDN CRT 0 . CMD CMD
437     #if MENU_IS_POWER
438     0x7f, 0x32, 0x51, 0x7f, 0xff, 0xff, 0xff, 0xff, // MNU EUR = POW inv inv inv inv
439     #else
440     0x32, 0x32, 0x51, 0x7f, 0xff, 0xff, 0xff, 0xff, // MNU EUR = POW inv inv inv inv
441     #endif
442     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // inv inv inv inv inv inv inv inv
443     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff // inv inv inv inv inv inv inv inv
444     };
445    
446     static const uint8 modifier2mac[0x20] = {
447     #if MENU_IS_POWER
448     0x38, 0x37, 0x36, 0x39, 0x6b, 0x47, 0x3a, 0x7f, // SHF CMD inv CAP F14 NUM OPT MNU
449     #else
450     0x38, 0x37, 0x36, 0x39, 0x6b, 0x47, 0x3a, 0x32, // SHF CMD CTR CAP F14 NUM OPT MNU
451     #endif
452     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // inv inv inv inv inv inv inv inv
453     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // inv inv inv inv inv inv inv inv
454     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff // inv inv inv inv inv inv inv inv
455     };
456    
457     static filter_result filter_func(BMessage *msg, BHandler **target, BMessageFilter *filter)
458     {
459     // msg->PrintToStream();
460     switch (msg->what) {
461     case B_KEY_DOWN:
462     case B_KEY_UP: {
463     uint32 be_code = msg->FindInt32("key") & 0xff;
464     uint32 mac_code = keycode2mac[be_code];
465    
466     // Intercept Ctrl-F1 (mount floppy disk shortcut)
467     uint32 mods = msg->FindInt32("modifiers");
468     if (be_code == 0x02 && (mods & B_CONTROL_KEY))
469     SysMountVolume("/dev/disk/floppy/raw");
470    
471     if (mac_code == 0xff)
472     return B_DISPATCH_MESSAGE;
473     if (msg->what == B_KEY_DOWN)
474     ADBKeyDown(mac_code);
475     else
476     ADBKeyUp(mac_code);
477     return B_SKIP_MESSAGE;
478     }
479    
480     case B_MODIFIERS_CHANGED: {
481     uint32 mods = msg->FindInt32("modifiers");
482     uint32 old_mods = msg->FindInt32("be:old_modifiers");
483     uint32 changed = mods ^ old_mods;
484     uint32 mask = 1;
485     for (int i=0; i<32; i++, mask<<=1)
486     if (changed & mask) {
487     uint32 mac_code = modifier2mac[i];
488     if (mac_code == 0xff)
489     continue;
490     if (mods & mask)
491     ADBKeyDown(mac_code);
492     else
493     ADBKeyUp(mac_code);
494     }
495     return B_SKIP_MESSAGE;
496     }
497    
498     case B_MOUSE_MOVED: {
499     BPoint point;
500     msg->FindPoint("where", &point);
501     ADBMouseMoved(int(point.x), int(point.y));
502     return B_DISPATCH_MESSAGE; // Otherwise BitmapView::MouseMoved() wouldn't be called
503     }
504    
505     case B_MOUSE_DOWN: {
506     uint32 buttons = msg->FindInt32("buttons");
507     if (buttons & B_PRIMARY_MOUSE_BUTTON)
508     ADBMouseDown(0);
509     if (buttons & B_SECONDARY_MOUSE_BUTTON)
510     ADBMouseDown(1);
511     if (buttons & B_TERTIARY_MOUSE_BUTTON)
512     ADBMouseDown(2);
513     return B_SKIP_MESSAGE;
514     }
515    
516     case B_MOUSE_UP: // B_MOUSE_UP means "all buttons released"
517     ADBMouseUp(0);
518     ADBMouseUp(1);
519     ADBMouseUp(2);
520     return B_SKIP_MESSAGE;
521    
522     default:
523     return B_DISPATCH_MESSAGE;
524     }
525     }
526    
527    
528     /*
529     * Install graphics acceleration
530     */
531    
532     // Rectangle blitting
533     static void accl_bitblt(accl_params *p)
534     {
535     D(bug("accl_bitblt\n"));
536    
537     // Get blitting parameters
538     int16 src_X = p->src_rect[1] - p->src_bounds[1];
539     int16 src_Y = p->src_rect[0] - p->src_bounds[0];
540     int16 dest_X = p->dest_rect[1] - p->dest_bounds[1];
541     int16 dest_Y = p->dest_rect[0] - p->dest_bounds[0];
542     int16 width = p->dest_rect[3] - p->dest_rect[1] - 1;
543     int16 height = p->dest_rect[2] - p->dest_rect[0] - 1;
544     D(bug(" src X %d, src Y %d, dest X %d, dest Y %d\n", src_X, src_Y, dest_X, dest_Y));
545     D(bug(" width %d, height %d\n", width, height));
546    
547     // And perform the blit
548     bitblt_hook(src_X, src_Y, dest_X, dest_Y, width, height);
549     }
550    
551     static bool accl_bitblt_hook(accl_params *p)
552     {
553     D(bug("accl_draw_hook %p\n", p));
554    
555     // Check if we can accelerate this bitblt
556     if (p->src_base_addr == screen_base && p->dest_base_addr == screen_base &&
557     display_type == DIS_SCREEN && bitblt_hook != NULL &&
558     ((uint32 *)p)[0x18 >> 2] + ((uint32 *)p)[0x128 >> 2] == 0 &&
559     ((uint32 *)p)[0x130 >> 2] == 0 &&
560     p->transfer_mode == 0 &&
561     p->src_row_bytes > 0 && ((uint32 *)p)[0x15c >> 2] > 0) {
562    
563     // Yes, set function pointer
564     p->draw_proc = accl_bitblt;
565     return true;
566     }
567     return false;
568     }
569    
570     // Rectangle filling/inversion
571     static void accl_fillrect8(accl_params *p)
572     {
573     D(bug("accl_fillrect8\n"));
574    
575     // Get filling parameters
576     int16 dest_X = p->dest_rect[1] - p->dest_bounds[1];
577     int16 dest_Y = p->dest_rect[0] - p->dest_bounds[0];
578     int16 dest_X_max = p->dest_rect[3] - p->dest_bounds[1] - 1;
579     int16 dest_Y_max = p->dest_rect[2] - p->dest_bounds[0] - 1;
580     uint8 color = p->pen_mode == 8 ? p->fore_pen : p->back_pen;
581     D(bug(" dest X %d, dest Y %d\n", dest_X, dest_Y));
582     D(bug(" dest X max %d, dest Y max %d\n", dest_X_max, dest_Y_max));
583    
584     // And perform the fill
585     fillrect8_hook(dest_X, dest_Y, dest_X_max, dest_Y_max, color);
586     }
587    
588     static void accl_fillrect32(accl_params *p)
589     {
590     D(bug("accl_fillrect32\n"));
591    
592     // Get filling parameters
593     int16 dest_X = p->dest_rect[1] - p->dest_bounds[1];
594     int16 dest_Y = p->dest_rect[0] - p->dest_bounds[0];
595     int16 dest_X_max = p->dest_rect[3] - p->dest_bounds[1] - 1;
596     int16 dest_Y_max = p->dest_rect[2] - p->dest_bounds[0] - 1;
597     uint32 color = p->pen_mode == 8 ? p->fore_pen : p->back_pen;
598     D(bug(" dest X %d, dest Y %d\n", dest_X, dest_Y));
599     D(bug(" dest X max %d, dest Y max %d\n", dest_X_max, dest_Y_max));
600    
601     // And perform the fill
602     fillrect32_hook(dest_X, dest_Y, dest_X_max, dest_Y_max, color);
603     }
604    
605     static void accl_invrect(accl_params *p)
606     {
607     D(bug("accl_invrect\n"));
608    
609     // Get inversion parameters
610     int16 dest_X = p->dest_rect[1] - p->dest_bounds[1];
611     int16 dest_Y = p->dest_rect[0] - p->dest_bounds[0];
612     int16 dest_X_max = p->dest_rect[3] - p->dest_bounds[1] - 1;
613     int16 dest_Y_max = p->dest_rect[2] - p->dest_bounds[0] - 1;
614     D(bug(" dest X %d, dest Y %d\n", dest_X, dest_Y));
615     D(bug(" dest X max %d, dest Y max %d\n", dest_X_max, dest_Y_max));
616    
617     //!!?? pen_mode == 14
618    
619     // And perform the inversion
620     invrect_hook(dest_X, dest_Y, dest_X_max, dest_Y_max);
621     }
622    
623     static bool accl_fillrect_hook(accl_params *p)
624     {
625     D(bug("accl_fillrect_hook %p\n", p));
626    
627     // Check if we can accelerate this fillrect
628     if (p->dest_base_addr == screen_base && ((uint32 *)p)[0x284 >> 2] != 0 && display_type == DIS_SCREEN) {
629     if (p->transfer_mode == 8) {
630     // Fill
631     if (p->dest_pixel_size == 8 && fillrect8_hook != NULL) {
632     p->draw_proc = accl_fillrect8;
633     return true;
634     } else if (p->dest_pixel_size == 32 && fillrect32_hook != NULL) {
635     p->draw_proc = accl_fillrect32;
636     return true;
637     }
638     } else if (p->transfer_mode == 10 && invrect_hook != NULL) {
639     // Invert
640     p->draw_proc = accl_invrect;
641     return true;
642     }
643     }
644     return false;
645     }
646    
647     // Dummy for testing
648     /*
649     static void do_nothing(accl_params *p) {}
650     static bool accl_foobar_hook(accl_params *p)
651     {
652     printf("accl_foobar_hook %p\n", p);
653     printf(" src_base_addr %p, dest_base_addr %p\n", p->src_base_addr, p->dest_base_addr);
654     printf(" src_row_bytes %d, dest_row_bytes %d\n", p->src_row_bytes, p->dest_row_bytes);
655     printf(" src_pixel_size %d, dest_pixel_size %d\n", p->src_pixel_size, p->dest_pixel_size);
656     printf(" src_bounds (%d,%d,%d,%d), dest_bounds (%d,%d,%d,%d)\n", p->src_bounds[0], p->src_bounds[1], p->src_bounds[2], p->src_bounds[3], p->dest_bounds[0], p->dest_bounds[1], p->dest_bounds[2], p->dest_bounds[3]);
657     printf(" src_rect (%d,%d,%d,%d), dest_rect (%d,%d,%d,%d)\n", p->src_rect[0], p->src_rect[1], p->src_rect[2], p->src_rect[3], p->dest_rect[0], p->dest_rect[1], p->dest_rect[2], p->dest_rect[3]);
658     printf(" transfer mode %d\n", p->transfer_mode);
659     printf(" pen mode %d\n", p->pen_mode);
660     printf(" fore_pen %08x, back_pen %08x\n", p->fore_pen, p->back_pen);
661     printf(" val1 %08x, val2 %08x\n", ((uint32 *)p)[0x18 >> 2], ((uint32 *)p)[0x128 >> 2]);
662     printf(" val3 %08x\n", ((uint32 *)p)[0x130 >> 2]);
663     printf(" val4 %08x\n", ((uint32 *)p)[0x15c >> 2]);
664     printf(" val5 %08x\n", ((uint32 *)p)[0x160 >> 2]);
665     printf(" val6 %08x\n", ((uint32 *)p)[0x1b4 >> 2]);
666     printf(" val7 %08x\n", ((uint32 *)p)[0x284 >> 2]);
667     p->draw_proc = do_nothing;
668     return true;
669     }
670     static struct accl_hook_info foobar_hook_info = {accl_foobar_hook, accl_sync_hook, 6};
671     */
672    
673     // Wait for graphics operation to finish
674     static bool accl_sync_hook(void *arg)
675     {
676     D(bug("accl_sync_hook %p\n", arg));
677     if (sync_hook != NULL)
678     sync_hook();
679     return true;
680     }
681    
682     static struct accl_hook_info bitblt_hook_info = {accl_bitblt_hook, accl_sync_hook, ACCL_BITBLT};
683     static struct accl_hook_info fillrect_hook_info = {accl_fillrect_hook, accl_sync_hook, ACCL_FILLRECT};
684    
685     void VideoInstallAccel(void)
686     {
687     // Install acceleration hooks
688     if (PrefsFindBool("gfxaccel")) {
689     D(bug("Video: Installing acceleration hooks\n"));
690     NQDMisc(6, &bitblt_hook_info);
691     NQDMisc(6, &fillrect_hook_info);
692     }
693     }
694    
695    
696     /*
697     * Change video mode
698     */
699    
700     int16 video_mode_change(VidLocals *csSave, uint32 ParamPtr)
701     {
702     /* return if no mode change */
703     if ((csSave->saveData == ReadMacInt32(ParamPtr + csData)) &&
704     (csSave->saveMode == ReadMacInt16(ParamPtr + csMode))) return noErr;
705    
706     /* first find video mode in table */
707     for (int i=0; VModes[i].viType != DIS_INVALID; i++) {
708     if ((ReadMacInt16(ParamPtr + csMode) == VModes[i].viAppleMode) &&
709     (ReadMacInt32(ParamPtr + csData) == VModes[i].viAppleID)) {
710     csSave->saveMode = ReadMacInt16(ParamPtr + csMode);
711     csSave->saveData = ReadMacInt32(ParamPtr + csData);
712     csSave->savePage = ReadMacInt16(ParamPtr + csPage);
713    
714     while (acquire_sem(video_lock) == B_INTERRUPTED) ;
715     DisableInterrupt();
716    
717     /* close old display */
718     close_display();
719    
720     /* open new display */
721     cur_mode = i;
722     open_display();
723    
724     /* opening the screen failed? Then bail out */
725     if (display_type == DIS_SCREEN && the_screen == NULL) {
726     release_sem(video_lock);
727     ErrorAlert(GetString(STR_FULL_SCREEN_ERR));
728     QuitEmulator();
729     }
730    
731     WriteMacInt32(ParamPtr + csBaseAddr, screen_base);
732     csSave->saveBaseAddr=screen_base;
733     csSave->saveData=VModes[cur_mode].viAppleID;/* First mode ... */
734     csSave->saveMode=VModes[cur_mode].viAppleMode;
735    
736     EnableInterrupt();
737     release_sem(video_lock);
738     return noErr;
739     }
740     }
741     return paramErr;
742     }
743    
744    
745     /*
746     * Set color palette
747     */
748    
749     void video_set_palette(void)
750     {
751     if (display_type == DIS_SCREEN && the_screen != NULL)
752     the_screen->palette_changed = true;
753     else { // remap colors to BeOS-Palette
754     BScreen screen;
755     for (int i=0;i<256;i++)
756     remap_mac_be[i]=screen.IndexForColor(mac_pal[i].red,mac_pal[i].green,mac_pal[i].blue);
757     }
758     }
759    
760    
761     /*
762     * Set cursor image for window
763     */
764    
765     void video_set_cursor(void)
766     {
767     the_window->cursor_changed = true; // Inform window (don't set cursor directly because this may run at interrupt (i.e. signal handler) time)
768     }