1 /*
2 * atari_x11.c - X11 specific port code
3 *
4 * Copyright (c) 1995-1998 David Firth
5 * Copyright (C) 1998-2014 Atari800 development team (see DOC/CREDITS)
6 *
7 * This file is part of the Atari800 emulator project which emulates
8 * the Atari 400, 800, 800XL, 130XE, and 5200 8-bit computers.
9 *
10 * Atari800 is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * Atari800 is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with Atari800; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #include "config.h"
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31 #include "pokey.h"
32
33 #ifdef VMS
34 #include <stat.h>
35 #else
36 #include <sys/stat.h>
37 #endif
38
39 #include <signal.h>
40 #include <sys/time.h>
41
42 typedef unsigned char ubyte;
43 typedef unsigned short uword;
44
45 #ifdef XVIEW
46 #include <xview/xview.h>
47 #include <xview/frame.h>
48 #include <xview/panel.h>
49 #include <xview/canvas.h>
50 #include <xview/notice.h>
51 #include <xview/file_chsr.h>
52 #endif
53
54 #ifdef MOTIF
55 #include <Xm/MainW.h>
56 #include <Xm/DrawingA.h>
57 #include <Xm/MessageB.h>
58 #include <Xm/FileSB.h>
59 #include <Xm/RowColumn.h>
60 #include <Xm/ToggleBG.h>
61
62 static XtAppContext app;
63 static Widget toplevel;
64 static Widget main_w;
65 static Widget drawing_area;
66 static Widget fsel_b;
67 static Widget fsel_d;
68 static Widget fsel_r;
69 static Widget rbox_d;
70 static Widget togg_d1, togg_d2, togg_d3, togg_d4;
71 static Widget togg_d5, togg_d6, togg_d7, togg_d8;
72 static Widget eject_menu;
73 static Widget disable_menu;
74 static Widget system_menu;
75 static int motif_disk_sel = 1;
76 #endif /* MOTIF */
77
78 #include <X11/Xlib.h>
79 #include <X11/Xutil.h>
80 #include <X11/keysym.h>
81
82 #include "atari.h"
83 #include "cartridge.h"
84 #include "colours.h"
85 #include "input.h"
86 #include "akey.h"
87 #include "log.h"
88 #include "monitor.h"
89 #include "memory.h"
90 #include "screen.h"
91 #include "sio.h"
92 #include "sound.h"
93 #include "platform.h"
94 #include "ui.h"
95 #include "util.h"
96
97 #ifdef SHM
98 #include <sys/ipc.h>
99 #include <sys/shm.h>
100 #include <X11/extensions/XShm.h>
101
102 static XShmSegmentInfo shminfo;
103 static XImage *image = NULL;
104 #ifdef USE_COLOUR_TRANSLATION_TABLE
105 extern int colour_translation_table[256];
106 #endif
107 #endif /* SHM */
108
109 static int invisible = 0;
110
111 #ifdef LINUX_JOYSTICK
112 #include <linux/joystick.h>
113
114 static int js0;
115 static int js1;
116
117 static int js0_centre_x;
118 static int js0_centre_y;
119 static int js1_centre_x;
120 static int js1_centre_y;
121
122 static struct JS_DATA_TYPE js_data;
123 #endif /* LINUX_JOYSTICK */
124
125 typedef enum {
126 Small,
127 Large,
128 Huge
129 } WindowSize;
130
131 static WindowSize windowsize = Large;
132
133 enum {
134 MONITOR_NOTHING,
135 MONITOR_SIO
136 } x11_monitor = MONITOR_NOTHING;
137
138 static int x11bug = FALSE;
139 static int private_cmap = FALSE;
140
141 static int window_width = 336;
142 static int window_height = Screen_HEIGHT;
143
144 static int clipping_factor = 1;
145 static int clipping_x = 24;
146 static int clipping_y = 0;
147 static int clipping_width = 336;
148 static int clipping_height = Screen_HEIGHT;
149
150
151 static Display *display = NULL;
152 static Screen *screen = NULL;
153 static Window window;
154 #ifndef SHM
155 static Pixmap pixmap;
156 #endif
157 static Visual *visual = NULL;
158 static Colormap cmap;
159
160 static GC gc;
161 static GC gc_colour[256];
162 static int colours[256];
163
164 #ifdef XVIEW
165 static Frame frame;
166 static Panel panel;
167 static Canvas canvas;
168 static Menu system_menu;
169 static Menu consol_menu;
170 static Menu options_menu;
171 static Frame chooser;
172
173 static Frame controllers_frame;
174 static Panel controllers_panel;
175 static Panel_item keypad_item;
176 static Panel_item mouse_item;
177
178 #ifdef LINUX_JOYSTICK
179 static Panel_item js0_item;
180 static Panel_item js1_item;
181 #endif
182
183 static Frame performance_frame;
184 static Panel performance_panel;
185 static Panel_item refresh_slider;
186 #endif /* XVIEW */
187
188 static int SHIFT = 0x00;
189 static int CONTROL = 0x00;
190 static UBYTE *image_data = NULL;
191 static int modified;
192
193 static int keypad_mode = -1; /* Joystick */
194 static int keypad_trig = 1; /* Keypad Trigger Position */
195 static int keypad_stick = 0x0f; /* Keypad Joystick Position */
196
197 static int xmouse_mode = -1; /* Joystick, Paddle and Light Pen */
198 static int mouse_stick; /* Mouse Joystick Position */
199
200 static int js0_mode = -1;
201 static int js1_mode = -1;
202
203 #ifndef SHM
204
205 #define NPOINTS (4096 / 4)
206 #define NRECTS (4096 / 4)
207
208 static XPoint points[NPOINTS];
209 static XRectangle rectangles[NRECTS];
210 #endif
211
212 static int keyboard_consol = INPUT_CONSOL_NONE;
213 static int menu_consol = INPUT_CONSOL_NONE;
214
215 static int autorepeat = 1;
216 static int last_focus = FocusOut;
217
autorepeat_get(void)218 static void autorepeat_get(void)
219 {
220 XKeyboardState kstat;
221
222 XGetKeyboardControl(display, &kstat);
223 autorepeat = kstat.global_auto_repeat;
224 }
225
autorepeat_off(void)226 static void autorepeat_off(void)
227 {
228 XAutoRepeatOff(display);
229 }
230
autorepeat_restore(void)231 static void autorepeat_restore(void)
232 {
233 if (autorepeat)
234 XAutoRepeatOn(display);
235 else
236 XAutoRepeatOff(display);
237 }
238
segmentationfault(int x)239 static void segmentationfault(int x)
240 {
241 Atari800_ErrExit();
242 exit(0);
243 }
244
GetKeyCode(XEvent * event)245 static int GetKeyCode(XEvent *event)
246 {
247 KeySym keysym;
248 char buffer[128];
249 static int keycode = AKEY_NONE;
250
251 if (event->type == KeyPress || event->type == KeyRelease) {
252 XLookupString((XKeyEvent *) event, buffer, sizeof(buffer), &keysym, NULL);
253 }
254
255 switch (event->type) {
256 case Expose:
257 #ifndef SHM
258 XCopyArea(display, pixmap, window, gc,
259 0, 0,
260 window_width, window_height,
261 0, 0);
262 #else
263 modified = TRUE;
264 #endif
265 break;
266 case FocusIn:
267 autorepeat_off();
268 last_focus = FocusIn;
269 break;
270 case FocusOut:
271 autorepeat_restore();
272 last_focus = FocusOut;
273 break;
274 case VisibilityNotify:
275 if (((XVisibilityEvent*) event)->state == VisibilityFullyObscured)
276 invisible = 1;
277 else
278 invisible = 0;
279 break;
280 case KeyPress:
281 switch (keysym) {
282 case XK_Shift_L:
283 case XK_Shift_R:
284 SHIFT = AKEY_SHFT;
285 INPUT_key_shift = 1;
286 break;
287 case XK_Control_L:
288 keypad_trig = 0;
289 /* FALLTHROUGH */
290 case XK_Control_R:
291 CONTROL = AKEY_CTRL;
292 break;
293 case XK_F1:
294 keycode = AKEY_UI;
295 break;
296 case XK_F5:
297 case XK_L5:
298 keycode = SHIFT ? AKEY_COLDSTART : AKEY_WARMSTART;
299 break;
300 case XK_F8:
301 keycode = PLATFORM_Exit(TRUE) ? AKEY_NONE : AKEY_EXIT;
302 break;
303 case XK_F9:
304 keycode = AKEY_EXIT;
305 break;
306 case XK_F10:
307 case XK_L10:
308 keycode = SHIFT ? AKEY_SCREENSHOT_INTERLACE : AKEY_SCREENSHOT;
309 break;
310 case XK_F12:
311 keycode = AKEY_TURBO;
312 break;
313 case XK_Left:
314 keycode = AKEY_LEFT;
315 keypad_stick &= INPUT_STICK_LEFT;
316 break;
317 case XK_Up:
318 keycode = AKEY_UP;
319 keypad_stick &= INPUT_STICK_FORWARD;
320 break;
321 case XK_Right:
322 keycode = AKEY_RIGHT;
323 keypad_stick &= INPUT_STICK_RIGHT;
324 break;
325 case XK_Down:
326 keycode = AKEY_DOWN;
327 keypad_stick &= INPUT_STICK_BACK;
328 break;
329 case XK_KP_0:
330 keypad_trig = 0;
331 keycode = AKEY_NONE;
332 break;
333 case XK_KP_1:
334 keypad_stick = INPUT_STICK_LL;
335 keycode = AKEY_NONE;
336 break;
337 case XK_KP_2:
338 keypad_stick &= INPUT_STICK_BACK;
339 keycode = AKEY_NONE;
340 break;
341 case XK_KP_3:
342 keypad_stick = INPUT_STICK_LR;
343 keycode = AKEY_NONE;
344 break;
345 case XK_KP_4:
346 keypad_stick &= INPUT_STICK_LEFT;
347 keycode = AKEY_NONE;
348 break;
349 case XK_KP_5:
350 keypad_stick = INPUT_STICK_CENTRE;
351 keycode = AKEY_NONE;
352 break;
353 case XK_KP_6:
354 keypad_stick &= INPUT_STICK_RIGHT;
355 keycode = AKEY_NONE;
356 break;
357 case XK_KP_7:
358 keypad_stick = INPUT_STICK_UL;
359 keycode = AKEY_NONE;
360 break;
361 case XK_KP_8:
362 keypad_stick &= INPUT_STICK_FORWARD;
363 keycode = AKEY_NONE;
364 break;
365 case XK_KP_9:
366 keypad_stick = INPUT_STICK_UR;
367 keycode = AKEY_NONE;
368 break;
369 }
370 if (Atari800_machine_type == Atari800_MACHINE_5200 && !UI_is_active) {
371 switch (keysym) {
372 case XK_F4:
373 keycode = SHIFT | AKEY_5200_START;
374 break;
375 case XK_P:
376 case XK_p:
377 keycode = SHIFT | AKEY_5200_PAUSE;
378 break;
379 case XK_R:
380 case XK_r:
381 keycode = SHIFT | AKEY_5200_RESET;
382 break;
383 case XK_0:
384 keycode = SHIFT | AKEY_5200_0;
385 break;
386 case XK_1:
387 keycode = SHIFT | AKEY_5200_1;
388 break;
389 case XK_2:
390 keycode = SHIFT | AKEY_5200_2;
391 break;
392 case XK_3:
393 keycode = SHIFT | AKEY_5200_3;
394 break;
395 case XK_4:
396 keycode = SHIFT | AKEY_5200_4;
397 break;
398 case XK_5:
399 keycode = SHIFT | AKEY_5200_5;
400 break;
401 case XK_6:
402 keycode = SHIFT | AKEY_5200_6;
403 break;
404 case XK_7:
405 keycode = SHIFT | AKEY_5200_7;
406 break;
407 case XK_8:
408 keycode = SHIFT | AKEY_5200_8;
409 break;
410 case XK_9:
411 keycode = SHIFT | AKEY_5200_9;
412 break;
413 /* XXX: "SHIFT | " harmful for '#' and '*' ? */
414 case XK_numbersign:
415 case XK_equal:
416 keycode = AKEY_5200_HASH;
417 break;
418 case XK_asterisk:
419 keycode = AKEY_5200_ASTERISK;
420 break;
421 }
422 break;
423 }
424 switch (keysym) {
425 case XK_Caps_Lock:
426 keycode = SHIFT | CONTROL | AKEY_CAPSTOGGLE;
427 break;
428 case XK_Shift_Lock:
429 if (x11bug)
430 printf("XK_Shift_Lock\n");
431 break;
432 case XK_Alt_L:
433 case XK_Alt_R:
434 keycode = AKEY_ATARI;
435 break;
436 case XK_F2:
437 keyboard_consol &= (~INPUT_CONSOL_OPTION);
438 keycode = AKEY_NONE;
439 break;
440 case XK_F3:
441 keyboard_consol &= (~INPUT_CONSOL_SELECT);
442 keycode = AKEY_NONE;
443 break;
444 case XK_F4:
445 keyboard_consol &= (~INPUT_CONSOL_START);
446 keycode = AKEY_NONE;
447 break;
448 case XK_F6:
449 keycode = SHIFT | CONTROL | AKEY_HELP;
450 break;
451 case XK_Break:
452 case XK_F7:
453 keycode = AKEY_BREAK;
454 break;
455 case XK_Home:
456 keycode = AKEY_CLEAR;
457 break;
458 case XK_Insert:
459 if (SHIFT)
460 keycode = AKEY_INSERT_LINE;
461 else
462 keycode = AKEY_INSERT_CHAR;
463 break;
464 case XK_BackSpace:
465 if (CONTROL)
466 keycode = AKEY_DELETE_CHAR;
467 else if (SHIFT)
468 keycode = AKEY_DELETE_LINE;
469 else
470 keycode = AKEY_BACKSPACE;
471 break;
472 case XK_Delete:
473 if (CONTROL)
474 keycode = AKEY_DELETE_CHAR;
475 else if (SHIFT)
476 keycode = AKEY_DELETE_LINE;
477 else
478 keycode = AKEY_BACKSPACE; /* XXX */
479 break;
480 case XK_End:
481 keycode = SHIFT | CONTROL | AKEY_HELP;
482 break;
483 case XK_Escape:
484 keycode = SHIFT | CONTROL | AKEY_ESCAPE;
485 break;
486 case XK_Tab:
487 keycode = SHIFT | CONTROL | AKEY_TAB;
488 break;
489 case XK_exclam:
490 keycode = CONTROL | AKEY_EXCLAMATION;
491 break;
492 case XK_quotedbl:
493 keycode = CONTROL | AKEY_DBLQUOTE;
494 break;
495 case XK_numbersign:
496 keycode = CONTROL | AKEY_HASH;
497 break;
498 case XK_dollar:
499 keycode = CONTROL | AKEY_DOLLAR;
500 break;
501 case XK_percent:
502 keycode = CONTROL | AKEY_PERCENT;
503 break;
504 case XK_ampersand:
505 keycode = CONTROL | AKEY_AMPERSAND;
506 break;
507 case XK_quoteright:
508 keycode = CONTROL | AKEY_QUOTE;
509 break;
510 case XK_at:
511 keycode = CONTROL | AKEY_AT;
512 break;
513 case XK_parenleft:
514 keycode = CONTROL | AKEY_PARENLEFT;
515 break;
516 case XK_parenright:
517 keycode = CONTROL | AKEY_PARENRIGHT;
518 break;
519 case XK_less:
520 keycode = CONTROL | AKEY_LESS;
521 break;
522 case XK_greater:
523 keycode = CONTROL | AKEY_GREATER;
524 break;
525 case XK_equal:
526 keycode = CONTROL | AKEY_EQUAL;
527 break;
528 case XK_question:
529 keycode = CONTROL | AKEY_QUESTION;
530 break;
531 case XK_minus:
532 keycode = CONTROL | AKEY_MINUS;
533 break;
534 case XK_plus:
535 keycode = CONTROL | AKEY_PLUS;
536 break;
537 case XK_asterisk:
538 keycode = CONTROL | AKEY_ASTERISK;
539 break;
540 case XK_slash:
541 keycode = CONTROL | AKEY_SLASH;
542 break;
543 case XK_colon:
544 keycode = CONTROL | AKEY_COLON;
545 break;
546 case XK_semicolon:
547 keycode = CONTROL | AKEY_SEMICOLON;
548 break;
549 case XK_comma:
550 keycode = CONTROL | AKEY_COMMA;
551 break;
552 case XK_period:
553 keycode = CONTROL | AKEY_FULLSTOP;
554 break;
555 case XK_underscore:
556 keycode = CONTROL | AKEY_UNDERSCORE;
557 break;
558 case XK_bracketleft:
559 keycode = CONTROL | AKEY_BRACKETLEFT;
560 break;
561 case XK_bracketright:
562 keycode = CONTROL | AKEY_BRACKETRIGHT;
563 break;
564 case XK_asciicircum:
565 keycode = CONTROL | AKEY_CIRCUMFLEX;
566 break;
567 case XK_backslash:
568 keycode = CONTROL | AKEY_BACKSLASH;
569 break;
570 case XK_bar:
571 keycode = CONTROL | AKEY_BAR;
572 break;
573 case XK_space:
574 keycode = SHIFT | CONTROL | AKEY_SPACE;
575 keypad_trig = 0;
576 break;
577 case XK_Return:
578 keycode = SHIFT | CONTROL | AKEY_RETURN;
579 keypad_stick = INPUT_STICK_CENTRE;
580 break;
581 case XK_0:
582 keycode = CONTROL | AKEY_0;
583 break;
584 case XK_1:
585 keycode = CONTROL | AKEY_1;
586 break;
587 case XK_2:
588 keycode = CONTROL | AKEY_2;
589 break;
590 case XK_3:
591 keycode = CONTROL | AKEY_3;
592 break;
593 case XK_4:
594 keycode = CONTROL | AKEY_4;
595 break;
596 case XK_5:
597 keycode = CONTROL | AKEY_5;
598 break;
599 case XK_6:
600 keycode = CONTROL | AKEY_6;
601 break;
602 case XK_7:
603 keycode = CONTROL | AKEY_7;
604 break;
605 case XK_8:
606 keycode = CONTROL | AKEY_8;
607 break;
608 case XK_9:
609 keycode = CONTROL | AKEY_9;
610 break;
611 case XK_A:
612 case XK_a:
613 keycode = SHIFT | CONTROL | AKEY_a;
614 break;
615 case XK_B:
616 case XK_b:
617 keycode = SHIFT | CONTROL | AKEY_b;
618 break;
619 case XK_C:
620 case XK_c:
621 keycode = SHIFT | CONTROL | AKEY_c;
622 break;
623 case XK_D:
624 case XK_d:
625 keycode = SHIFT | CONTROL | AKEY_d;
626 break;
627 case XK_E:
628 case XK_e:
629 keycode = SHIFT | CONTROL | AKEY_e;
630 break;
631 case XK_F:
632 case XK_f:
633 keycode = SHIFT | CONTROL | AKEY_f;
634 break;
635 case XK_G:
636 case XK_g:
637 keycode = SHIFT | CONTROL | AKEY_g;
638 break;
639 case XK_H:
640 case XK_h:
641 keycode = SHIFT | CONTROL | AKEY_h;
642 break;
643 case XK_I:
644 case XK_i:
645 keycode = SHIFT | CONTROL | AKEY_i;
646 break;
647 case XK_J:
648 case XK_j:
649 keycode = SHIFT | CONTROL | AKEY_j;
650 break;
651 case XK_K:
652 case XK_k:
653 keycode = SHIFT | CONTROL | AKEY_k;
654 break;
655 case XK_L:
656 case XK_l:
657 keycode = SHIFT | CONTROL | AKEY_l;
658 break;
659 case XK_M:
660 case XK_m:
661 keycode = SHIFT | CONTROL | AKEY_m;
662 break;
663 case XK_N:
664 case XK_n:
665 keycode = SHIFT | CONTROL | AKEY_n;
666 break;
667 case XK_O:
668 case XK_o:
669 keycode = SHIFT | CONTROL | AKEY_o;
670 break;
671 case XK_P:
672 case XK_p:
673 keycode = SHIFT | CONTROL | AKEY_p;
674 break;
675 case XK_Q:
676 case XK_q:
677 keycode = SHIFT | CONTROL | AKEY_q;
678 break;
679 case XK_R:
680 case XK_r:
681 keycode = SHIFT | CONTROL | AKEY_r;
682 break;
683 case XK_S:
684 case XK_s:
685 keycode = SHIFT | CONTROL | AKEY_s;
686 break;
687 case XK_T:
688 case XK_t:
689 keycode = SHIFT | CONTROL | AKEY_t;
690 break;
691 case XK_U:
692 case XK_u:
693 keycode = SHIFT | CONTROL | AKEY_u;
694 break;
695 case XK_V:
696 case XK_v:
697 keycode = SHIFT | CONTROL | AKEY_v;
698 break;
699 case XK_W:
700 case XK_w:
701 keycode = SHIFT | CONTROL | AKEY_w;
702 break;
703 case XK_X:
704 case XK_x:
705 keycode = SHIFT | CONTROL | AKEY_x;
706 break;
707 case XK_Y:
708 case XK_y:
709 keycode = SHIFT | CONTROL | AKEY_y;
710 break;
711 case XK_Z:
712 case XK_z:
713 keycode = SHIFT | CONTROL | AKEY_z;
714 break;
715 default:
716 if (x11bug)
717 printf("Pressed Keysym = %x\n", (int) keysym);
718 break;
719 }
720 break;
721 case KeyRelease:
722 keycode = AKEY_NONE;
723 switch (keysym) {
724 case XK_Shift_L:
725 case XK_Shift_R:
726 INPUT_key_shift = 0;
727 SHIFT = 0x00;
728 break;
729 case XK_Control_L:
730 keypad_trig = 1;
731 /* FALLTHROUGH */
732 case XK_Control_R:
733 CONTROL = 0x00;
734 break;
735 case XK_Shift_Lock:
736 if (x11bug)
737 printf("XK_Shift_Lock\n");
738 break;
739 case XK_F2:
740 keyboard_consol |= INPUT_CONSOL_OPTION;
741 break;
742 case XK_F3:
743 keyboard_consol |= INPUT_CONSOL_SELECT;
744 break;
745 case XK_F4:
746 keyboard_consol |= INPUT_CONSOL_START;
747 break;
748 case XK_space:
749 case XK_KP_0:
750 keypad_trig = 1;
751 break;
752 case XK_Down:
753 case XK_KP_2:
754 keypad_stick |= INPUT_STICK_CENTRE ^ INPUT_STICK_BACK;
755 break;
756 case XK_Left:
757 case XK_KP_4:
758 keypad_stick |= INPUT_STICK_CENTRE ^ INPUT_STICK_LEFT;
759 break;
760 case XK_Right:
761 case XK_KP_6:
762 keypad_stick |= INPUT_STICK_CENTRE ^ INPUT_STICK_RIGHT;
763 break;
764 case XK_Up:
765 case XK_KP_8:
766 keypad_stick |= INPUT_STICK_CENTRE ^ INPUT_STICK_FORWARD;
767 break;
768 case XK_KP_1:
769 case XK_KP_3:
770 case XK_KP_5:
771 case XK_KP_7:
772 case XK_KP_9:
773 keypad_stick = INPUT_STICK_CENTRE;
774 break;
775 default:
776 break;
777 }
778 break;
779 }
780 return keycode;
781 }
782
783 #if defined(XVIEW) || defined(MOTIF)
784
insert_rom(const char * filename)785 static int insert_rom(const char *filename)
786 {
787 int r;
788 int i;
789 r = CARTRIDGE_Insert(filename);
790 if (r < 0)
791 return FALSE;
792 if (r == 0) {
793 Atari800_Coldstart();
794 return TRUE;
795 }
796 /* TODO: select cartridge type */
797 for (i = 1; i < CARTRIDGE_LAST_SUPPORTED; i++) {
798 if (CARTRIDGE_kb[i] == r) {
799 CARTRIDGE_type = i;
800 Atari800_Coldstart();
801 return TRUE;
802 }
803 }
804 return FALSE;
805 }
806
807 static int xview_keycode = AKEY_NONE;
808
809 #endif /* defined(XVIEW) || defined(MOTIF) */
810
811 #ifdef XVIEW
812
event_proc(Xv_Window window,Event * event,Notify_arg arg)813 static void event_proc(Xv_Window window, Event * event, Notify_arg arg)
814 {
815 xview_keycode = GetKeyCode(event->ie_xevent);
816 }
817
818 static int auto_reboot;
819
disk_change(char * a,char * full_filename,char * filename)820 static int disk_change(char *a, char *full_filename, char *filename)
821 {
822 int diskno;
823 int status;
824
825 diskno = 1;
826
827 if (!auto_reboot)
828 diskno = notice_prompt(panel, NULL,
829 NOTICE_MESSAGE_STRINGS,
830 "Insert Disk into which drive?",
831 NULL,
832 NOTICE_BUTTON, "1", 1,
833 NOTICE_BUTTON, "2", 2,
834 NOTICE_BUTTON, "3", 3,
835 NOTICE_BUTTON, "4", 4,
836 NOTICE_BUTTON, "5", 5,
837 NOTICE_BUTTON, "6", 6,
838 NOTICE_BUTTON, "7", 7,
839 NOTICE_BUTTON, "8", 8,
840 NULL);
841
842 if ((diskno < 1) || (diskno > 8)) {
843 printf("Invalid diskno: %d\n", diskno);
844 exit(1);
845 }
846 SIO_Dismount(diskno);
847 if (!SIO_Mount(diskno, full_filename, FALSE))
848 status = XV_ERROR;
849 else {
850 if (auto_reboot)
851 Atari800_Coldstart();
852 status = XV_OK;
853 }
854
855 return status;
856 }
857
boot_callback(void)858 static void boot_callback(void)
859 {
860 static char dir[FILENAME_MAX];
861 if (UI_n_atari_files_dir > 0)
862 strcpy(dir, UI_atari_files_dir[0]);
863 else
864 dir[0] = '\0';
865 auto_reboot = TRUE;
866 xv_set(chooser,
867 FRAME_LABEL, "Disk Selector",
868 FILE_CHOOSER_DIRECTORY, dir,
869 FILE_CHOOSER_NOTIFY_FUNC, disk_change,
870 XV_SHOW, TRUE,
871 NULL);
872 }
873
insert_callback(void)874 static void insert_callback(void)
875 {
876 static char dir[FILENAME_MAX];
877 if (UI_n_atari_files_dir > 0)
878 strcpy(dir, UI_atari_files_dir[0]);
879 else
880 dir[0] = '\0';
881 auto_reboot = FALSE;
882 xv_set(chooser,
883 FRAME_LABEL, "Disk Selector",
884 FILE_CHOOSER_DIRECTORY, dir,
885 FILE_CHOOSER_NOTIFY_FUNC, disk_change,
886 XV_SHOW, TRUE,
887 NULL);
888 }
889
eject_callback(void)890 static void eject_callback(void)
891 {
892 int diskno;
893
894 diskno = notice_prompt(panel, NULL,
895 NOTICE_MESSAGE_STRINGS,
896 "Eject Disk from drive?",
897 NULL,
898 NOTICE_BUTTON, "1", 1,
899 NOTICE_BUTTON, "2", 2,
900 NOTICE_BUTTON, "3", 3,
901 NOTICE_BUTTON, "4", 4,
902 NOTICE_BUTTON, "5", 5,
903 NOTICE_BUTTON, "6", 6,
904 NOTICE_BUTTON, "7", 7,
905 NOTICE_BUTTON, "8", 8,
906 NULL);
907
908 if (diskno >= 1 && diskno <= 8)
909 SIO_Dismount(diskno);
910 }
911
disable_callback(void)912 static void disable_callback(void)
913 {
914 int diskno;
915
916 diskno = notice_prompt(panel, NULL,
917 NOTICE_MESSAGE_STRINGS,
918 "Drive to Disable?",
919 NULL,
920 NOTICE_BUTTON, "1", 1,
921 NOTICE_BUTTON, "2", 2,
922 NOTICE_BUTTON, "3", 3,
923 NOTICE_BUTTON, "4", 4,
924 NOTICE_BUTTON, "5", 5,
925 NOTICE_BUTTON, "6", 6,
926 NOTICE_BUTTON, "7", 7,
927 NOTICE_BUTTON, "8", 8,
928 NULL);
929
930 if (diskno >= 1 && diskno <= 8)
931 SIO_DisableDrive(diskno);
932 }
933
rom_change(char * a,char * full_filename,char * filename)934 static int rom_change(char *a, char *full_filename, char *filename)
935 {
936 return insert_rom(full_filename) ? XV_OK : XV_ERROR;
937 }
938
insert_rom_callback(void)939 static void insert_rom_callback(void)
940 {
941 static char dir[FILENAME_MAX];
942 if (UI_n_atari_files_dir > 0)
943 strcpy(dir, UI_atari_files_dir[0]);
944 else
945 dir[0] = '\0';
946 xv_set(chooser,
947 FRAME_LABEL, "ROM Selector",
948 FILE_CHOOSER_DIRECTORY, dir,
949 FILE_CHOOSER_NOTIFY_FUNC, rom_change,
950 XV_SHOW, TRUE,
951 NULL);
952 }
953
remove_rom_callback(void)954 static void remove_rom_callback(void)
955 {
956 CARTRIDGE_Remove();
957 Atari800_Coldstart();
958 }
959
exit_callback(void)960 static void exit_callback(void)
961 {
962 Atari800_Exit(FALSE);
963 exit(1);
964 }
965
option_callback(void)966 static void option_callback(void)
967 {
968 menu_consol &= (~INPUT_CONSOL_OPTION);
969 }
970
select_callback(void)971 static void select_callback(void)
972 {
973 menu_consol &= (~INPUT_CONSOL_SELECT);
974 }
975
start_callback(void)976 static void start_callback(void)
977 {
978 menu_consol &= (~INPUT_CONSOL_START);
979 }
980
reset_callback(void)981 static void reset_callback(void)
982 {
983 Atari800_Warmstart();
984 }
985
coldstart_callback(void)986 static void coldstart_callback(void)
987 {
988 Atari800_Coldstart();
989 }
990
coldstart_sys(int machtype,int ram,const char * errmsg)991 static void coldstart_sys(int machtype, int ram, const char *errmsg)
992 {
993 Atari800_machine_type = machtype;
994 MEMORY_ram_size = ram;
995 if (!Atari800_InitialiseMachine()) {
996 notice_prompt(panel, NULL,
997 NOTICE_MESSAGE_STRINGS,
998 errmsg,
999 NULL,
1000 NOTICE_BUTTON, "Cancel", 1,
1001 NULL);
1002 }
1003 }
1004
coldstart_osa_callback(void)1005 static void coldstart_osa_callback(void)
1006 {
1007 coldstart_sys(Atari800_MACHINE_OSA, 48, "Sorry, OS/A ROM Unavailable");
1008 }
1009
coldstart_osb_callback(void)1010 static void coldstart_osb_callback(void)
1011 {
1012 coldstart_sys(Atari800_MACHINE_OSB, 48, "Sorry, OS/B ROM Unavailable");
1013 }
1014
coldstart_xl_callback(void)1015 static void coldstart_xl_callback(void)
1016 {
1017 coldstart_sys(Atari800_MACHINE_XLXE, 64, "Sorry, XL/XE ROM Unavailable");
1018 }
1019
coldstart_xe_callback(void)1020 static void coldstart_xe_callback(void)
1021 {
1022 coldstart_sys(Atari800_MACHINE_XLXE, 128, "Sorry, XL/XE ROM Unavailable");
1023 }
1024
coldstart_5200_callback(void)1025 static void coldstart_5200_callback(void)
1026 {
1027 coldstart_sys(Atari800_MACHINE_5200, 16, "Sorry, 5200 ROM Unavailable");
1028 }
1029
controllers_ok_callback(void)1030 static void controllers_ok_callback(void)
1031 {
1032 xv_set(controllers_frame,
1033 XV_SHOW, FALSE,
1034 NULL);
1035 }
1036
controllers_callback(void)1037 static void controllers_callback(void)
1038 {
1039 xv_set(controllers_frame,
1040 XV_SHOW, TRUE,
1041 NULL);
1042 }
1043
sorry_message(void)1044 static void sorry_message(void)
1045 {
1046 notice_prompt(panel, NULL,
1047 NOTICE_MESSAGE_STRINGS,
1048 "Sorry, controller already assigned",
1049 "to another device",
1050 NULL,
1051 NOTICE_BUTTON, "Cancel", 1,
1052 NULL);
1053 }
1054
keypad_callback(void)1055 static void keypad_callback(void)
1056 {
1057 int new_mode;
1058
1059 new_mode = xv_get(keypad_item, PANEL_VALUE);
1060
1061 if ((new_mode != xmouse_mode) &&
1062 (new_mode != js0_mode) &&
1063 (new_mode != js1_mode)) {
1064 keypad_mode = new_mode;
1065 }
1066 else {
1067 sorry_message();
1068 xv_set(keypad_item,
1069 PANEL_VALUE, keypad_mode,
1070 NULL);
1071 }
1072 }
1073
mouse_callback(void)1074 static void mouse_callback(void)
1075 {
1076 int new_mode;
1077
1078 new_mode = xv_get(mouse_item, PANEL_VALUE);
1079
1080 if ((new_mode != keypad_mode) &&
1081 (new_mode != js0_mode) &&
1082 (new_mode != js1_mode)) {
1083 xmouse_mode = new_mode;
1084 }
1085 else {
1086 sorry_message();
1087 xv_set(mouse_item,
1088 PANEL_VALUE, xmouse_mode,
1089 NULL);
1090 }
1091 }
1092
1093 #ifdef LINUX_JOYSTICK
js0_callback(void)1094 static void js0_callback(void)
1095 {
1096 int new_mode;
1097
1098 new_mode = xv_get(js0_item, PANEL_VALUE);
1099
1100 if ((new_mode != keypad_mode) &&
1101 (new_mode != xmouse_mode) &&
1102 (new_mode != js1_mode)) {
1103 js0_mode = new_mode;
1104 }
1105 else {
1106 sorry_message();
1107 xv_set(js0_item,
1108 PANEL_VALUE, js0_mode,
1109 NULL);
1110 }
1111 }
1112
js1_callback(void)1113 static void js1_callback(void)
1114 {
1115 int new_mode;
1116
1117 new_mode = xv_get(js1_item, PANEL_VALUE);
1118
1119 if ((new_mode != keypad_mode) &&
1120 (new_mode != xmouse_mode) &&
1121 (new_mode != js0_mode)) {
1122 js1_mode = new_mode;
1123 }
1124 else {
1125 sorry_message();
1126 xv_set(js1_item,
1127 PANEL_VALUE, js1_mode,
1128 NULL);
1129 }
1130 }
1131 #endif /* LINUX_JOYSTICK */
1132
performance_ok_callback(void)1133 static void performance_ok_callback(void)
1134 {
1135 xv_set(performance_frame,
1136 XV_SHOW, FALSE,
1137 NULL);
1138 }
1139
performance_callback(void)1140 static void performance_callback(void)
1141 {
1142 xv_set(performance_frame,
1143 XV_SHOW, TRUE,
1144 NULL);
1145 }
1146
refresh_callback(Panel_item item,int value,Event * event)1147 static void refresh_callback(Panel_item item, int value, Event * event)
1148 {
1149 Atari800_refresh_rate = value;
1150 }
1151
1152 #endif /* XVIEW */
1153
Atari_WhatIs(int mode)1154 static void Atari_WhatIs(int mode)
1155 {
1156 switch (mode) {
1157 case 0:
1158 printf("Joystick 0");
1159 break;
1160 case 1:
1161 printf("Joystick 1");
1162 break;
1163 case 2:
1164 printf("Joystick 2");
1165 break;
1166 case 3:
1167 printf("Joystick 3");
1168 break;
1169 default:
1170 printf("not available");
1171 break;
1172 }
1173 }
1174
1175 #ifdef MOTIF
1176
motif_boot_disk(Widget fs,XtPointer client_data,XtPointer cbs)1177 static void motif_boot_disk(Widget fs, XtPointer client_data,
1178 XtPointer cbs)
1179 {
1180 char *filename;
1181
1182 if (XmStringGetLtoR(((XmFileSelectionBoxCallbackStruct *) cbs)->value,
1183 XmSTRING_DEFAULT_CHARSET, &filename)) {
1184 if (*filename) {
1185 SIO_Dismount(1);
1186 if (SIO_Mount(1, filename, FALSE))
1187 Atari800_Coldstart();
1188 }
1189 XtFree(filename);
1190 }
1191 XtUnmanageChild(fs);
1192 XtPopdown(XtParent(fs));
1193 }
1194
motif_select_disk(Widget toggle,XtPointer client_data,XtPointer cbs)1195 static void motif_select_disk(Widget toggle, XtPointer client_data, XtPointer cbs)
1196 {
1197 motif_disk_sel = (int) client_data;
1198 }
1199
motif_insert_disk(Widget fs,XtPointer client_data,XtPointer cbs)1200 static void motif_insert_disk(Widget fs, XtPointer client_data, XtPointer cbs)
1201 {
1202 char *filename;
1203
1204 if (XmStringGetLtoR(((XmFileSelectionBoxCallbackStruct *) cbs)->value,
1205 XmSTRING_DEFAULT_CHARSET, &filename)) {
1206 if (*filename) {
1207 SIO_Dismount(motif_disk_sel);
1208 SIO_Mount(motif_disk_sel, filename, FALSE);
1209 }
1210 XtFree(filename);
1211 }
1212 XtUnmanageChild(fs);
1213 XtPopdown(XtParent(fs));
1214 }
1215
motif_insert_rom(Widget fs,XtPointer client_data,XtPointer cbs)1216 static void motif_insert_rom(Widget fs, XtPointer client_data, XtPointer cbs)
1217 {
1218 char *filename;
1219
1220 if (XmStringGetLtoR(((XmFileSelectionBoxCallbackStruct *) cbs)->value,
1221 XmSTRING_DEFAULT_CHARSET, &filename)) {
1222 if (*filename) {
1223 insert_rom(filename);
1224 }
1225 XtFree(filename);
1226 }
1227 XtUnmanageChild(fs);
1228 XtPopdown(XtParent(fs));
1229 }
1230
motif_fs_cancel(Widget fs,XtPointer client_data,XtPointer call_data)1231 static void motif_fs_cancel(Widget fs, XtPointer client_data, XtPointer call_data)
1232 {
1233 XtUnmanageChild(fs);
1234 XtPopdown(XtParent(fs));
1235 }
1236
motif_eject_cback(Widget button,XtPointer client_data,XtPointer cbs)1237 static void motif_eject_cback(Widget button, XtPointer client_data, XtPointer cbs)
1238 {
1239 SIO_Dismount(((int) client_data) + 1);
1240 }
1241
motif_disable_cback(Widget button,XtPointer client_data,XtPointer cbs)1242 static void motif_disable_cback(Widget button, XtPointer client_data, XtPointer cbs)
1243 {
1244 SIO_DisableDrive(((int) client_data) + 1);
1245 }
1246
update_fsel(Widget fsel)1247 static void update_fsel(Widget fsel)
1248 {
1249 XmString dirmask;
1250
1251 XtVaGetValues(fsel, XmNdirMask, &dirmask, NULL);
1252 XmFileSelectionDoSearch(fsel, dirmask);
1253 }
1254
motif_system_cback(Widget w,XtPointer item_no,XtPointer cbs)1255 static void motif_system_cback(Widget w, XtPointer item_no, XtPointer cbs)
1256 {
1257 XmString t;
1258 int status;
1259 char *errmsg = NULL;
1260
1261 switch ((int) item_no) {
1262 case 0:
1263 update_fsel(fsel_b);
1264 XtManageChild(fsel_b);
1265 XtPopup(XtParent(fsel_b), XtGrabNone);
1266 break;
1267 case 1:
1268 /* insert disk */
1269 update_fsel(fsel_d);
1270 XtManageChild(fsel_d);
1271 XtPopup(XtParent(fsel_d), XtGrabNone);
1272 break;
1273 case 2:
1274 /* eject disk */
1275 /* handled by pullright menu */
1276 break;
1277 case 3:
1278 /* disable drive */
1279 /* handled by pullright menu */
1280 break;
1281 case 4:
1282 /* insert rom */
1283 update_fsel(fsel_r);
1284 XtManageChild(fsel_r);
1285 XtPopup(XtParent(fsel_r), XtGrabNone);
1286 break;
1287 case 5:
1288 CARTRIDGE_Remove();
1289 Atari800_Coldstart();
1290 break;
1291 case 6:
1292 Atari800_machine_type = Atari800_MACHINE_OSA;
1293 MEMORY_ram_size = 48;
1294 status = Atari800_InitialiseMachine();
1295 if (status == 0)
1296 errmsg = "Sorry, OS/A ROM Unavailable";
1297 break;
1298 case 7:
1299 Atari800_machine_type = Atari800_MACHINE_OSB;
1300 MEMORY_ram_size = 48;
1301 status = Atari800_InitialiseMachine();
1302 if (status == 0)
1303 errmsg = "Sorry, OS/B ROM Unavailable";
1304 break;
1305 case 8:
1306 Atari800_machine_type = Atari800_MACHINE_XLXE;
1307 MEMORY_ram_size = 64;
1308 status = Atari800_InitialiseMachine();
1309 if (status == 0)
1310 errmsg = "Sorry, XL/XE ROM Unavailable";
1311 break;
1312 case 9:
1313 Atari800_machine_type = Atari800_MACHINE_XLXE;
1314 MEMORY_ram_size = 128;
1315 status = Atari800_InitialiseMachine();
1316 if (status == 0)
1317 errmsg = "Sorry, XL/XE ROM Unavailable";
1318 break;
1319 case 10:
1320 Atari800_machine_type = Atari800_MACHINE_5200;
1321 MEMORY_ram_size = 16;
1322 status = Atari800_InitialiseMachine();
1323 if (status == 0)
1324 errmsg = "Sorry, 5200 ROM Unavailable";
1325 break;
1326 case 11:
1327 Atari800_Exit(FALSE);
1328 exit(0);
1329 }
1330
1331 if (errmsg) {
1332 static Widget dialog = NULL;
1333
1334 if (!dialog) {
1335 Arg arg[1];
1336
1337 dialog = XmCreateErrorDialog(main_w, "message", arg, 0);
1338
1339 XtVaSetValues(dialog,
1340 XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL,
1341 NULL);
1342
1343 XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_OK_BUTTON));
1344 XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
1345 }
1346 t = XmStringCreateSimple(errmsg);
1347 XtVaSetValues(dialog,
1348 XmNmessageString, t,
1349 NULL);
1350 XmStringFree(t);
1351 XtManageChild(dialog);
1352 }
1353 }
1354
motif_consol_cback(Widget w,XtPointer item_no,XtPointer cbs)1355 static void motif_consol_cback(Widget w, XtPointer item_no, XtPointer cbs)
1356 {
1357 switch ((int) item_no) {
1358 case 0:
1359 menu_consol &= (~INPUT_CONSOL_OPTION);
1360 break;
1361 case 1:
1362 menu_consol &= (~INPUT_CONSOL_SELECT);
1363 break;
1364 case 2:
1365 menu_consol &= (~INPUT_CONSOL_START);
1366 break;
1367 case 3:
1368 Atari800_Warmstart();
1369 break;
1370 case 4:
1371 Atari800_Coldstart();
1372 break;
1373 }
1374 }
1375
motif_keypress(Widget w,XtPointer client_data,XEvent * event,Boolean * continue_to_dispatch)1376 static void motif_keypress(Widget w, XtPointer client_data, XEvent *event,
1377 Boolean *continue_to_dispatch)
1378 {
1379 xview_keycode = GetKeyCode(event);
1380 }
1381
motif_exposure(Widget w,XtPointer client_data,XEvent * event,Boolean * continue_to_dispatch)1382 static void motif_exposure(Widget w, XtPointer client_data, XEvent *event,
1383 Boolean *continue_to_dispatch)
1384 {
1385 modified = TRUE;
1386 }
1387
1388 #endif /* MOTIF */
1389
PLATFORM_Initialise(int * argc,char * argv[])1390 int PLATFORM_Initialise(int *argc, char *argv[])
1391 {
1392 #if !defined(XVIEW) && !defined(MOTIF)
1393 XSetWindowAttributes xswda;
1394 #endif
1395
1396 XGCValues xgcvl;
1397
1398 int depth;
1399 int colorstep;
1400 int i, j;
1401 int mode = 0;
1402 int help_only = FALSE;
1403
1404 #ifdef XVIEW
1405 int ypos;
1406
1407 xv_init(XV_INIT_ARGC_PTR_ARGV, argc, argv, NULL);
1408 #endif
1409
1410 #ifdef MOTIF
1411 toplevel = XtVaAppInitialize(&app, "Atari800",
1412 NULL, 0,
1413 argc, argv, NULL,
1414 XtNtitle, Atari800_TITLE,
1415 NULL);
1416 #endif
1417
1418 for (i = j = 1; i < *argc; i++) {
1419 int i_a = (i + 1 < *argc); /* is argument available? */
1420 int a_m = FALSE; /* error, argument missing! */
1421
1422 if (strcmp(argv[i], "-small") == 0)
1423 windowsize = Small;
1424 else if (strcmp(argv[i], "-large") == 0)
1425 windowsize = Large;
1426 else if (strcmp(argv[i], "-huge") == 0)
1427 windowsize = Huge;
1428 else if (strcmp(argv[i], "-clip_x") == 0)
1429 if (i_a)
1430 clipping_x = atoi(argv[++i]);
1431 else a_m = TRUE;
1432 else if (strcmp(argv[i], "-clip_y") == 0)
1433 if (i_a)
1434 clipping_y = atoi(argv[++i]);
1435 else a_m = TRUE;
1436 else if (strcmp(argv[i], "-clip_width") == 0)
1437 if (i_a)
1438 clipping_width = atoi(argv[++i]);
1439 else a_m = TRUE;
1440 else if (strcmp(argv[i], "-clip_height") == 0)
1441 if (i_a)
1442 clipping_height = atoi(argv[++i]);
1443 else a_m = TRUE;
1444 else if (strcmp(argv[i], "-x11bug") == 0)
1445 x11bug = TRUE;
1446 else if (strcmp(argv[i], "-sio") == 0)
1447 x11_monitor = MONITOR_SIO;
1448 else if (strcmp(argv[i], "-private_cmap") == 0)
1449 private_cmap = TRUE;
1450 else if (strcmp(argv[i], "-keypad") == 0) {
1451 if (keypad_mode == -1)
1452 keypad_mode = mode++;
1453 }
1454 else {
1455 if (strcmp(argv[i], "-help") == 0) {
1456 help_only = TRUE;
1457 printf("\t-small Small window (%dx%d)\n",
1458 clipping_width, clipping_height);
1459 printf("\t-large Large window (%dx%d)\n",
1460 clipping_width * 2, clipping_height * 2);
1461 printf("\t-huge Huge window (%dx%d)\n",
1462 clipping_width * 3, clipping_height * 3);
1463 printf("\t-x11bug Enable debug code in atari_x11.c\n");
1464 printf("\t-clip_x <n> Set left offset in pixels for clipping\n");
1465 printf("\t-clip_width <n> Set window clip-width\n");
1466 printf("\t-clip_y <n> Set top offset for clipping\n");
1467 printf("\t-clip_height <n> Set window clip-height\n");
1468 printf("\t-private_cmap Use private colormap\n");
1469 printf("\t-sio Show SIO monitor\n");
1470 printf("\t-keypad Keypad mode\n");
1471 }
1472 argv[j++] = argv[i];
1473 }
1474 }
1475
1476 *argc = j;
1477
1478 #ifdef SOUND
1479 if (!Sound_Initialise(argc, argv))
1480 return FALSE;
1481 #endif
1482
1483 if (help_only)
1484 return TRUE;
1485
1486 if ((clipping_x < 0) || (clipping_x >= Screen_WIDTH))
1487 clipping_x = 0;
1488 if ((clipping_y < 0) || (clipping_y >= Screen_HEIGHT))
1489 clipping_y = 0;
1490 if ((clipping_width <= 0) || (clipping_x + clipping_width > Screen_WIDTH))
1491 clipping_width = Screen_WIDTH - clipping_x;
1492 if ((clipping_height <= 0) || (clipping_y + clipping_height > Screen_HEIGHT))
1493 clipping_height = Screen_HEIGHT - clipping_y;
1494 Screen_visible_x1 = clipping_x;
1495 Screen_visible_x2 = clipping_x + clipping_width;
1496 Screen_visible_y1 = clipping_y;
1497 Screen_visible_y2 = clipping_y + clipping_height;
1498 switch (windowsize) {
1499 case Small:
1500 clipping_factor = 1;
1501 window_width = clipping_width;
1502 window_height = clipping_height;
1503 break;
1504 case Large:
1505 clipping_factor = 2;
1506 window_width = clipping_width * 2;
1507 window_height = clipping_height * 2;
1508 break;
1509 case Huge:
1510 clipping_factor = 3;
1511 window_width = clipping_width * 3;
1512 window_height = clipping_height * 3;
1513 break;
1514 }
1515
1516 #ifdef LINUX_JOYSTICK
1517 js0 = open("/dev/js0", O_RDONLY, 0777);
1518 if (js0 != -1) {
1519 int status;
1520
1521 status = read(js0, &js_data, JS_RETURN);
1522 if (status != JS_RETURN) {
1523 perror("/dev/js0");
1524 exit(1);
1525 }
1526 js0_centre_x = js_data.x;
1527 js0_centre_y = js_data.y;
1528
1529 if (x11bug)
1530 printf("Joystick 0: centre_x = %d, centry_y = %d\n",
1531 js0_centre_x, js0_centre_y);
1532
1533 js0_mode = mode++;
1534 }
1535 js1 = open("/dev/js1", O_RDONLY, 0777);
1536 if (js1 != -1) {
1537 int status;
1538
1539 status = read(js1, &js_data, JS_RETURN);
1540 if (status != JS_RETURN) {
1541 perror("/dev/js1");
1542 exit(1);
1543 }
1544 js1_centre_x = js_data.x;
1545 js1_centre_y = js_data.y;
1546
1547 if (x11bug)
1548 printf("Joystick 1: centre_x = %d, centry_y = %d\n",
1549 js1_centre_x, js1_centre_y);
1550
1551 js1_mode = mode++;
1552 }
1553 #endif
1554
1555 xmouse_mode = mode++;
1556 if (keypad_mode == -1)
1557 keypad_mode = mode++;
1558
1559 #ifdef XVIEW
1560 frame = (Frame) xv_create((Xv_opaque) NULL, FRAME,
1561 FRAME_LABEL, Atari800_TITLE,
1562 FRAME_SHOW_RESIZE_CORNER, FALSE,
1563 XV_WIDTH, window_width,
1564 XV_HEIGHT, window_height + 27,
1565 FRAME_SHOW_FOOTER, TRUE,
1566 XV_SHOW, TRUE,
1567 NULL);
1568
1569 panel = (Panel) xv_create(frame, PANEL,
1570 XV_HEIGHT, 25,
1571 XV_SHOW, TRUE,
1572 NULL);
1573
1574 system_menu = xv_create((Xv_opaque) NULL, MENU,
1575 MENU_ITEM,
1576 MENU_STRING, "Boot Disk",
1577 MENU_NOTIFY_PROC, boot_callback,
1578 NULL,
1579 MENU_ITEM,
1580 MENU_STRING, "Insert Disk",
1581 MENU_NOTIFY_PROC, insert_callback,
1582 NULL,
1583 MENU_ITEM,
1584 MENU_STRING, "Eject Disk",
1585 MENU_NOTIFY_PROC, eject_callback,
1586 NULL,
1587 MENU_ITEM,
1588 MENU_STRING, "Disable Drive",
1589 MENU_NOTIFY_PROC, disable_callback,
1590 NULL,
1591 MENU_ITEM,
1592 MENU_STRING, "Insert Cartridge",
1593 MENU_NOTIFY_PROC, insert_rom_callback,
1594 NULL,
1595 MENU_ITEM,
1596 MENU_STRING, "Remove Cartridge",
1597 MENU_NOTIFY_PROC, remove_rom_callback,
1598 NULL,
1599 MENU_ITEM,
1600 MENU_STRING, "Atari 800 OS/A",
1601 MENU_NOTIFY_PROC, coldstart_osa_callback,
1602 NULL,
1603 MENU_ITEM,
1604 MENU_STRING, "Atari 800 OS/B",
1605 MENU_NOTIFY_PROC, coldstart_osb_callback,
1606 NULL,
1607 MENU_ITEM,
1608 MENU_STRING, "Atari 800XL",
1609 MENU_NOTIFY_PROC, coldstart_xl_callback,
1610 NULL,
1611 MENU_ITEM,
1612 MENU_STRING, "Atari 130XE",
1613 MENU_NOTIFY_PROC, coldstart_xe_callback,
1614 NULL,
1615 MENU_ITEM,
1616 MENU_STRING, "Atari 5200",
1617 MENU_NOTIFY_PROC, coldstart_5200_callback,
1618 NULL,
1619 MENU_ITEM,
1620 MENU_STRING, "Exit",
1621 MENU_NOTIFY_PROC, exit_callback,
1622 NULL,
1623 NULL);
1624
1625 xv_create(panel, PANEL_BUTTON,
1626 PANEL_LABEL_STRING, "System",
1627 PANEL_ITEM_MENU, system_menu,
1628 NULL);
1629
1630 consol_menu = (Menu) xv_create((Xv_opaque) NULL, MENU,
1631 MENU_ITEM,
1632 MENU_STRING, "Option",
1633 MENU_NOTIFY_PROC, option_callback,
1634 NULL,
1635 MENU_ITEM,
1636 MENU_STRING, "Select",
1637 MENU_NOTIFY_PROC, select_callback,
1638 NULL,
1639 MENU_ITEM,
1640 MENU_STRING, "Start",
1641 MENU_NOTIFY_PROC, start_callback,
1642 NULL,
1643 MENU_ITEM,
1644 MENU_STRING, "Reset",
1645 MENU_NOTIFY_PROC, reset_callback,
1646 NULL,
1647 MENU_ITEM,
1648 MENU_STRING, "Coldstart",
1649 MENU_NOTIFY_PROC, coldstart_callback,
1650 NULL,
1651 NULL);
1652
1653 xv_create(panel, PANEL_BUTTON,
1654 PANEL_LABEL_STRING, "Console",
1655 PANEL_ITEM_MENU, consol_menu,
1656 NULL);
1657
1658 options_menu = (Menu) xv_create((Xv_opaque) NULL, MENU,
1659 MENU_ITEM,
1660 MENU_STRING, "Controllers",
1661 MENU_NOTIFY_PROC, controllers_callback,
1662 NULL,
1663 MENU_ITEM,
1664 MENU_STRING, "Performance",
1665 MENU_NOTIFY_PROC, performance_callback,
1666 NULL,
1667 NULL);
1668
1669 xv_create(panel, PANEL_BUTTON,
1670 PANEL_LABEL_STRING, "Options",
1671 PANEL_ITEM_MENU, options_menu,
1672 NULL);
1673
1674 canvas = (Canvas) xv_create(frame, CANVAS,
1675 CANVAS_WIDTH, window_width,
1676 CANVAS_HEIGHT, window_height,
1677 NULL);
1678 /*
1679 =====================================
1680 Create Controller Configuration Frame
1681 =====================================
1682 */
1683 controllers_frame = (Frame) xv_create(frame, FRAME_CMD,
1684 FRAME_LABEL, "Controller Configuration",
1685 XV_WIDTH, 300,
1686 XV_HEIGHT, 150,
1687 NULL);
1688
1689 controllers_panel = (Panel) xv_get(controllers_frame, FRAME_CMD_PANEL,
1690 NULL);
1691
1692 ypos = 10;
1693 keypad_item = (Panel_item) xv_create(controllers_panel, PANEL_CHOICE_STACK,
1694 PANEL_VALUE_X, 150,
1695 PANEL_VALUE_Y, ypos,
1696 PANEL_LAYOUT, PANEL_HORIZONTAL,
1697 PANEL_LABEL_STRING, "Numeric Keypad",
1698 PANEL_CHOICE_STRINGS,
1699 "Joystick 1",
1700 "Joystick 2",
1701 "Joystick 3",
1702 "Joystick 4",
1703 NULL,
1704 PANEL_VALUE, keypad_mode,
1705 PANEL_NOTIFY_PROC, keypad_callback,
1706 NULL);
1707 ypos += 25;
1708
1709 mouse_item = (Panel_item) xv_create(controllers_panel, PANEL_CHOICE_STACK,
1710 PANEL_VALUE_X, 150,
1711 PANEL_VALUE_Y, ypos,
1712 PANEL_LAYOUT, PANEL_HORIZONTAL,
1713 PANEL_LABEL_STRING, "Mouse",
1714 PANEL_CHOICE_STRINGS,
1715 "Joystick 1",
1716 "Joystick 2",
1717 "Joystick 3",
1718 "Joystick 4",
1719 NULL,
1720 PANEL_VALUE, xmouse_mode,
1721 PANEL_NOTIFY_PROC, mouse_callback,
1722 NULL);
1723 ypos += 25;
1724
1725 #ifdef LINUX_JOYSTICK
1726 if (js0 != -1) {
1727 js0_item = (Panel_item) xv_create(controllers_panel, PANEL_CHOICE_STACK,
1728 PANEL_VALUE_X, 150,
1729 PANEL_VALUE_Y, ypos,
1730 PANEL_LAYOUT, PANEL_HORIZONTAL,
1731 PANEL_LABEL_STRING, "/dev/js0",
1732 PANEL_CHOICE_STRINGS,
1733 "Joystick 1",
1734 "Joystick 2",
1735 "Joystick 3",
1736 "Joystick 4",
1737 NULL,
1738 PANEL_VALUE, js0_mode,
1739 PANEL_NOTIFY_PROC, js0_callback,
1740 NULL);
1741 ypos += 25;
1742 }
1743 if (js1 != -1) {
1744 js1_item = (Panel_item) xv_create(controllers_panel, PANEL_CHOICE_STACK,
1745 PANEL_VALUE_X, 150,
1746 PANEL_VALUE_Y, ypos,
1747 PANEL_LAYOUT, PANEL_HORIZONTAL,
1748 PANEL_LABEL_STRING, "/dev/js1",
1749 PANEL_CHOICE_STRINGS,
1750 "Joystick 1",
1751 "Joystick 2",
1752 "Joystick 3",
1753 "Joystick 4",
1754 NULL,
1755 PANEL_VALUE, js1_mode,
1756 PANEL_NOTIFY_PROC, js1_callback,
1757 NULL);
1758 ypos += 25;
1759 }
1760 #endif
1761
1762 xv_create(controllers_panel, PANEL_BUTTON,
1763 XV_X, 130,
1764 XV_Y, 125,
1765 PANEL_LABEL_STRING, "OK",
1766 PANEL_NOTIFY_PROC, controllers_ok_callback,
1767 NULL);
1768 /*
1769 ======================================
1770 Create Performance Configuration Frame
1771 ======================================
1772 */
1773 performance_frame = (Frame) xv_create(frame, FRAME_CMD,
1774 FRAME_LABEL, "Performance Configuration",
1775 XV_WIDTH, 400,
1776 XV_HEIGHT, 100,
1777 NULL);
1778
1779 performance_panel = (Panel) xv_get(performance_frame, FRAME_CMD_PANEL,
1780 NULL);
1781
1782 ypos = 10;
1783 refresh_slider = (Panel_item) xv_create(performance_panel, PANEL_SLIDER,
1784 PANEL_VALUE_X, 155,
1785 PANEL_VALUE_Y, ypos,
1786 PANEL_LAYOUT, PANEL_HORIZONTAL,
1787 PANEL_LABEL_STRING, "Screen Refresh Rate",
1788 PANEL_VALUE, Atari800_refresh_rate,
1789 PANEL_MIN_VALUE, 1,
1790 PANEL_MAX_VALUE, 32,
1791 PANEL_SLIDER_WIDTH, 100,
1792 PANEL_TICKS, 32,
1793 PANEL_NOTIFY_PROC, refresh_callback,
1794 NULL);
1795 ypos += 25;
1796
1797 xv_create(performance_panel, PANEL_BUTTON,
1798 XV_X, 180,
1799 XV_Y, 75,
1800 PANEL_LABEL_STRING, "OK",
1801 PANEL_NOTIFY_PROC, performance_ok_callback,
1802 NULL);
1803 /*
1804 ====================
1805 Get X Window Objects
1806 ====================
1807 */
1808 display = (Display *) xv_get(frame, XV_DISPLAY);
1809 if (!display) {
1810 printf("Failed to open display\n");
1811 exit(1);
1812 }
1813 autorepeat_get();
1814 screen = XDefaultScreenOfDisplay(display);
1815 if (!screen) {
1816 printf("Unable to get screen\n");
1817 exit(1);
1818 }
1819 visual = XDefaultVisualOfScreen(screen);
1820 if (!visual) {
1821 printf("Unable to get visual\n");
1822 exit(1);
1823 }
1824 window = (Window) xv_get(canvas_paint_window(canvas), XV_XID);
1825 depth = XDefaultDepthOfScreen(screen);
1826 cmap = XDefaultColormapOfScreen(screen);
1827
1828 chooser = (Frame) xv_create(frame, FILE_CHOOSER,
1829 FILE_CHOOSER_TYPE, FILE_CHOOSER_OPEN,
1830 NULL);
1831
1832 xv_set(canvas_paint_window(canvas),
1833 WIN_EVENT_PROC, event_proc,
1834 WIN_CONSUME_EVENTS, WIN_ASCII_EVENTS, WIN_MOUSE_BUTTONS,
1835 WIN_VISIBILITY_NOTIFY, /* mmm */
1836 NULL,
1837 NULL);
1838
1839 #endif /* XVIEW */
1840
1841 #ifdef MOTIF
1842 {
1843 Widget menubar;
1844
1845 XmString s_system;
1846 XmString s_boot_disk;
1847 XmString s_insert_disk;
1848 XmString s_eject_disk;
1849 XmString s_disable_drive;
1850 XmString s_insert_cart;
1851 XmString s_remove_cart;
1852 XmString s_osa;
1853 XmString s_osb;
1854 XmString s_osxl;
1855 XmString s_osxe;
1856 XmString s_os5200;
1857 XmString s_exit;
1858
1859 XmString s_console;
1860 XmString s_option;
1861 XmString s_select;
1862 XmString s_start;
1863 XmString s_warmstart;
1864 XmString s_coldstart;
1865
1866 XmString s_label;
1867
1868 XmString s_d1, s_d2, s_d3, s_d4;
1869 XmString s_d5, s_d6, s_d7, s_d8;
1870
1871 char *tmpstr;
1872 XmString xmtmpstr;
1873
1874 Arg args[8];
1875 int n;
1876
1877 main_w = XtVaCreateManagedWidget("main_window",
1878 xmMainWindowWidgetClass, toplevel,
1879 NULL);
1880
1881 s_system = XmStringCreateSimple("System");
1882 s_boot_disk = XmStringCreateSimple("Boot Disk...");
1883 s_insert_disk = XmStringCreateSimple("Insert Disk...");
1884 s_eject_disk = XmStringCreateSimple("Eject Disk");
1885 s_disable_drive = XmStringCreateSimple("Disable Drive");
1886 s_insert_cart = XmStringCreateSimple("Insert Cartridge...");
1887 s_remove_cart = XmStringCreateSimple("Remove Cartridge");
1888 s_osa = XmStringCreateSimple("Atari 800 OS/A");
1889 s_osb = XmStringCreateSimple("Atari 800 OS/B");
1890 s_osxl = XmStringCreateSimple("Atari 800XL");
1891 s_osxe = XmStringCreateSimple("Atari 130XE");
1892 s_os5200 = XmStringCreateSimple("Atari 5200");
1893 s_exit = XmStringCreateSimple("Exit");
1894
1895 s_console = XmStringCreateSimple("Console");
1896 s_option = XmStringCreateSimple("Option");
1897 s_select = XmStringCreateSimple("Select");
1898 s_start = XmStringCreateSimple("Start");
1899 s_warmstart = XmStringCreateSimple("Warmstart");
1900 s_coldstart = XmStringCreateSimple("Coldstart");
1901
1902 menubar = XmVaCreateSimpleMenuBar(main_w, "menubar",
1903 XmVaCASCADEBUTTON, s_system, 'S',
1904 XmVaCASCADEBUTTON, s_console, 'C',
1905 NULL);
1906
1907 system_menu =
1908 XmVaCreateSimplePulldownMenu(menubar, "system_menu", 0, motif_system_cback,
1909 XmVaPUSHBUTTON, s_boot_disk, 'o', NULL, NULL,
1910 XmVaPUSHBUTTON, s_insert_disk, 'I', NULL, NULL,
1911 XmVaCASCADEBUTTON, s_eject_disk, 'j',
1912 XmVaCASCADEBUTTON, s_disable_drive, 'D',
1913 XmVaSEPARATOR,
1914 XmVaPUSHBUTTON, s_insert_cart, 'n', NULL, NULL,
1915 XmVaPUSHBUTTON, s_remove_cart, 'R', NULL, NULL,
1916 XmVaSEPARATOR,
1917 XmVaPUSHBUTTON, s_osa, 'A', NULL, NULL,
1918 XmVaPUSHBUTTON, s_osb, 'B', NULL, NULL,
1919 XmVaPUSHBUTTON, s_osxl, 'L', NULL, NULL,
1920 XmVaPUSHBUTTON, s_osxe, 'E', NULL, NULL,
1921 XmVaPUSHBUTTON, s_os5200, '5', NULL, NULL,
1922 XmVaSEPARATOR,
1923 XmVaPUSHBUTTON, s_exit, 'x', NULL, NULL,
1924 NULL);
1925
1926 XmVaCreateSimplePulldownMenu(menubar, "console_menu", 1, motif_consol_cback,
1927 XmVaPUSHBUTTON, s_option, 'O', NULL, NULL,
1928 XmVaPUSHBUTTON, s_select, 't', NULL, NULL,
1929 XmVaPUSHBUTTON, s_start, 'S', NULL, NULL,
1930 XmVaSEPARATOR,
1931 XmVaPUSHBUTTON, s_warmstart, 'W', NULL, NULL,
1932 XmVaPUSHBUTTON, s_coldstart, 'C', NULL, NULL,
1933 NULL);
1934
1935 XmStringFree(s_system);
1936 XmStringFree(s_boot_disk);
1937 XmStringFree(s_insert_disk);
1938 XmStringFree(s_eject_disk);
1939 XmStringFree(s_disable_drive);
1940 XmStringFree(s_insert_cart);
1941 XmStringFree(s_remove_cart);
1942 XmStringFree(s_osa);
1943 XmStringFree(s_osb);
1944 XmStringFree(s_osxl);
1945 XmStringFree(s_osxe);
1946 XmStringFree(s_os5200);
1947 XmStringFree(s_exit);
1948
1949 XmStringFree(s_console);
1950 XmStringFree(s_option);
1951 XmStringFree(s_select);
1952 XmStringFree(s_start);
1953 XmStringFree(s_warmstart);
1954 XmStringFree(s_coldstart);
1955
1956 XtManageChild(menubar);
1957
1958 fsel_b = XmCreateFileSelectionDialog(toplevel, "boot_disk", NULL, 0);
1959 XtAddCallback(fsel_b, XmNokCallback, motif_boot_disk, NULL);
1960 XtAddCallback(fsel_b, XmNcancelCallback, motif_fs_cancel, NULL);
1961
1962 fsel_d = XmCreateFileSelectionDialog(toplevel, "load_disk", NULL, 0);
1963 XtAddCallback(fsel_d, XmNokCallback, motif_insert_disk, NULL);
1964 XtAddCallback(fsel_d, XmNcancelCallback, motif_fs_cancel, NULL);
1965
1966 n = 0;
1967 XtSetArg(args[n], XmNradioBehavior, True);
1968 n++;
1969 XtSetArg(args[n], XmNradioAlwaysOne, True);
1970 n++;
1971 XtSetArg(args[n], XmNorientation, XmHORIZONTAL);
1972 n++;
1973 rbox_d = XmCreateWorkArea(fsel_d, "rbox_d", args, n);
1974 XtManageChild(rbox_d);
1975
1976 s_label = XmStringCreateSimple("D1:");
1977 n = 0;
1978 XtSetArg(args[n], XmNlabelString, s_label);
1979 n++;
1980 XtSetArg(args[n], XmNset, True);
1981 n++;
1982 togg_d1 = XmCreateToggleButtonGadget(rbox_d, "togg_d1", args, n);
1983 XtManageChild(togg_d1);
1984 XmStringFree(s_label);
1985 XtAddCallback(togg_d1, XmNarmCallback, motif_select_disk, (XtPointer) 1);
1986
1987 s_label = XmStringCreateSimple("D2:");
1988 n = 0;
1989 XtSetArg(args[n], XmNlabelString, s_label);
1990 n++;
1991 togg_d2 = XmCreateToggleButtonGadget(rbox_d, "togg_d2", args, n);
1992 XtManageChild(togg_d2);
1993 XmStringFree(s_label);
1994 XtAddCallback(togg_d2, XmNarmCallback, motif_select_disk, (XtPointer) 2);
1995
1996 s_label = XmStringCreateSimple("D3:");
1997 n = 0;
1998 XtSetArg(args[n], XmNlabelString, s_label);
1999 n++;
2000 togg_d3 = XmCreateToggleButtonGadget(rbox_d, "togg_d3", args, n);
2001 XtManageChild(togg_d3);
2002 XmStringFree(s_label);
2003 XtAddCallback(togg_d3, XmNarmCallback, motif_select_disk, (XtPointer) 3);
2004
2005 s_label = XmStringCreateSimple("D4:");
2006 n = 0;
2007 XtSetArg(args[n], XmNlabelString, s_label);
2008 n++;
2009 togg_d4 = XmCreateToggleButtonGadget(rbox_d, "togg_d4", args, n);
2010 XtManageChild(togg_d4);
2011 XmStringFree(s_label);
2012 XtAddCallback(togg_d4, XmNarmCallback, motif_select_disk, (XtPointer) 4);
2013
2014 s_label = XmStringCreateSimple("D5:");
2015 n = 0;
2016 XtSetArg(args[n], XmNlabelString, s_label);
2017 n++;
2018 togg_d5 = XmCreateToggleButtonGadget(rbox_d, "togg_d5", args, n);
2019 XtManageChild(togg_d5);
2020 XmStringFree(s_label);
2021 XtAddCallback(togg_d5, XmNarmCallback, motif_select_disk, (XtPointer) 5);
2022
2023 s_label = XmStringCreateSimple("D6:");
2024 n = 0;
2025 XtSetArg(args[n], XmNlabelString, s_label);
2026 n++;
2027 togg_d6 = XmCreateToggleButtonGadget(rbox_d, "togg_d6", args, n);
2028 XtManageChild(togg_d6);
2029 XmStringFree(s_label);
2030 XtAddCallback(togg_d6, XmNarmCallback, motif_select_disk, (XtPointer) 6);
2031
2032 s_label = XmStringCreateSimple("D7:");
2033 n = 0;
2034 XtSetArg(args[n], XmNlabelString, s_label);
2035 n++;
2036 togg_d7 = XmCreateToggleButtonGadget(rbox_d, "togg_d7", args, n);
2037 XtManageChild(togg_d7);
2038 XmStringFree(s_label);
2039 XtAddCallback(togg_d7, XmNarmCallback, motif_select_disk, (XtPointer) 7);
2040
2041 s_label = XmStringCreateSimple("D8:");
2042 n = 0;
2043 XtSetArg(args[n], XmNlabelString, s_label);
2044 n++;
2045 togg_d8 = XmCreateToggleButtonGadget(rbox_d, "togg_d8", args, n);
2046 XtManageChild(togg_d8);
2047 XmStringFree(s_label);
2048 XtAddCallback(togg_d8, XmNarmCallback, motif_select_disk, (XtPointer) 8);
2049
2050
2051 fsel_r = XmCreateFileSelectionDialog(toplevel, "load_rom", NULL, 0);
2052 XtAddCallback(fsel_r, XmNokCallback, motif_insert_rom, NULL);
2053 XtAddCallback(fsel_r, XmNcancelCallback, motif_fs_cancel, NULL);
2054
2055 if (UI_n_atari_files_dir > 0) {
2056 tmpstr = (char *) XtMalloc(strlen(UI_atari_files_dir[0] + 3));
2057 strcpy(Util_stpcpy(tmpstr, UI_atari_files_dir[0]), "/*");
2058 }
2059 else {
2060 tmpstr = (char *) XtMalloc(4);
2061 strcpy(tmpstr, "./*");
2062 }
2063 xmtmpstr = XmStringCreateSimple(tmpstr);
2064 XmFileSelectionDoSearch(fsel_b, xmtmpstr);
2065 XmFileSelectionDoSearch(fsel_d, xmtmpstr);
2066 XmStringFree(xmtmpstr);
2067 /* XXX: can use the same tmpstr? can use the same xmtmpstr? */
2068 xmtmpstr = XmStringCreateSimple(tmpstr);
2069 XmFileSelectionDoSearch(fsel_r, xmtmpstr);
2070 XmStringFree(xmtmpstr);
2071 XtFree(tmpstr);
2072
2073 s_d1 = XmStringCreateSimple("D1:");
2074 s_d2 = XmStringCreateSimple("D2:");
2075 s_d3 = XmStringCreateSimple("D3:");
2076 s_d4 = XmStringCreateSimple("D4:");
2077 s_d5 = XmStringCreateSimple("D5:");
2078 s_d6 = XmStringCreateSimple("D6:");
2079 s_d7 = XmStringCreateSimple("D7:");
2080 s_d8 = XmStringCreateSimple("D8:");
2081 eject_menu = XmVaCreateSimplePulldownMenu(system_menu,
2082 "eject_disk", 2,
2083 motif_eject_cback,
2084 XmVaPUSHBUTTON, s_d1, '1', NULL, NULL,
2085 XmVaPUSHBUTTON, s_d2, '2', NULL, NULL,
2086 XmVaPUSHBUTTON, s_d3, '3', NULL, NULL,
2087 XmVaPUSHBUTTON, s_d4, '4', NULL, NULL,
2088 XmVaPUSHBUTTON, s_d5, '5', NULL, NULL,
2089 XmVaPUSHBUTTON, s_d6, '6', NULL, NULL,
2090 XmVaPUSHBUTTON, s_d7, '7', NULL, NULL,
2091 XmVaPUSHBUTTON, s_d8, '8', NULL, NULL,
2092 NULL);
2093 disable_menu = XmVaCreateSimplePulldownMenu(system_menu,
2094 "disable_disk", 3,
2095 motif_disable_cback,
2096 XmVaPUSHBUTTON, s_d1, '1', NULL, NULL,
2097 XmVaPUSHBUTTON, s_d2, '2', NULL, NULL,
2098 XmVaPUSHBUTTON, s_d3, '3', NULL, NULL,
2099 XmVaPUSHBUTTON, s_d4, '4', NULL, NULL,
2100 XmVaPUSHBUTTON, s_d5, '5', NULL, NULL,
2101 XmVaPUSHBUTTON, s_d6, '6', NULL, NULL,
2102 XmVaPUSHBUTTON, s_d7, '7', NULL, NULL,
2103 XmVaPUSHBUTTON, s_d8, '8', NULL, NULL,
2104 NULL);
2105 XmStringFree(s_d1);
2106 XmStringFree(s_d2);
2107 XmStringFree(s_d3);
2108 XmStringFree(s_d4);
2109 XmStringFree(s_d5);
2110 XmStringFree(s_d6);
2111 XmStringFree(s_d7);
2112 XmStringFree(s_d8);
2113
2114 drawing_area = XtVaCreateManagedWidget("Canvas",
2115 xmDrawingAreaWidgetClass, main_w,
2116 XmNunitType, XmPIXELS,
2117 XmNheight, window_height,
2118 XmNwidth, window_width,
2119 XmNresizePolicy, XmNONE,
2120 NULL);
2121
2122 XtAddEventHandler(drawing_area,
2123 KeyPressMask | KeyReleaseMask | VisibilityChangeMask | FocusChangeMask, /* mmm */
2124 False,
2125 motif_keypress, NULL);
2126
2127 XtAddEventHandler(drawing_area,
2128 ExposureMask,
2129 False,
2130 motif_exposure, NULL);
2131
2132 XtRealizeWidget(toplevel);
2133 }
2134
2135 display = XtDisplay(drawing_area);
2136
2137 window = XtWindow(drawing_area);
2138
2139 screen = XDefaultScreenOfDisplay(display);
2140 if (!screen) {
2141 printf("Unable to get screen\n");
2142 exit(1);
2143 }
2144 visual = XDefaultVisualOfScreen(screen);
2145 if (!visual) {
2146 printf("Unable to get visual\n");
2147 exit(1);
2148 }
2149 depth = XDefaultDepthOfScreen(screen);
2150 cmap = XDefaultColormapOfScreen(screen);
2151 #endif /* MOTIF */
2152
2153 #if !defined(XVIEW) && !defined(MOTIF)
2154 display = XOpenDisplay(NULL);
2155 if (!display) {
2156 printf("Failed to open display\n");
2157 exit(1);
2158 }
2159 screen = XDefaultScreenOfDisplay(display);
2160 if (!screen) {
2161 printf("Unable to get screen\n");
2162 exit(1);
2163 }
2164 visual = XDefaultVisualOfScreen(screen);
2165 if (!visual) {
2166 printf("Unable to get visual\n");
2167 exit(1);
2168 }
2169 depth = XDefaultDepthOfScreen(screen);
2170
2171 if (private_cmap)
2172 cmap = XCreateColormap(display,
2173 XRootWindowOfScreen(screen),
2174 visual,
2175 AllocNone);
2176 else
2177 cmap = XDefaultColormapOfScreen(screen);
2178
2179 xswda.event_mask = KeyPressMask | KeyReleaseMask | ExposureMask | VisibilityChangeMask | FocusChangeMask /* mmm */;
2180 xswda.colormap = cmap;
2181
2182 window = XCreateWindow(display,
2183 XRootWindowOfScreen(screen),
2184 50, 50,
2185 window_width, window_height, 3, depth,
2186 InputOutput, visual,
2187 CWEventMask | CWBackPixel | CWColormap,
2188 &xswda);
2189
2190 XStoreName(display, window, Atari800_TITLE);
2191 #endif /* !defined(XVIEW) && !defined(MOTIF) */
2192
2193 #ifdef SHM
2194 {
2195 int major;
2196 int minor;
2197 Bool pixmaps;
2198 Status status;
2199 int shmsize;
2200
2201 status = XShmQueryVersion(display, &major, &minor, &pixmaps);
2202 if (!status) {
2203 printf("X Shared Memory extensions not available\n");
2204 exit(1);
2205 }
2206 printf("Using X11 Shared Memory Extensions\n");
2207
2208 image = XShmCreateImage(display, visual, depth, ZPixmap,
2209 NULL, &shminfo, window_width, window_height);
2210 shmsize = (window_width * window_height *
2211 image->bits_per_pixel) / 8;
2212
2213 shminfo.shmid = shmget(IPC_PRIVATE, shmsize, IPC_CREAT | 0777);
2214 shminfo.shmaddr = image->data = shmat(shminfo.shmid, 0, 0);
2215 shminfo.readOnly = False;
2216
2217 XShmAttach(display, &shminfo);
2218
2219 XSync(display, False);
2220
2221 shmctl(shminfo.shmid, IPC_RMID, 0);
2222
2223 }
2224 #else
2225 pixmap = XCreatePixmap(display, window,
2226 window_width, window_height, depth);
2227 #endif /* SHM */
2228
2229 if (depth <= 8)
2230 colorstep = 2;
2231 else
2232 colorstep = 1;
2233 for (i = 0; i < 256; i += colorstep) {
2234 XColor colour;
2235
2236 int rgb = Colours_table[i];
2237 int status;
2238
2239 colour.red = (rgb & 0x00ff0000) >> 8;
2240 colour.green = (rgb & 0x0000ff00);
2241 colour.blue = (rgb & 0x000000ff) << 8;
2242
2243 status = XAllocColor(display,
2244 cmap,
2245 &colour);
2246
2247 for (j = 0; j < colorstep; j++)
2248 colours[i + j] = colour.pixel;
2249
2250 #ifdef SHM
2251 #ifdef USE_COLOUR_TRANSLATION_TABLE
2252 for (j = 0; j < colorstep; j++)
2253 colour_translation_table[i + j] = colours[i + j] | (colours[i + j] << 8);
2254 #endif
2255 #endif
2256 }
2257
2258 for (i = 0; i < 256; i++) {
2259 xgcvl.background = colours[0];
2260 xgcvl.foreground = colours[i];
2261
2262 gc_colour[i] = XCreateGC(display, window,
2263 GCForeground | GCBackground,
2264 &xgcvl);
2265 }
2266
2267 xgcvl.background = colours[0];
2268 xgcvl.foreground = colours[0];
2269
2270 gc = XCreateGC(display, window,
2271 GCForeground | GCBackground,
2272 &xgcvl);
2273
2274 #ifndef SHM
2275 XFillRectangle(display, pixmap, gc, 0, 0,
2276 window_width, window_height);
2277 for (i = 0; i < NRECTS; i++)
2278 rectangles[i].height = (windowsize == Huge) ? 3 : 2;
2279 #endif
2280
2281 XMapWindow(display, window);
2282
2283 XSync(display, False);
2284 autorepeat_get();
2285
2286 /*
2287 ============================
2288 Storage for Atari 800 Screen
2289 ============================
2290 */
2291 image_data = (UBYTE *) Util_malloc(Screen_WIDTH * Screen_HEIGHT);
2292
2293 keyboard_consol = INPUT_CONSOL_NONE;
2294
2295 if (x11bug) {
2296 printf("Initial X11 controller configuration\n");
2297 printf("------------------------------------\n\n");
2298 printf("Keypad is ");
2299 Atari_WhatIs(keypad_mode);
2300 printf("\n");
2301 printf("Mouse is ");
2302 Atari_WhatIs(xmouse_mode);
2303 printf("\n");
2304 printf("/dev/js0 is ");
2305 Atari_WhatIs(js0_mode);
2306 printf("\n");
2307 printf("/dev/js1 is ");
2308 Atari_WhatIs(js1_mode);
2309 printf("\n");
2310 }
2311 signal(SIGSEGV, segmentationfault);
2312
2313 return TRUE;
2314 }
2315
PLATFORM_Exit(int run_monitor)2316 int PLATFORM_Exit(int run_monitor)
2317 {
2318 int restart;
2319
2320 Log_flushlog();
2321 if (run_monitor) {
2322 autorepeat_restore();
2323 restart = MONITOR_Run();
2324 autorepeat_off();
2325 }
2326 else
2327 restart = FALSE;
2328
2329 if (!restart) {
2330 if (image_data != NULL)
2331 free(image_data);
2332
2333 if (display != NULL) {
2334 XSync(display, True);
2335
2336 if (private_cmap)
2337 XFreeColormap(display, cmap);
2338
2339 #ifdef SHM
2340 if (image != NULL)
2341 XDestroyImage(image);
2342 #else
2343 XFreePixmap(display, pixmap);
2344 #endif
2345 XUnmapWindow(display, window);
2346 XDestroyWindow(display, window);
2347 autorepeat_restore();
2348 XCloseDisplay(display);
2349 }
2350
2351 #ifdef LINUX_JOYSTICK
2352 if (js0 != -1)
2353 close(js0);
2354
2355 if (js1 != -1)
2356 close(js1);
2357 #endif
2358
2359 }
2360 return restart;
2361 }
2362
PLATFORM_DisplayScreen(void)2363 void PLATFORM_DisplayScreen(void)
2364 {
2365 static char status_line[64];
2366 int update_status_line = FALSE;
2367
2368 if (!invisible) {
2369 const UBYTE *ptr2 = (const UBYTE *) Screen_atari + clipping_y * Screen_WIDTH + clipping_x;
2370
2371 #ifdef SHM
2372
2373 int first_x = Screen_WIDTH;
2374 int last_x = -1000;
2375 int first_y = Screen_HEIGHT;
2376 int last_y = -1000;
2377 int x;
2378 int y;
2379
2380 #define SHM_SET_LAST \
2381 last_y = y; \
2382 if (x > last_x) \
2383 last_x = x; \
2384 if (x < first_x) \
2385 first_x = x;
2386
2387 #define SHM_DISPLAY_SCREEN(pixel_type) \
2388 pixel_type *ptr = (pixel_type *) image->data; \
2389 pixel_type help_color; \
2390 if (windowsize == Small) { \
2391 for (y = clipping_y; y < (clipping_y + clipping_height); y++) { \
2392 for (x = clipping_x; x < (clipping_x + clipping_width); x++) { \
2393 help_color = colours[*ptr2++]; \
2394 if (help_color != *ptr) { \
2395 SHM_SET_LAST \
2396 *ptr = help_color; \
2397 } \
2398 ptr++; \
2399 } \
2400 if (first_y > last_y && last_y >= 0) \
2401 first_y = last_y; \
2402 ptr2 += Screen_WIDTH - clipping_width; \
2403 } \
2404 } \
2405 else if (windowsize == Large) { \
2406 for (y = clipping_y; y < (clipping_y + clipping_height); y++) { \
2407 pixel_type *ptr_second_line = ptr + window_width; \
2408 for (x = clipping_x; x < (clipping_x + clipping_width); x++) { \
2409 help_color = colours[*ptr2++]; \
2410 if (help_color != *ptr) { \
2411 SHM_SET_LAST \
2412 ptr[0] = help_color; \
2413 ptr[1] = help_color; \
2414 ptr_second_line[0] = help_color; \
2415 ptr_second_line[1] = help_color; \
2416 } \
2417 ptr += 2; \
2418 ptr_second_line += 2; \
2419 } \
2420 if (first_y > last_y && last_y >= 0) \
2421 first_y = last_y; \
2422 ptr2 += Screen_WIDTH - clipping_width; \
2423 ptr += window_width; \
2424 } \
2425 } \
2426 else { \
2427 for (y = clipping_y; y < (clipping_y + clipping_height); y++) { \
2428 pixel_type *ptr_second_line = ptr + window_width; \
2429 pixel_type *ptr_third_line = ptr + window_width + window_width; \
2430 for (x = clipping_x; x < (clipping_x + clipping_width); x++) { \
2431 help_color = colours[*ptr2++]; \
2432 if (help_color != *ptr) { \
2433 SHM_SET_LAST \
2434 ptr[0] = help_color; \
2435 ptr[1] = help_color; \
2436 ptr[2] = help_color; \
2437 ptr_second_line[0] = help_color; \
2438 ptr_second_line[1] = help_color; \
2439 ptr_second_line[2] = help_color; \
2440 ptr_third_line[0] = help_color; \
2441 ptr_third_line[1] = help_color; \
2442 ptr_third_line[2] = help_color; \
2443 } \
2444 ptr += 3; \
2445 ptr_second_line += 3; \
2446 ptr_third_line += 3; \
2447 } \
2448 if (first_y > last_y && last_y >= 0) \
2449 first_y = last_y; \
2450 ptr2 += Screen_WIDTH - clipping_width; \
2451 ptr += window_width + window_width; \
2452 } \
2453 }
2454
2455 if (image->bits_per_pixel == 32) {
2456 SHM_DISPLAY_SCREEN(ULONG)
2457 }
2458 else if (image->bits_per_pixel == 16) {
2459 SHM_DISPLAY_SCREEN(UWORD)
2460 }
2461 else if (image->bits_per_pixel == 8) {
2462 SHM_DISPLAY_SCREEN(UBYTE)
2463 }
2464
2465 if (modified) {
2466 XShmPutImage(display, window, gc, image, 0, 0, 0, 0,
2467 window_width, window_height, 0);
2468 modified = FALSE;
2469 }
2470 else if (last_y >= 0) {
2471 last_x++;
2472 last_y++;
2473 if (first_x < clipping_x)
2474 first_x = clipping_x;
2475 if (last_x > clipping_x + clipping_width)
2476 last_x = clipping_x + clipping_width;
2477 else if (last_x <= first_x)
2478 last_x = first_x + 1;
2479 if (first_y < clipping_y)
2480 first_y = clipping_y;
2481 if (last_y > clipping_y + clipping_height)
2482 last_y = clipping_y + clipping_height;
2483 else if (last_y <= first_y)
2484 last_y = first_y + 1;
2485
2486 first_x *= clipping_factor;
2487 last_x *= clipping_factor;
2488 first_y *= clipping_factor;
2489 last_y *= clipping_factor;
2490
2491 XShmPutImage(display, window, gc, image,
2492 first_x - (clipping_x * clipping_factor),
2493 first_y - (clipping_y * clipping_factor),
2494 first_x - (clipping_x * clipping_factor),
2495 first_y - (clipping_y * clipping_factor),
2496 last_x - first_x, last_y - first_y, 0);
2497 }
2498
2499 XSync(display, FALSE);
2500
2501 #else /* SHM */
2502
2503 UBYTE *ptr = image_data + clipping_y * Screen_WIDTH + clipping_x;
2504 int n = 0;
2505 int last_colour = -1;
2506 int x;
2507 int y;
2508
2509 switch (windowsize) {
2510 case Small:
2511 for (y = 0; y < clipping_height; y++) {
2512 for (x = 0; x < clipping_width; x++) {
2513 UBYTE colour = *ptr2++;
2514 if (colour != *ptr) {
2515 *ptr = colour;
2516 if (colour != last_colour || n >= NPOINTS) {
2517 if (n > 0) {
2518 XDrawPoints(display, pixmap, gc_colour[last_colour],
2519 points, n, CoordModeOrigin);
2520 n = 0;
2521 modified = TRUE;
2522 }
2523 last_colour = colour;
2524 }
2525 points[n].x = x;
2526 points[n].y = y;
2527 n++;
2528 }
2529 ptr++;
2530 }
2531 ptr += Screen_WIDTH - clipping_width;
2532 ptr2 += Screen_WIDTH - clipping_width;
2533 }
2534 if (n > 0) {
2535 XDrawPoints(display, pixmap, gc_colour[last_colour],
2536 points, n, CoordModeOrigin);
2537 modified = TRUE;
2538 }
2539 break;
2540 case Large:
2541 for (y = 0; y < window_height; y += 2) {
2542 for (x = 0; x < window_width; ) {
2543 UBYTE colour = *ptr2++;
2544 if (colour != *ptr) {
2545 int width = 2;
2546 *ptr++ = colour;
2547 if (colour != last_colour || n >= NRECTS) {
2548 if (n > 0) {
2549 XFillRectangles(display, pixmap, gc_colour[last_colour],
2550 rectangles, n);
2551 n = 0;
2552 modified = TRUE;
2553 }
2554 last_colour = colour;
2555 }
2556 rectangles[n].x = x;
2557 rectangles[n].y = y;
2558 while ((x += 2) < window_width && colour == *ptr2 && colour != *ptr) {
2559 width += 2;
2560 ptr2++;
2561 *ptr++ = colour;
2562 }
2563 rectangles[n].width = width;
2564 /* rectangles[n].height = 2; */
2565 n++;
2566 continue;
2567 }
2568 ptr++;
2569 x += 2;
2570 }
2571 ptr += Screen_WIDTH - clipping_width;
2572 ptr2 += Screen_WIDTH - clipping_width;
2573 }
2574 if (n > 0) {
2575 XFillRectangles(display, pixmap, gc_colour[last_colour],
2576 rectangles, n);
2577 modified = TRUE;
2578 }
2579 break;
2580 case Huge:
2581 for (y = 0; y < window_height; y += 3) {
2582 for (x = 0; x < window_width; ) {
2583 UBYTE colour = *ptr2++;
2584 if (colour != *ptr) {
2585 int width = 3;
2586 *ptr++ = colour;
2587 if (colour != last_colour || n >= NRECTS) {
2588 if (n > 0) {
2589 XFillRectangles(display, pixmap, gc_colour[last_colour],
2590 rectangles, n);
2591 n = 0;
2592 modified = TRUE;
2593 }
2594 last_colour = colour;
2595 }
2596 rectangles[n].x = x;
2597 rectangles[n].y = y;
2598 while ((x += 3) < window_width && colour == *ptr2 && colour != *ptr) {
2599 width += 3;
2600 ptr2++;
2601 *ptr++ = colour;
2602 }
2603 rectangles[n].width = width;
2604 /* rectangles[n].height = 3; */
2605 n++;
2606 continue;
2607 }
2608 ptr++;
2609 x += 3;
2610 }
2611 ptr2 += Screen_WIDTH - clipping_width;
2612 ptr += Screen_WIDTH - clipping_width;
2613 }
2614 if (n > 0) {
2615 XFillRectangles(display, pixmap, gc_colour[last_colour],
2616 rectangles, n);
2617 modified = TRUE;
2618 }
2619 break;
2620 }
2621
2622 if (modified) {
2623 XCopyArea(display, pixmap, window, gc, 0, 0,
2624 window_width, window_height, 0, 0);
2625 XSync(display, FALSE);
2626 modified = FALSE;
2627 }
2628
2629 #endif /* SHM */
2630
2631 }
2632
2633 switch (x11_monitor) {
2634 case MONITOR_SIO:
2635 if (SIO_status[0] != '\0') {
2636 #ifdef XVIEW
2637 strcpy(status_line, SIO_status);
2638 #else
2639 sprintf(status_line, "%s - %s",
2640 Atari800_TITLE, SIO_status);
2641 #endif
2642 SIO_status[0] = '\0';
2643 update_status_line = TRUE;
2644 }
2645 else {
2646 update_status_line = FALSE;
2647 }
2648 break;
2649 default:
2650 update_status_line = FALSE;
2651 break;
2652 }
2653
2654 if (update_status_line) {
2655 #ifdef XVIEW
2656 xv_set(frame,
2657 FRAME_LEFT_FOOTER, status_line,
2658 NULL);
2659 #else
2660 #ifdef MOTIF
2661 XtVaSetValues(toplevel,
2662 XtNtitle, status_line,
2663 NULL);
2664 #else
2665 XStoreName(display, window, status_line);
2666 #endif
2667 #endif
2668 }
2669
2670 }
2671
PLATFORM_Keyboard(void)2672 int PLATFORM_Keyboard(void)
2673 {
2674 static int keycode = AKEY_NONE;
2675
2676 #ifdef XVIEW
2677 notify_dispatch();
2678 XFlush(display);
2679 #endif
2680
2681 #ifdef MOTIF
2682 while (XtAppPending(app)) {
2683 static XEvent event;
2684
2685 XtAppNextEvent(app, &event);
2686 XtDispatchEvent(&event);
2687 }
2688 #endif
2689
2690 #if defined(XVIEW) || defined(MOTIF)
2691 keycode = xview_keycode;
2692 #else
2693 if (XEventsQueued(display, QueuedAfterFlush) > 0) {
2694 XEvent event;
2695
2696 XNextEvent(display, &event);
2697 keycode = GetKeyCode(&event);
2698 }
2699 #endif
2700
2701 return keycode;
2702 }
2703
2704 #if 0
2705 void experimental_mouse_joystick(int mode) /* Don't use ;-) */
2706 {
2707 Window root_return;
2708 Window child_return;
2709 int root_x_return;
2710 int root_y_return;
2711 int win_x_return;
2712 int win_y_return;
2713 int mask_return;
2714
2715 static int prev_x=-1,prev_y=-1;
2716
2717 XQueryPointer(display, window, &root_return, &child_return,
2718 &root_x_return, &root_y_return,
2719 &win_x_return, &win_y_return,
2720 &mask_return);
2721
2722 if (mode < 5) {
2723 int dx,dy;
2724 int course,rc;
2725
2726 if( prev_x<0 ) prev_x=root_x_return;
2727 if( prev_y<0 ) prev_y=root_y_return;
2728 dx=(root_x_return-prev_x)<<1;
2729 dy=(root_y_return-prev_y)*3;
2730 #define Ms 8
2731 #define Mc 3 /* Mc/Mm = 2 45 deg. <2 => >45 deg for x or y only */
2732 #define Mm 2
2733 if( dx>Ms && dy>Ms )
2734 { if( dx*Mm>Mc*dy )
2735 course = 0x08; /* RIGHT */
2736 else if ( dx*Mc<dy*Mm )
2737 course = 0x02; /* DOWN */
2738 else course = 0x0a; /* RIGHT DOWN */
2739 } else if( dx<-Ms && dy<-Ms )
2740 { if( dx*Mm<Mc*dy )
2741 course = 0x04; /* LEFT */
2742 else if ( dx*Mc>dy*Mm )
2743 course = 0x01; /* UP */
2744 else course = 0x05; /* LEFT UP */
2745 } else if( dx<-Ms && dy>Ms )
2746 { if( -dx*Mm>Mc*dy )
2747 course = 0x04; /* LEFT */
2748 else if ( -dx*Mc<dy*Mm )
2749 course = 0x02; /* DOWN */
2750 else course = 0x06; /* LEFT DOWN */
2751 } else if( dx>Ms && dy<-Ms )
2752 { if( -dx*Mm<Mc*dy )
2753 course = 0x08; /* RIGHT */
2754 else if ( -dx*Mc>dy*Mm )
2755 course = 0x01; /* UP */
2756 else course = 0x09; /* RIGHT UP */
2757 }
2758 else if( dx>Ms )
2759 course = 0x08; /* RIGHT */
2760 else if( dx<-Ms )
2761 course = 0x04; /* LEFT */
2762 else if( dy>Ms )
2763 course = 0x02; /* DOWN */
2764 else if( dy<-Ms )
2765 course = 0x01; /* UP */
2766 else course=0;
2767
2768 rc=(((course&0x5)<<1)|((course&0xa)>>1));
2769 rc&= ~mouse_stick;
2770 mouse_stick|=rc;
2771 course&=~(((rc&0x5)<<1)|((rc&0xa)>>1));
2772 mouse_stick&=~course;
2773
2774 prev_x=root_x_return;
2775 prev_y=root_y_return;
2776 }
2777 else {
2778 if (mask_return)
2779 mouse_stick &= 0xfb;
2780 }
2781 }
2782 #endif
2783
mouse_joystick(int mode)2784 static void mouse_joystick(int mode)
2785 {
2786 Window root_return;
2787 Window child_return;
2788 int root_x_return;
2789 int root_y_return;
2790 int win_x_return;
2791 int win_y_return;
2792 unsigned int mask_return;
2793
2794 mouse_stick = 0x0f;
2795
2796 XQueryPointer(display, window, &root_return, &child_return,
2797 &root_x_return, &root_y_return,
2798 &win_x_return, &win_y_return,
2799 &mask_return);
2800
2801 if (mode < 5) {
2802 int center_x;
2803 int center_y;
2804 int threshold;
2805
2806 if (windowsize == Small) {
2807 center_x = window_width / 2;
2808 center_y = window_height / 2;
2809 threshold = 32;
2810 }
2811 else if (windowsize == Large) {
2812 center_x = window_width / 2;
2813 center_y = window_height / 2;
2814 threshold = 64;
2815 }
2816 else {
2817 center_x = window_width / 2;
2818 center_y = window_height / 2;
2819 threshold = 96;
2820 }
2821
2822 if (win_x_return < 0 || win_x_return > center_x * 2 ||
2823 win_y_return < 0 || win_y_return > center_y * 2 )
2824 mouse_stick = 0x0f;
2825 else
2826 {
2827 if (win_x_return < (center_x - threshold))
2828 mouse_stick &= 0xfb;
2829 if (win_x_return > (center_x + threshold))
2830 mouse_stick &= 0xf7;
2831 if (win_y_return < (center_y - threshold))
2832 mouse_stick &= 0xfe;
2833 if (win_y_return > (center_y + threshold))
2834 mouse_stick &= 0xfd;
2835 }
2836 }
2837 else {
2838 if (mask_return)
2839 mouse_stick &= 0xfb;
2840 }
2841 }
2842
2843 #ifdef LINUX_JOYSTICK
2844
read_joystick(int js,int centre_x,int centre_y)2845 static void read_joystick(int js, int centre_x, int centre_y)
2846 {
2847 const int threshold = 50;
2848 int status;
2849
2850 mouse_stick = 0x0f;
2851
2852 status = read(js, &js_data, JS_RETURN);
2853 if (status != JS_RETURN) {
2854 perror("/dev/js");
2855 exit(1);
2856 }
2857 if (js_data.x < (centre_x - threshold))
2858 mouse_stick &= 0xfb;
2859 if (js_data.x > (centre_x + threshold))
2860 mouse_stick &= 0xf7;
2861 if (js_data.y < (centre_y - threshold))
2862 mouse_stick &= 0xfe;
2863 if (js_data.y > (centre_y + threshold))
2864 mouse_stick &= 0xfd;
2865 }
2866 #endif
2867
PLATFORM_PORT(int num)2868 int PLATFORM_PORT(int num)
2869 {
2870 int nibble_0 = 0x0f;
2871 int nibble_1 = 0x0f;
2872
2873 if (num == 0) {
2874 if (keypad_mode == 0)
2875 nibble_0 = keypad_stick;
2876 else if (keypad_mode == 1)
2877 nibble_1 = keypad_stick;
2878
2879 if (INPUT_mouse_mode == INPUT_MOUSE_OFF) {
2880 if (xmouse_mode == 0) {
2881 mouse_joystick(xmouse_mode);
2882 nibble_0 = mouse_stick;
2883 }
2884 else if (xmouse_mode == 1) {
2885 mouse_joystick(xmouse_mode);
2886 nibble_1 = mouse_stick;
2887 }
2888 }
2889 #ifdef LINUX_JOYSTICK
2890 if (js0_mode == 0) {
2891 read_joystick(js0, js0_centre_x, js0_centre_y);
2892 nibble_0 = mouse_stick;
2893 }
2894 else if (js0_mode == 1) {
2895 read_joystick(js0, js0_centre_x, js0_centre_y);
2896 nibble_1 = mouse_stick;
2897 }
2898 if (js1_mode == 0) {
2899 read_joystick(js1, js1_centre_x, js1_centre_y);
2900 nibble_0 = mouse_stick;
2901 }
2902 else if (js1_mode == 1) {
2903 read_joystick(js1, js1_centre_x, js1_centre_y);
2904 nibble_1 = mouse_stick;
2905 }
2906 #endif
2907 }
2908 else {
2909 if (keypad_mode == 2)
2910 nibble_0 = keypad_stick;
2911 else if (keypad_mode == 3)
2912 nibble_1 = keypad_stick;
2913
2914 if (INPUT_mouse_mode == INPUT_MOUSE_OFF) {
2915 if (xmouse_mode == 2) {
2916 mouse_joystick(xmouse_mode);
2917 nibble_0 = mouse_stick;
2918 }
2919 else if (xmouse_mode == 3) {
2920 mouse_joystick(xmouse_mode);
2921 nibble_1 = mouse_stick;
2922 }
2923 }
2924
2925 #ifdef LINUX_JOYSTICK
2926 if (js0_mode == 2) {
2927 read_joystick(js0, js0_centre_x, js0_centre_y);
2928 nibble_0 = mouse_stick;
2929 }
2930 else if (js0_mode == 3) {
2931 read_joystick(js0, js0_centre_x, js0_centre_y);
2932 nibble_1 = mouse_stick;
2933 }
2934 if (js1_mode == 2) {
2935 read_joystick(js1, js1_centre_x, js1_centre_y);
2936 nibble_0 = mouse_stick;
2937 }
2938 else if (js1_mode == 3) {
2939 read_joystick(js1, js1_centre_x, js1_centre_y);
2940 nibble_1 = mouse_stick;
2941 }
2942 #endif
2943 }
2944
2945 return (nibble_1 << 4) | nibble_0;
2946 }
2947
PLATFORM_TRIG(int num)2948 int PLATFORM_TRIG(int num)
2949 {
2950 int trig = 1; /* Trigger not pressed */
2951
2952 if (num == keypad_mode) {
2953 trig = keypad_trig;
2954 }
2955 if (num == xmouse_mode) {
2956 Window root_return;
2957 Window child_return;
2958 int root_x_return;
2959 int root_y_return;
2960 int win_x_return;
2961 int win_y_return;
2962 unsigned int mask_return;
2963
2964 if (XQueryPointer(display, window, &root_return, &child_return,
2965 &root_x_return, &root_y_return,
2966 &win_x_return, &win_y_return,
2967 &mask_return)) {
2968 if (win_x_return < 0 || win_x_return > window_width ||
2969 win_y_return < 0 || win_y_return > window_height)
2970 trig = 1;
2971 else if (mask_return & Button1Mask)
2972 trig = 0;
2973 }
2974 }
2975 #ifdef LINUX_JOYSTICK
2976 if (num == js0_mode) {
2977 int status;
2978
2979 status = read(js0, &js_data, JS_RETURN);
2980 if (status != JS_RETURN) {
2981 perror("/dev/js0");
2982 exit(1);
2983 }
2984 if (js_data.buttons & 0x01)
2985 trig = 0;
2986 else
2987 trig = 1;
2988 }
2989 if (num == js1_mode) {
2990 int status;
2991
2992 status = read(js1, &js_data, JS_RETURN);
2993 if (status != JS_RETURN) {
2994 perror("/dev/js1");
2995 exit(1);
2996 }
2997 trig = (js_data.buttons & 0x0f) ? 0 : 1;
2998 }
2999 #endif
3000
3001 return trig;
3002 }
3003
Atari_Mouse(void)3004 void Atari_Mouse(void)
3005 {
3006 static int last_x = 0;
3007 static int last_y = 0;
3008 Window root_return;
3009 Window child_return;
3010 int root_x_return;
3011 int root_y_return;
3012 int win_x_return;
3013 int win_y_return;
3014 unsigned int mask_return;
3015
3016 if (INPUT_mouse_mode == INPUT_MOUSE_OFF)
3017 return;
3018 if (XQueryPointer(display, window, &root_return,
3019 &child_return, &root_x_return, &root_y_return,
3020 &win_x_return, &win_y_return, &mask_return)) {
3021 if(INPUT_direct_mouse) {
3022 int potx = win_x_return, poty = win_y_return;
3023 if(potx < 0) potx = 0;
3024 if(poty < 0) poty = 0;
3025 potx = (double)potx * (228.0 / (double)window_width);
3026 poty = (double)poty * (228.0 / (double)window_height);
3027 if(potx > 227) potx = 227;
3028 if(poty > 227) poty = 227;
3029 POKEY_POT_input[INPUT_mouse_port << 1] = 227 - potx;
3030 POKEY_POT_input[(INPUT_mouse_port << 1) + 1] = 227 - poty;
3031 } else {
3032 INPUT_mouse_delta_x = win_x_return - last_x;
3033 INPUT_mouse_delta_y = win_y_return - last_y;
3034 last_x = win_x_return;
3035 last_y = win_y_return;
3036 }
3037
3038 INPUT_mouse_buttons = (mask_return & Button1Mask ? 1 : 0)
3039 | (mask_return & Button3Mask ? 2 : 0)
3040 | (mask_return & Button2Mask ? 4 : 0);
3041 }
3042 }
3043
main(int argc,char ** argv)3044 int main(int argc, char **argv)
3045 {
3046 /* initialise Atari800 core */
3047 if (!Atari800_Initialise(&argc, argv))
3048 return 3;
3049
3050 /* main loop */
3051 for (;;) {
3052 INPUT_key_code = PLATFORM_Keyboard();
3053
3054 if (menu_consol != INPUT_CONSOL_NONE) {
3055 INPUT_key_consol = menu_consol;
3056 menu_consol = INPUT_CONSOL_NONE;
3057 }
3058 else
3059 INPUT_key_consol = keyboard_consol;
3060
3061 Atari_Mouse();
3062
3063 Atari800_Frame();
3064 if (Atari800_display_screen)
3065 PLATFORM_DisplayScreen();
3066 }
3067 }
3068