home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 5 / MA_Cover_5.iso / ppc / atari / atari800-0.8.6 / atari_x11.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-05-10  |  60.9 KB  |  2,917 lines

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