home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Emulation / Atari800 / atari_x11.c < prev    next >
C/C++ Source or Header  |  1998-02-12  |  76KB  |  3,538 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #ifdef VMS
  4. #include <stat.h>
  5. #else
  6. #include <sys/stat.h>
  7. #endif
  8.  
  9. #include <sys/time.h>
  10. #include <unistd.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.42 1997/09/30 jhs,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. #include "mem.h"
  71.  
  72. static struct timeval tp;
  73. static struct timezone tzp;
  74.  
  75. static double basetime;
  76. /*
  77. static int nframes = 0;
  78. */
  79.  
  80. #ifdef SHM
  81. #include <sys/ipc.h>
  82. #include <sys/shm.h>
  83. #include <X11/extensions/XShm.h>
  84.  
  85. static XShmSegmentInfo shminfo;
  86. static XImage *image;
  87. extern char *atari_screen;
  88. extern int colour_translation_table[256];
  89. #endif
  90.  
  91. #ifdef LINUX_JOYSTICK
  92. #include <linux/joystick.h>
  93. #include <fcntl.h>
  94.  
  95. static int js0;
  96. static int js1;
  97.  
  98. static int js0_centre_x;
  99. static int js0_centre_y;
  100. static int js1_centre_x;
  101. static int js1_centre_y;
  102.  
  103. static struct JS_DATA_TYPE js_data;
  104. #endif
  105.  
  106. #define    FALSE    0
  107. #define    TRUE    1
  108.  
  109. typedef enum
  110. {
  111.   Small,
  112.   Large,
  113.   Huge
  114. } WindowSize;
  115.  
  116. static WindowSize windowsize = Large;
  117.  
  118. enum
  119. {
  120.   MONITOR_NOTHING,
  121.   MONITOR_FPS,
  122.   MONITOR_SIO
  123. } x11_monitor = MONITOR_NOTHING;
  124.  
  125. static int x11bug = FALSE;
  126.  
  127. static int private_cmap = FALSE;    /* If TRUE, allocate own cmap,
  128.                        otherwise cmap == defcmap */
  129. static Colormap defcmap;        /* Default of Screen */
  130. static Colormap cmap;            /* The cmap we actually use */
  131.  
  132. static int window_width;
  133. static int window_height;
  134.  
  135. static Display    *display;
  136. static Screen    *screen;
  137. static Window    window;
  138. #ifndef SHM
  139. static Pixmap    pixmap;
  140. #endif
  141. static Visual    *visual;
  142.  
  143. static GC gc;
  144. static GC gc_colour[256];
  145. static int colours[256];
  146.  
  147. /*static XComposeStatus    keyboard_status;*/
  148.  
  149. #ifdef XVIEW
  150. static Frame frame;
  151. static Panel panel;
  152. static Canvas canvas;
  153. static Menu system_menu;
  154. static Menu coldstart_menu;
  155. static Menu consol_menu;
  156. static Menu options_menu;
  157. static Frame chooser;
  158.  
  159. static Frame controllers_frame;
  160. static Panel controllers_panel;
  161. static Panel_item keypad_item;
  162. static Panel_item mouse_item;
  163.  
  164. #ifdef LINUX_JOYSTICK
  165. static Panel_item js0_item;
  166. static Panel_item js1_item;
  167. #endif
  168.  
  169. static Frame performance_frame;
  170. static Panel performance_panel;
  171. static Panel_item refresh_slider;
  172. #endif
  173.  
  174.  
  175.  
  176. static int NUMLOCKMASK    = Mod2Mask;    /* preliminary */
  177. /* Should try to find out with XGetModifierMapping */
  178.  
  179.  
  180. #define IsShifted(event)    (!!((event)->xkey.state & ShiftMask))
  181. #define SHIFT(event)    (IsShifted(event) ? AKEY_SHFT : 0)
  182. #define CONTROL(event)    (((event)->xkey.state & ControlMask) ? AKEY_CTRL : 0)
  183. #define IsNumlocked(event)    (!!((event)->xkey.state & NUMLOCKMASK))
  184.  
  185.  
  186. static int SHIFTPRESSED =0;
  187. static int KEYPRESSED =0;
  188. static int XTERNAUTOREPEAT=1;    /* At program-start, is autorepeat set? */
  189. static int XCURRENTAUTOREPEAT=1; /* is autorepeat currently set? */
  190.  
  191.  
  192. static int    paused=0;
  193. static UBYTE    *image_data;
  194. static int    modified;
  195.  
  196. static int keypad_mode = -1; /* Joystick */
  197. static int keypad_trig = 1; /* Keypad Trigger Position */
  198. /* static int keypad_stick = 0x0f;  * Keypad Joystick Position, now function */
  199.  
  200.  
  201.     /* These are the specific keys currently pressed */
  202.     /* The scheme is from xkobo, which has great keypad control */
  203. static int keypad_dl =0;
  204. static int keypad_d =0;
  205. static int keypad_dr =0;
  206. static int keypad_l =0;
  207. static int keypad_r =0;
  208. static int keypad_ul =0;
  209. static int keypad_u =0;
  210. static int keypad_ur =0;
  211.  
  212. static int keypad_changed=1;    /* one of the values above has changed */
  213.  
  214.  
  215. static int mouse_mode = -1; /* Joystick, Paddle and Light Pen */
  216. static int mouse_stick; /* Mouse Joystick Position */
  217.  
  218. static int js0_mode = -1;
  219. static int js1_mode = -1;
  220.  
  221. static int    last_colour = -1;
  222.  
  223. #define    NPOINTS    (4096/4)
  224. #define    NRECTS    (4096/4)
  225.  
  226.  
  227. /*
  228. static int    nrects = 0;
  229. */
  230. static int    npoints = 0;
  231.  
  232. static XPoint        points[NPOINTS];
  233. static XRectangle    rectangles[NRECTS];
  234.  
  235. static int keyboard_consol;
  236. static int menu_consol;
  237. static int screen_dump = 0;
  238.  
  239. /*
  240.    ==========================================
  241.    Import a few variables from atari_custom.c
  242.    ==========================================
  243. */
  244.  
  245. extern int refresh_rate;
  246.  
  247. int GetKeyCode (XEvent *event)
  248. {
  249.   KeySym keysym = NoSymbol;
  250.   int keycode = AKEY_NONE;
  251.  
  252.   /* OLD, and slow:
  253.   char buffer[128];
  254.         XLookupString ((XKeyEvent*)event, buffer, 128,
  255.          &keysym, &keyboard_status);  */
  256.  
  257.  
  258.   switch (event->type)
  259.     {
  260.     case Expose :
  261. #ifndef SHM
  262.       XCopyArea (display, pixmap, window, gc,
  263.          0, 0,
  264.          window_width, window_height,
  265.          0, 0);
  266. #endif
  267.       break;
  268.     case KeyPress :
  269.       keysym = XLookupKeysym((XKeyEvent*)event, IsShifted(event));
  270.       switch (keysym)
  271.     {
  272.     case XK_Shift_L :
  273.     case XK_Shift_R :
  274.             /* not quite correct to use Shift here, I SHOULD
  275.                look up the XModMap.  But then I couldnt do
  276.                a switch - case. */
  277.         SHIFTPRESSED=1;            /* Pokey register */
  278.         break;
  279.     case XK_Control_L :
  280.     case XK_Control_R :
  281.       break;
  282.     case XK_Caps_Lock :
  283.       if (IsShifted(event))    
  284.         keycode = CONTROL(event) | AKEY_CAPSLOCK;
  285.       else
  286.         keycode = CONTROL(event) | AKEY_CAPSTOGGLE;
  287.       break;
  288.     case XK_Shift_Lock :
  289.       if (x11bug)
  290.         printf ("XK_Shift_Lock\n");
  291.       break;
  292.     case XK_Alt_L :
  293.     case XK_Alt_R :
  294.       keycode = AKEY_ATARI;
  295.       break;
  296.     case XK_F1 :
  297.           keycode = AKEY_UI;
  298.       break;
  299.     case XK_F2 :
  300.       keyboard_consol &= 0x03;
  301.       keycode = AKEY_NONE;
  302.       break;
  303.     case XK_F3 :
  304.       keyboard_consol &= 0x05;
  305.       keycode = AKEY_NONE;
  306.       break;
  307.     case XK_F4 :
  308.       keyboard_consol &= 0x6;
  309.       keycode = AKEY_NONE;
  310.       break;
  311.     case XK_F5 :
  312.       keycode = AKEY_WARMSTART;
  313.       break;
  314.     case XK_L5 :
  315.       keycode = AKEY_COLDSTART;
  316.       break;
  317.     case XK_F6 :
  318.       keycode = AKEY_PIL;
  319.       break;
  320.     case XK_F7 :
  321.       keycode = AKEY_BREAK;
  322.       break;
  323.     case XK_L8 :
  324.           screen_dump = (1 - screen_dump);
  325.           keycode = AKEY_NONE;
  326.       break;
  327.     case XK_F8 :
  328.           screen_dump = 2;
  329.           keycode = AKEY_NONE;
  330.       break;
  331.     case XK_F9 :
  332.       keycode = AKEY_EXIT;
  333.       break;
  334.     case XK_F10 :
  335.       keycode = AKEY_NONE;
  336.       break;
  337.     case XK_Pause:
  338.       keycode = AKEY_NONE;
  339.       if (!paused)
  340.           paused = 2;        /* waiting for TWO Pause releases */
  341.       break;
  342.     case XK_Home :
  343.       keycode = 0x76;
  344.       break;
  345.     case XK_Insert :
  346.       if (IsShifted(event))
  347.         keycode = AKEY_INSERT_LINE;
  348.       else
  349.         keycode = AKEY_INSERT_CHAR;
  350.       break;
  351.     case XK_BackSpace :
  352.       if (CONTROL(event))
  353.         keycode = AKEY_DELETE_CHAR;
  354.       else if (IsShifted(event))
  355.         keycode = AKEY_DELETE_LINE;
  356.       else
  357.         keycode = AKEY_BACKSPACE;
  358.       break;
  359.     case XK_Delete :
  360.       if (CONTROL(event))
  361.         keycode = AKEY_DELETE_CHAR;
  362.       else if (IsShifted(event))
  363.         keycode = AKEY_DELETE_LINE;
  364.       else
  365.         keycode = AKEY_BACKSPACE;
  366.       break;
  367.     case XK_Left :
  368.       keycode = AKEY_LEFT;
  369. /*      keypad_stick = STICK_LEFT;    */
  370.       break;
  371.     case XK_Up :
  372.       keycode = AKEY_UP;
  373. /*      keypad_stick = STICK_FORWARD;    */
  374.       break;
  375.     case XK_Right :
  376.       keycode = AKEY_RIGHT;
  377. /*      keypad_stick = STICK_RIGHT;    */
  378.       break;
  379.     case XK_Down :
  380.       keycode = AKEY_DOWN;
  381. /*      keypad_stick = STICK_BACK;    */
  382.       break;
  383.     case XK_Escape :
  384.       keycode = AKEY_ESCAPE;
  385.       break;
  386.     case XK_Tab :
  387.       if (CONTROL(event))
  388.         keycode = AKEY_CLRTAB;
  389.       else if (IsShifted(event))
  390.         keycode = AKEY_SETTAB;
  391.       else
  392.         keycode = AKEY_TAB;
  393.       break;
  394.     case XK_exclam :
  395.       keycode = AKEY_EXCLAMATION;
  396.       break;
  397.     case XK_quotedbl :
  398.       keycode = AKEY_DBLQUOTE;
  399.       break;
  400.     case XK_numbersign :
  401.       keycode = AKEY_HASH;
  402.       break;
  403.     case XK_dollar :
  404.       keycode = AKEY_DOLLAR;
  405.       break;
  406.     case XK_percent :
  407.       keycode = AKEY_PERCENT;
  408.       break;
  409.     case XK_ampersand :
  410.       keycode = AKEY_AMPERSAND;
  411.       break;
  412.     case XK_quoteright :
  413.       keycode = AKEY_QUOTE;
  414.       break;
  415.     case XK_at :
  416.       keycode = AKEY_AT;
  417.       break;
  418.     case XK_parenleft :
  419.       keycode = AKEY_PARENLEFT;
  420.       break;
  421.     case XK_parenright :
  422.       keycode = AKEY_PARENRIGHT;
  423.       break;
  424.     case XK_less :
  425.       keycode = AKEY_LESS;
  426.       break;
  427.     case XK_greater :
  428.       keycode = AKEY_GREATER;
  429.       break;
  430.     case XK_equal :
  431.       keycode = AKEY_EQUAL;
  432.       break;
  433.     case XK_question :
  434.       keycode = AKEY_QUESTION;
  435.       break;
  436.     case XK_minus :
  437.       keycode = AKEY_MINUS;
  438.       break;
  439.     case XK_plus :
  440.       keycode = AKEY_PLUS;
  441.       break;
  442.     case XK_asterisk :
  443.       keycode = AKEY_ASTERISK;
  444.       break;
  445.     case XK_slash :
  446.       keycode = AKEY_SLASH;
  447.       break;
  448.     case XK_colon :
  449.       keycode = AKEY_COLON;
  450.       break;
  451.     case XK_semicolon :
  452.       keycode = AKEY_SEMICOLON;
  453.       break;
  454.     case XK_comma :
  455.       keycode = AKEY_COMMA;
  456.       break;
  457.     case XK_period :
  458.       keycode = AKEY_FULLSTOP;
  459.       break;
  460.     case XK_underscore :
  461.       keycode = AKEY_UNDERSCORE;
  462.       break;
  463.     case XK_bracketleft :
  464.       keycode = AKEY_BRACKETLEFT;
  465.       break;
  466.     case XK_bracketright :
  467.       keycode = AKEY_BRACKETRIGHT;
  468.       break;
  469.     case XK_asciicircum :
  470.       keycode = AKEY_CIRCUMFLEX;
  471.       break;
  472.     case XK_backslash :
  473.       keycode = AKEY_BACKSLASH;
  474.       break;
  475.     case XK_bar :
  476.       keycode = AKEY_BAR;
  477.       break;
  478.     case XK_space :
  479.       keycode = AKEY_SPACE;
  480. /*      keypad_trig = 0;        */
  481.       break;
  482.     case XK_Return :
  483.       keycode = AKEY_RETURN;
  484. /*      keypad_stick = STICK_CENTRE;    */
  485.       break;
  486.     case XK_0 :
  487.       keycode = CONTROL(event) | AKEY_0;
  488.       break;
  489.     case XK_1 :
  490.       keycode = CONTROL(event) | AKEY_1;
  491.       break;
  492.     case XK_2 :
  493.       keycode = CONTROL(event) | AKEY_2;
  494.       break;
  495.     case XK_3 :
  496.       keycode = CONTROL(event) | AKEY_3;
  497.       break;
  498.     case XK_4 :
  499.       keycode = CONTROL(event) | AKEY_4;
  500.       break;
  501.     case XK_5 :
  502.       keycode = CONTROL(event) | AKEY_5;
  503.       break;
  504.     case XK_6 :
  505.       keycode = CONTROL(event) | AKEY_6;
  506.       break;
  507.     case XK_7 :
  508.       keycode = CONTROL(event) | AKEY_7;
  509.       break;
  510.     case XK_8 :
  511.       keycode = CONTROL(event) | AKEY_8;
  512.       break;
  513.     case XK_9 :
  514.       keycode = CONTROL(event) | AKEY_9;
  515.       break;
  516.     case XK_A : case XK_a :
  517.       keycode = SHIFT(event) | CONTROL(event) | AKEY_a;
  518.       break;
  519.     case XK_B : case XK_b :
  520.       keycode = SHIFT(event) | CONTROL(event) | AKEY_b;
  521.       break;
  522.     case XK_C : case XK_c :
  523.       keycode = SHIFT(event) | CONTROL(event) | AKEY_c;
  524.       break;
  525.     case XK_D : case XK_d :
  526.       keycode = SHIFT(event) | CONTROL(event) | AKEY_d;
  527.       break;
  528.     case XK_E : case XK_e :
  529.       keycode = SHIFT(event) | CONTROL(event) | AKEY_e;
  530.       break;
  531.     case XK_F : case XK_f :
  532.       keycode = SHIFT(event) | CONTROL(event) | AKEY_f;
  533.       break;
  534.     case XK_G : case XK_g :
  535.       keycode = SHIFT(event) | CONTROL(event) | AKEY_g;
  536.       break;
  537.     case XK_H : case XK_h :
  538.       keycode = SHIFT(event) | CONTROL(event) | AKEY_h;
  539.       break;
  540.     case XK_I : case XK_i :
  541.       keycode = SHIFT(event) | CONTROL(event) | AKEY_i;
  542.       break;
  543.     case XK_J : case XK_j :
  544.       keycode = SHIFT(event) | CONTROL(event) | AKEY_j;
  545.       break;
  546.     case XK_K : case XK_k :
  547.       keycode = SHIFT(event) | CONTROL(event) | AKEY_k;
  548.       break;
  549.     case XK_L : case XK_l :
  550.       keycode = SHIFT(event) | CONTROL(event) | AKEY_l;
  551.       break;
  552.     case XK_M : case XK_m :
  553.       keycode = SHIFT(event) | CONTROL(event) | AKEY_m;
  554.       break;
  555.     case XK_N : case XK_n :
  556.       keycode = SHIFT(event) | CONTROL(event) | AKEY_n;
  557.       break;
  558.     case XK_O : case XK_o :
  559.       keycode = SHIFT(event) | CONTROL(event) | AKEY_o;
  560.       break;
  561.     case XK_P : case XK_p :
  562.       keycode = SHIFT(event) | CONTROL(event) | AKEY_p;
  563.       break;
  564.     case XK_Q : case XK_q :
  565.       keycode = SHIFT(event) | CONTROL(event) | AKEY_q;
  566.       break;
  567.     case XK_R : case XK_r :
  568.       keycode = SHIFT(event) | CONTROL(event) | AKEY_r;
  569.       break;
  570.     case XK_S : case XK_s :
  571.       keycode = SHIFT(event) | CONTROL(event) | AKEY_s;
  572.       break;
  573.     case XK_T : case XK_t :
  574.       keycode = SHIFT(event) | CONTROL(event) | AKEY_t;
  575.       break;
  576.     case XK_U : case XK_u :
  577.       keycode = SHIFT(event) | CONTROL(event) | AKEY_u;
  578.       break;
  579.     case XK_V : case XK_v :
  580.       keycode = SHIFT(event) | CONTROL(event) | AKEY_v;
  581.       break;
  582.     case XK_W : case XK_w :
  583.       keycode = SHIFT(event) | CONTROL(event) | AKEY_w;
  584.       break;
  585.     case XK_X : case XK_x :
  586.       keycode = SHIFT(event) | CONTROL(event) | AKEY_x;
  587.       break;
  588.     case XK_Y : case XK_y :
  589.       keycode = SHIFT(event) | CONTROL(event) | AKEY_y;
  590.       break;
  591.     case XK_Z : case XK_z :
  592.       keycode = SHIFT(event) | CONTROL(event) | AKEY_z;
  593.       break;
  594.     case XK_KP_0 :
  595.     case XK_KP_Insert :
  596.       keypad_trig = 0;
  597.       break;
  598.     case XK_KP_1 :
  599.     case XK_KP_End :
  600.       keypad_dl = 1;
  601.       keypad_changed =1;
  602.       break;
  603.     case XK_KP_2 :
  604.     case XK_KP_Down:
  605.       keypad_d = 1;
  606.       keypad_changed =1;
  607.       break;
  608.     case XK_KP_3 :
  609.     case XK_KP_Next:
  610.       keypad_dr = 1;
  611.       keypad_changed =1;
  612.       break;
  613.     case XK_KP_4 :
  614.     case XK_KP_Left:
  615.       keypad_l = 1;
  616.       keypad_changed =1;
  617.       break;
  618.     case XK_KP_5 :
  619.     case XK_KP_Begin:        /* Center joystick */
  620.       keypad_dl = keypad_d = keypad_dr = keypad_l =0;
  621.       keypad_r = keypad_ul = keypad_u = keypad_ur =0;
  622.       keypad_changed =1;
  623.       break;
  624.     case XK_KP_6 :
  625.     case XK_KP_Right:
  626.       keypad_r = 1;
  627.       keypad_changed =1;
  628.       break;
  629.     case XK_KP_7 :
  630.     case XK_KP_Home:
  631.       keypad_ul = 1;
  632.       keypad_changed =1;
  633.       break;
  634.     case XK_KP_8 :
  635.     case XK_KP_Up:
  636.       keypad_u = 1;
  637.       keypad_changed =1;
  638.       break;
  639.     case XK_KP_9 :
  640.     case XK_KP_Prior:
  641.       keypad_ur = 1;
  642.       keypad_changed =1;
  643.       break;
  644.     default :
  645.       if (x11bug)
  646.         printf ("Pressed Keysym = %x\n", (int)keysym);
  647.       break;
  648.     }
  649.       if (keycode > AKEY_NONE)
  650.           KEYPRESSED=1;            /* Pokey Register */
  651.       break;
  652.     case KeyRelease :
  653.       keysym = XLookupKeysym((XKeyEvent*)event, 0);
  654.       switch (keysym)
  655.     {
  656.     case XK_Shift_L :
  657.     case XK_Shift_R :
  658.         SHIFTPRESSED=0;
  659.         break;
  660.     case XK_Control_L :
  661.     case XK_Control_R :
  662.       break;
  663.     case XK_Shift_Lock :
  664.       if (x11bug)
  665.         printf ("XK_Shift_Lock\n");
  666.       break;
  667.     case XK_Pause:
  668.       if (paused > 0)        /* safety! */
  669.         paused--;
  670.       break;
  671.     case XK_F1:
  672.     case XK_F5:
  673.     case XK_F6:
  674.     case XK_F7:
  675.     case XK_L8:
  676.     case XK_F8:
  677.     case XK_F9:
  678.     case XK_F10:
  679.       break;
  680.     case XK_F2 :
  681.     case XK_F3 :
  682.     case XK_F4 :
  683.       keyboard_consol = 0x07;
  684.           break;
  685.     case XK_KP_0 :
  686.     case XK_KP_Insert :
  687.       keypad_trig = 1;
  688.       break;
  689.     case XK_KP_1 :
  690.     case XK_KP_End :
  691.       keypad_dl = 0;
  692.       keypad_changed =1;
  693.       break;
  694.     case XK_KP_2 :
  695.     case XK_KP_Down:
  696.       keypad_d = 0;
  697.       keypad_changed =1;
  698.       break;
  699.     case XK_KP_3 :
  700.     case XK_KP_Next:
  701.       keypad_dr = 0;
  702.       keypad_changed =1;
  703.       break;
  704.     case XK_KP_4 :
  705.     case XK_KP_Left:
  706.       keypad_l = 0;
  707.       keypad_changed =1;
  708.       break;
  709.     case XK_KP_6 :
  710.     case XK_KP_Right:
  711.       keypad_r = 0;
  712.       keypad_changed =1;
  713.       break;
  714.     case XK_KP_7 :
  715.     case XK_KP_Home:
  716.       keypad_ul = 0;
  717.       keypad_changed =1;
  718.       break;
  719.     case XK_KP_8 :
  720.     case XK_KP_Up:
  721.       keypad_u = 0;
  722.       keypad_changed =1;
  723.       break;
  724.     case XK_KP_9 :
  725.     case XK_KP_Prior:
  726.       keypad_ur = 0;
  727.       keypad_changed =1;
  728.       break;
  729.     case XK_KP_5 :
  730.     case XK_KP_Begin:
  731.     default :
  732.       KEYPRESSED=0;
  733.       break;
  734.     }
  735.       break;
  736.     }
  737.  
  738.   return keycode;
  739. }
  740.  
  741.  
  742.  
  743.  
  744. static int xview_keycode = AKEY_NONE;
  745.  
  746. #ifdef XVIEW
  747.  
  748. void event_proc (Xv_Window window, Event *event, Notify_arg arg)
  749. {
  750.   int keycode;
  751.  
  752.   keycode = GetKeyCode (event->ie_xevent);
  753.   if (keycode != AKEY_NONE)
  754.     xview_keycode = keycode;
  755. }
  756.  
  757. static int auto_reboot;
  758.  
  759. int disk_change (char *a, char *full_filename, char *filename)
  760. {
  761.   int diskno;
  762.   int status;
  763.  
  764.   diskno = 1;
  765.  
  766.   if (!auto_reboot)
  767.     diskno = notice_prompt (panel, NULL,
  768.                 NOTICE_MESSAGE_STRINGS,
  769.                   "Insert Disk into which drive?",
  770.                   NULL,
  771.                 NOTICE_BUTTON, "1", 1,
  772.                 NOTICE_BUTTON, "2", 2,
  773.                 NOTICE_BUTTON, "3", 3,
  774.                 NOTICE_BUTTON, "4", 4,
  775.                 NOTICE_BUTTON, "5", 5,
  776.                 NOTICE_BUTTON, "6", 6,
  777.                 NOTICE_BUTTON, "7", 7,
  778.                 NOTICE_BUTTON, "8", 8,
  779.                 NULL);
  780.  
  781.   if ((diskno < 1) || (diskno > 8))
  782.     {
  783.       printf ("Invalid diskno: %d\n", diskno);
  784.       exit (1);
  785.     }
  786.  
  787.   SIO_Dismount(diskno);
  788.   if (!SIO_Mount (diskno,full_filename))
  789.     status = XV_ERROR;
  790.   else
  791.     {
  792.       if (auto_reboot)
  793.     Coldstart ();
  794.       status = XV_OK;
  795.     }
  796.  
  797.   return status;
  798. }
  799.  
  800. boot_callback ()
  801. {
  802.   auto_reboot = TRUE;
  803.  
  804.   xv_set (chooser,
  805.       FRAME_LABEL, "Disk Selector",
  806.       FILE_CHOOSER_DIRECTORY, atari_disk_dir,
  807.       FILE_CHOOSER_NOTIFY_FUNC, disk_change,
  808.       XV_SHOW, TRUE,
  809.       NULL);
  810. }
  811.  
  812. insert_callback ()
  813. {
  814.   auto_reboot = FALSE;
  815.  
  816.   xv_set (chooser,
  817.       FRAME_LABEL, "Disk Selector",
  818.       FILE_CHOOSER_DIRECTORY, atari_disk_dir,
  819.       FILE_CHOOSER_NOTIFY_FUNC, disk_change,
  820.       XV_SHOW, TRUE,
  821.       NULL);
  822. }
  823.  
  824. eject_callback ()
  825. {
  826.   int diskno;
  827.  
  828.   diskno = notice_prompt (panel, NULL,
  829.               NOTICE_MESSAGE_STRINGS,
  830.                 "Eject Disk from drive?",
  831.                 NULL,
  832.               NOTICE_BUTTON, "1", 1,
  833.               NOTICE_BUTTON, "2", 2,
  834.               NOTICE_BUTTON, "3", 3,
  835.               NOTICE_BUTTON, "4", 4,
  836.               NOTICE_BUTTON, "5", 5,
  837.               NOTICE_BUTTON, "6", 6,
  838.               NOTICE_BUTTON, "7", 7,
  839.               NOTICE_BUTTON, "8", 8,
  840.               NULL);
  841.  
  842.   if ((diskno < 1) || (diskno > 8))
  843.     {
  844.       printf ("Invalid diskno: %d\n", diskno);
  845.       exit (1);
  846.     }
  847.  
  848.   SIO_Dismount(diskno);
  849. }
  850.  
  851. disable_callback ()
  852. {
  853.   int diskno;
  854.  
  855.   diskno = notice_prompt (panel, NULL,
  856.               NOTICE_MESSAGE_STRINGS,
  857.                 "Drive to Disable?",
  858.                 NULL,
  859.               NOTICE_BUTTON, "1", 1,
  860.               NOTICE_BUTTON, "2", 2,
  861.               NOTICE_BUTTON, "3", 3,
  862.               NOTICE_BUTTON, "4", 4,
  863.               NOTICE_BUTTON, "5", 5,
  864.               NOTICE_BUTTON, "6", 6,
  865.               NOTICE_BUTTON, "7", 7,
  866.               NOTICE_BUTTON, "8", 8,
  867.               NULL);
  868.  
  869.   if ((diskno < 1) || (diskno > 8))
  870.     {
  871.       printf ("Invalid driveno: %d\n", diskno);
  872.       exit (1);
  873.     }
  874.  
  875.   SIO_DisableDrive(diskno);
  876. }
  877.  
  878. int rom_change (char *a, char *full_filename, char *filename)
  879. {
  880.   struct stat buf;
  881.   int status = XV_ERROR;
  882.   int yesno;
  883.  
  884.   stat (full_filename, &buf);
  885.  
  886.   switch (buf.st_size)
  887.     {
  888.     case 0x2000 :
  889.       Remove_ROM ();
  890.       if (Insert_8K_ROM(full_filename,0))
  891.     {
  892.       Coldstart ();
  893.       status = XV_OK;
  894.     }
  895.       break;
  896.     case 0x4000 :
  897.       yesno = notice_prompt (panel, NULL,
  898.                  NOTICE_MESSAGE_STRINGS,
  899.                    filename,
  900.                    "Is this an OSS Supercartridge?",
  901.                    NULL,
  902.                  NOTICE_BUTTON_YES, "No",
  903.                  NOTICE_BUTTON_NO, "Yes",
  904.                  NULL);
  905.       if (yesno == NOTICE_YES)
  906.     {
  907.       Remove_ROM ();
  908.       if (Insert_16K_ROM(full_filename,0))
  909.         {
  910.           Coldstart ();
  911.           status = XV_OK;
  912.         }
  913.     }
  914.       else
  915.     {
  916.       Remove_ROM ();
  917.       if (Insert_OSS_ROM(full_filename,0))
  918.         {
  919.           Coldstart ();
  920.           status = XV_OK;
  921.         }
  922.     }
  923.       break;
  924.     case 0x8000 :
  925.       Remove_ROM ();
  926.       if (machine == Atari5200)
  927.     {
  928.       if (Insert_32K_5200ROM(full_filename,0))
  929.         {
  930.           Coldstart ();
  931.           status = XV_OK;
  932.         }
  933.     }
  934.       else
  935.     {
  936.       if (Insert_DB_ROM(full_filename,0))
  937.         {
  938.           Coldstart ();
  939.           status = XV_OK;
  940.         }
  941.     }
  942.       break;
  943.     default :
  944.       break;
  945.     }
  946.  
  947.   return status;
  948. }
  949.  
  950. insert_rom_callback ()
  951. {
  952.   xv_set (chooser,
  953.       FRAME_LABEL, "ROM Selector",
  954.       FILE_CHOOSER_DIRECTORY, atari_rom_dir,
  955.       FILE_CHOOSER_NOTIFY_FUNC, rom_change,
  956.       XV_SHOW, TRUE,
  957.       NULL);
  958. }
  959.  
  960. remove_rom_callback ()
  961. {
  962.   Remove_ROM ();
  963.   Coldstart ();
  964. }
  965.  
  966. enable_pill_callback ()
  967. {
  968.   EnablePILL ();
  969.   Coldstart ();
  970. }
  971.  
  972. exit_callback ()
  973. {
  974.   exit (1);
  975. }
  976.  
  977. option_callback ()
  978. {
  979.   menu_consol &= 0x03;
  980. }
  981.  
  982. select_callback ()
  983. {
  984.   menu_consol &= 0x05;
  985. }
  986.  
  987. start_callback ()
  988. {
  989.   menu_consol &= 0x6;
  990. }
  991.  
  992. help_callback ()
  993. {
  994.   xview_keycode = AKEY_HELP;
  995. }
  996.  
  997. break_callback ()
  998. {
  999.   xview_keycode = AKEY_BREAK;
  1000. }
  1001.  
  1002. reset_callback ()
  1003. {
  1004.   Warmstart ();
  1005. }
  1006.  
  1007. coldstart_callback ()
  1008. {
  1009.   Coldstart ();
  1010. }
  1011.  
  1012. coldstart_osa_callback ()
  1013. {
  1014.   int status;
  1015.  
  1016.   status = Initialise_AtariOSA ();
  1017.   if (status)
  1018.     {
  1019.       Menu_item menuitem;
  1020.  
  1021.       menuitem = xv_get (consol_menu,
  1022.              MENU_NTH_ITEM, 4);
  1023.  
  1024.       xv_set (menuitem,
  1025.           MENU_INACTIVE, TRUE,
  1026.           NULL);
  1027.     }
  1028.   else
  1029.     {
  1030.       notice_prompt (panel, NULL,
  1031.              NOTICE_MESSAGE_STRINGS,
  1032.                "Sorry, OS/A ROM Unavailable",
  1033.                NULL,
  1034.              NOTICE_BUTTON, "Cancel", 1,
  1035.              NULL);
  1036.     }
  1037. }
  1038.  
  1039. coldstart_osb_callback ()
  1040. {
  1041.   int status;
  1042.  
  1043.   status = Initialise_AtariOSB ();
  1044.   if (status)
  1045.     {
  1046.       Menu_item menuitem;
  1047.       
  1048.       menuitem = xv_get (consol_menu,
  1049.              MENU_NTH_ITEM, 4);
  1050.  
  1051.       xv_set (menuitem,
  1052.           MENU_INACTIVE, TRUE,
  1053.           NULL);
  1054.     }
  1055.   else
  1056.     {
  1057.       notice_prompt (panel, NULL,
  1058.              NOTICE_MESSAGE_STRINGS,
  1059.                "Sorry, OS/B ROM Unavailable",
  1060.                NULL,
  1061.              NOTICE_BUTTON, "Cancel", 1,
  1062.              NULL);
  1063.     }
  1064. }
  1065.  
  1066. coldstart_xl_callback ()
  1067. {
  1068.   int status;
  1069.  
  1070.   status = Initialise_AtariXL ();
  1071.   if (status)
  1072.     {
  1073.       Menu_item menuitem;
  1074.  
  1075.       menuitem = xv_get (consol_menu,
  1076.              MENU_NTH_ITEM, 4);
  1077.       
  1078.       xv_set (menuitem,
  1079.           MENU_INACTIVE, FALSE,
  1080.           NULL);
  1081.     }
  1082.   else
  1083.     {
  1084.       notice_prompt (panel, NULL,
  1085.              NOTICE_MESSAGE_STRINGS,
  1086.                "Sorry, XL/XE ROM Unavailable",
  1087.                NULL,
  1088.              NOTICE_BUTTON, "Cancel", 1,
  1089.              NULL);
  1090.     }
  1091. }
  1092.  
  1093. coldstart_xe_callback ()
  1094. {
  1095.   int status;
  1096.  
  1097.   status = Initialise_AtariXE ();
  1098.   if (status)
  1099.     {
  1100.       Menu_item menuitem;
  1101.  
  1102.       menuitem = xv_get (consol_menu,
  1103.              MENU_NTH_ITEM, 4);
  1104.  
  1105.       xv_set (menuitem,
  1106.           MENU_INACTIVE, FALSE,
  1107.           NULL);
  1108.     }
  1109.   else
  1110.     {
  1111.       notice_prompt (panel, NULL,
  1112.              NOTICE_MESSAGE_STRINGS,
  1113.                "Sorry, XL/XE ROM Unavailable",
  1114.                NULL,
  1115.              NOTICE_BUTTON, "Cancel", 1,
  1116.              NULL);
  1117.     }
  1118. }
  1119.  
  1120. coldstart_5200_callback ()
  1121. {
  1122.   int status;
  1123.  
  1124.   status = Initialise_Atari5200 ();
  1125.   if (status)
  1126.     {
  1127.       Menu_item menuitem;
  1128.  
  1129.       menuitem = xv_get (consol_menu,
  1130.              MENU_NTH_ITEM, 4);
  1131.  
  1132.       xv_set (menuitem,
  1133.           MENU_INACTIVE, FALSE,
  1134.           NULL);
  1135.     }
  1136.   else
  1137.     {
  1138.       notice_prompt (panel, NULL,
  1139.              NOTICE_MESSAGE_STRINGS,
  1140.                "Sorry, 5200 ROM Unavailable",
  1141.                NULL,
  1142.              NOTICE_BUTTON, "Cancel", 1,
  1143.              NULL);
  1144.     }
  1145. }
  1146.  
  1147. controllers_ok_callback ()
  1148. {
  1149.   xv_set (controllers_frame,
  1150.       XV_SHOW, FALSE,
  1151.       NULL);
  1152. }
  1153.  
  1154. controllers_callback ()
  1155. {
  1156.   xv_set (controllers_frame,
  1157.       XV_SHOW, TRUE,
  1158.       NULL);
  1159. }
  1160.  
  1161. void sorry_message ()
  1162. {
  1163.   notice_prompt (panel, NULL,
  1164.          NOTICE_MESSAGE_STRINGS,
  1165.            "Sorry, controller already assign",
  1166.            "to another device",
  1167.            NULL,
  1168.          NOTICE_BUTTON, "Cancel", 1,
  1169.          NULL);
  1170. }
  1171.  
  1172. keypad_callback ()
  1173. {
  1174.   int new_mode;
  1175.  
  1176.   new_mode = xv_get (keypad_item, PANEL_VALUE);
  1177.  
  1178.   if ((new_mode != mouse_mode) &&
  1179.       (new_mode != js0_mode) &&
  1180.       (new_mode != js1_mode))
  1181.     {
  1182.       keypad_mode = new_mode;
  1183.     }
  1184.   else
  1185.     {
  1186.       sorry_message ();
  1187.       xv_set (keypad_item,
  1188.           PANEL_VALUE, keypad_mode,
  1189.           NULL);
  1190.     }
  1191. }
  1192.  
  1193. mouse_callback ()
  1194. {
  1195.   int new_mode;
  1196.  
  1197.   new_mode = xv_get (mouse_item, PANEL_VALUE);
  1198.  
  1199.   if ((new_mode != keypad_mode) &&
  1200.       (new_mode != js0_mode) &&
  1201.       (new_mode != js1_mode))
  1202.     {
  1203.       mouse_mode = new_mode;
  1204.     }
  1205.   else
  1206.     {
  1207.       sorry_message ();
  1208.       xv_set (mouse_item,
  1209.           PANEL_VALUE, mouse_mode,
  1210.           NULL);
  1211.     }
  1212. }
  1213.  
  1214. #ifdef LINUX_JOYSTICK
  1215. js0_callback ()
  1216. {
  1217.   int new_mode;
  1218.  
  1219.   new_mode = xv_get (js0_item, PANEL_VALUE);
  1220.  
  1221.   if ((new_mode != keypad_mode) &&
  1222.       (new_mode != mouse_mode) &&
  1223.       (new_mode != js1_mode))
  1224.     {
  1225.       js0_mode = new_mode;
  1226.     }
  1227.   else
  1228.     {
  1229.       sorry_message ();
  1230.       xv_set (js0_item,
  1231.           PANEL_VALUE, js0_mode,
  1232.           NULL);
  1233.     }
  1234. }
  1235.  
  1236. js1_callback ()
  1237. {
  1238.   int new_mode;
  1239.  
  1240.   new_mode = xv_get (js1_item, PANEL_VALUE);
  1241.  
  1242.   if ((new_mode != keypad_mode) &&
  1243.       (new_mode != mouse_mode) &&
  1244.       (new_mode != js0_mode))
  1245.     {
  1246.       js1_mode = new_mode;
  1247.     }
  1248.   else
  1249.     {
  1250.       sorry_message ();
  1251.       xv_set (js1_item,
  1252.           PANEL_VALUE, js1_mode,
  1253.           NULL);
  1254.     }
  1255. }
  1256. #endif
  1257.  
  1258. performance_ok_callback ()
  1259. {
  1260.   xv_set (performance_frame,
  1261.       XV_SHOW, FALSE,
  1262.       NULL);
  1263. }
  1264.  
  1265. performance_callback ()
  1266. {
  1267.   xv_set (performance_frame,
  1268.       XV_SHOW, TRUE,
  1269.       NULL);
  1270. }
  1271.  
  1272. refresh_callback (Panel_item item, int value, Event *event)
  1273. {
  1274.   refresh_rate = value;
  1275. }
  1276.  
  1277. #endif
  1278.  
  1279. void Atari_WhatIs (int mode)
  1280. {
  1281.   switch (mode)
  1282.     {
  1283.     case 0 :
  1284.       printf ("Joystick 0");
  1285.       break;
  1286.     case 1 :
  1287.       printf ("Joystick 1");
  1288.       break;
  1289.     case 2 :
  1290.       printf ("Joystick 2");
  1291.       break;
  1292.     case 3 :
  1293.       printf ("Joystick 3");
  1294.       break;
  1295.     default :
  1296.       printf ("not available");
  1297.       break;
  1298.     }
  1299. }
  1300.  
  1301. #ifdef MOTIF
  1302. void motif_boot_disk (Widget fs, XtPointer client_data,
  1303.               XtPointer cbs)
  1304. {
  1305.   char *filename;
  1306.  
  1307.   if (XmStringGetLtoR(((XmFileSelectionBoxCallbackStruct *) cbs)->value,
  1308.               XmSTRING_DEFAULT_CHARSET, &filename))
  1309.     {
  1310.       if (*filename)
  1311.     {
  1312.       SIO_Dismount(1);
  1313.       if (SIO_Mount (1, filename))
  1314.         Coldstart ();
  1315.     }
  1316.  
  1317.       XtFree (filename);
  1318.     }
  1319.  
  1320.   XtUnmanageChild (fs);
  1321.   XtPopdown (XtParent(fs));
  1322. }
  1323.  
  1324. void motif_select_disk (Widget toggle, XtPointer client_data, XtPointer cbs)
  1325. {
  1326.   motif_disk_sel = (int) client_data;
  1327. }
  1328.  
  1329. void motif_insert_disk (Widget fs, XtPointer client_data, XtPointer cbs)
  1330. {
  1331.   char *filename;
  1332.  
  1333.   if (XmStringGetLtoR(((XmFileSelectionBoxCallbackStruct *) cbs)->value,
  1334.               XmSTRING_DEFAULT_CHARSET, &filename))
  1335.     {
  1336.       if (*filename)
  1337.     {
  1338.       SIO_Dismount(motif_disk_sel);
  1339.       SIO_Mount (motif_disk_sel, filename);
  1340.     }
  1341.  
  1342.       XtFree (filename);
  1343.     }
  1344.  
  1345.   XtUnmanageChild (fs);
  1346.   XtPopdown (XtParent(fs));
  1347. }
  1348.  
  1349. void motif_select_rom (Widget toggle, XtPointer client_data, XtPointer cbs)
  1350. {
  1351.   motif_rom_sel = (int) client_data;
  1352. }
  1353.  
  1354. void motif_insert_rom (Widget fs, XtPointer client_data, XtPointer cbs)
  1355. {
  1356.   char *filename;
  1357.   int ret;
  1358.  
  1359.   if (XmStringGetLtoR(((XmFileSelectionBoxCallbackStruct *) cbs)->value,
  1360.               XmSTRING_DEFAULT_CHARSET, &filename))
  1361.     {
  1362.       if (*filename)
  1363.     {
  1364.       Remove_ROM ();
  1365.       switch (motif_rom_sel)
  1366.       {
  1367.       case 1:
  1368.         ret = Insert_8K_ROM(filename,0);
  1369.         break;
  1370.       case 2:
  1371.         ret = Insert_16K_ROM(filename,0);
  1372.         break;
  1373.       case 3:
  1374.         ret = Insert_OSS_ROM(filename,0);
  1375.         break;
  1376.       case 4:
  1377.         ret = Insert_DB_ROM(filename,0);
  1378.         break;
  1379.       case 5:
  1380.         ret = Insert_32K_5200ROM(filename,0);
  1381.         break;
  1382.       default:
  1383.         ret = 0;
  1384.         break;
  1385.       }
  1386.       if (ret)
  1387.       {
  1388.         Coldstart ();
  1389.       }
  1390.     }
  1391.  
  1392.       XtFree (filename);
  1393.     }
  1394.  
  1395.   XtUnmanageChild (fs);
  1396.   XtPopdown (XtParent(fs));
  1397. }
  1398.  
  1399. void motif_fs_cancel (Widget fs, XtPointer client_data, XtPointer call_data)
  1400. {
  1401.   XtUnmanageChild (fs);
  1402.   XtPopdown (XtParent(fs));
  1403. }
  1404.  
  1405. void motif_eject_cback (Widget button, XtPointer client_data, XtPointer cbs)
  1406. {
  1407.   SIO_Dismount(((int) client_data) + 1);
  1408. }
  1409.  
  1410. void motif_disable_cback (Widget button, XtPointer client_data, XtPointer cbs)
  1411. {
  1412.   SIO_DisableDrive(((int) client_data) + 1);
  1413. }
  1414.  
  1415. void update_fsel(Widget fsel)
  1416. {
  1417.   XmString dirmask;
  1418.  
  1419.   XtVaGetValues(fsel, XmNdirMask, &dirmask, NULL);
  1420.   XmFileSelectionDoSearch(fsel, dirmask);
  1421. }
  1422.  
  1423. void motif_system_cback (Widget w, XtPointer item_no, XtPointer cbs)
  1424. {
  1425.   XmString t;
  1426.   int status;
  1427.   char *errmsg = NULL;
  1428.  
  1429.   switch ((int) item_no)
  1430.     {
  1431.     case 0 :
  1432.       update_fsel(fsel_b);
  1433.       XtManageChild (fsel_b);
  1434.       XtPopup (XtParent(fsel_b), XtGrabNone);
  1435.       break;
  1436.     case 1 :
  1437.       /* insert disk */
  1438.       update_fsel(fsel_d);
  1439.       XtManageChild (fsel_d);
  1440.       XtPopup (XtParent(fsel_d), XtGrabNone);
  1441.       break;
  1442.     case 2 :
  1443.       /* eject disk */
  1444.       /* handled by pullright menu */
  1445.       break;
  1446.     case 3 :
  1447.       /* disable drive */
  1448.       /* handled by pullright menu */
  1449.       break;
  1450.     case 4 :
  1451.       /* insert rom */
  1452.       update_fsel(fsel_r);
  1453.       XtManageChild (fsel_r);
  1454.       XtPopup (XtParent(fsel_r), XtGrabNone);
  1455.       break;
  1456.     case 5 :
  1457.       Remove_ROM ();
  1458.       Coldstart ();
  1459.       break;
  1460.     case 6 :
  1461.       EnablePILL ();
  1462.       Coldstart ();
  1463.       break;
  1464.     case 7 :
  1465.       status = Initialise_AtariOSA (NULL,NULL);
  1466.       if (status == 0)
  1467.     errmsg = "Sorry, OS/A ROM Unavailable";
  1468.       break;
  1469.     case 8 :
  1470.       status = Initialise_AtariOSB (NULL,NULL);
  1471.       if (status == 0)
  1472.     errmsg = "Sorry, OS/B ROM Unavailable";
  1473.       break;
  1474.     case 9 :
  1475.       status = Initialise_AtariXL (NULL,NULL);
  1476.       if (status == 0)
  1477.     errmsg = "Sorry, XL/XE ROM Unavailable";
  1478.       break;
  1479.     case 10 :
  1480.       status = Initialise_AtariXE (NULL,NULL);
  1481.       if (status == 0)
  1482.     errmsg = "Sorry, XL/XE ROM Unavailable";
  1483.       break;
  1484.     case 11 :
  1485.       status = Initialise_Atari5200 (NULL,NULL);
  1486.       if (status == 0)
  1487.     errmsg = "Sorry, 5200 ROM Unavailable";
  1488.       break;
  1489.     case 12 :
  1490.       exit (0);
  1491.     }
  1492.  
  1493.   if (errmsg)
  1494.     {
  1495.       static Widget dialog = NULL;
  1496.  
  1497.       if (!dialog)
  1498.     {
  1499.       Arg arg[1];
  1500.  
  1501.       dialog = XmCreateErrorDialog (main_w, "message", arg, 0);
  1502.  
  1503.       XtVaSetValues (dialog,
  1504.              XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL,
  1505.              NULL);
  1506.  
  1507.       XtUnmanageChild (XmMessageBoxGetChild(dialog, XmDIALOG_OK_BUTTON));
  1508.       XtUnmanageChild (XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
  1509.     }
  1510.  
  1511.       t = XmStringCreateSimple (errmsg);
  1512.       XtVaSetValues (dialog,
  1513.              XmNmessageString, t,
  1514.              NULL);
  1515.       XmStringFree (t);
  1516.       XtManageChild (dialog);
  1517.     }
  1518. }
  1519.  
  1520. void motif_consol_cback (Widget w, XtPointer item_no, XtPointer cbs)
  1521. {
  1522.   switch ((int) item_no)
  1523.     {
  1524.     case 0 :
  1525.       menu_consol &= 0x03; /* Option Pressed */
  1526.       break;
  1527.     case 1 :
  1528.       menu_consol &= 0x05; /* Select Pressed */
  1529.       break;
  1530.     case 2 :
  1531.       menu_consol &= 0x06; /* Start Pressed */
  1532.       break;
  1533.     case 3 :
  1534.       xview_keycode = AKEY_HELP;
  1535.       break;
  1536.     case 4 :
  1537.       xview_keycode = AKEY_BREAK;
  1538.       break;
  1539.     case 5 :
  1540.       Warmstart ();
  1541.       break;
  1542.     case 6 :
  1543.       Coldstart ();
  1544.       break;
  1545.     }
  1546. }
  1547.  
  1548. void motif_keypress (Widget w, XtPointer client_data, XEvent *event,
  1549.              Boolean *continue_to_dispatch)
  1550. {
  1551.   int keycode;
  1552.  
  1553.   keycode = GetKeyCode (event);
  1554.   if (keycode != AKEY_NONE)
  1555.     xview_keycode = keycode;
  1556. }
  1557.  
  1558. void motif_exposure (Widget w, XtPointer client_data, XEvent *event,
  1559.              Boolean *continue_to_dispatch)
  1560. {
  1561.   modified = TRUE;
  1562. }
  1563.  
  1564.  
  1565. void motif_enter (Widget w, XtPointer client_data, XEvent *event, Boolean *ctd)
  1566. {
  1567.     if (XCURRENTAUTOREPEAT == AutoRepeatModeOn)
  1568.         {
  1569.         XAutoRepeatOff(display);
  1570.         XCURRENTAUTOREPEAT=AutoRepeatModeOff;
  1571.         }
  1572.     if (private_cmap)
  1573.         XInstallColormap(display, cmap);
  1574. }
  1575.  
  1576. void motif_leave (Widget w, XtPointer client_data, XEvent *event, Boolean *ctd)
  1577. {
  1578.     if (XTERNAUTOREPEAT == AutoRepeatModeOn)
  1579.         {
  1580.         XAutoRepeatOn(display);
  1581.         XCURRENTAUTOREPEAT=AutoRepeatModeOn;
  1582.         }
  1583.     if (private_cmap)
  1584.         {
  1585.         XUninstallColormap(display,cmap);
  1586. /*        XInstallColormap(display,defcmap); */
  1587.         }
  1588. }
  1589.  
  1590. #endif
  1591.  
  1592. void Atari_Destruct(void)
  1593. {
  1594.     if (display && XTERNAUTOREPEAT != XCURRENTAUTOREPEAT)
  1595.         XAutoRepeatOn(display);
  1596. }
  1597.  
  1598.  
  1599. void Atari_Initialise (int *argc, char *argv[])
  1600. {
  1601.  
  1602. #ifndef XVIEW
  1603. #ifndef MOTIF
  1604.   XSetWindowAttributes    xswda;
  1605. #endif
  1606. #endif
  1607.  
  1608.   XGCValues    xgcvl;
  1609.  
  1610.   int missing_colors=0;
  1611.  
  1612.   int depth;
  1613.   int i, j;
  1614.   int mode = 0;
  1615.  
  1616. #ifdef XVIEW
  1617.   int ypos;
  1618.  
  1619.   xv_init (XV_INIT_ARGC_PTR_ARGV, argc, argv, NULL);
  1620. #endif
  1621.  
  1622.  
  1623.   atexit(Atari_Destruct); 
  1624.  
  1625. #ifdef MOTIF
  1626.   toplevel = XtVaAppInitialize (&app, "Atari800",
  1627.                 NULL, 0,
  1628.                 argc, argv, NULL,
  1629.                 XtNtitle, ATARI_TITLE,
  1630.                 NULL);
  1631. #endif
  1632.  
  1633.  
  1634.  
  1635.   gettimeofday (&tp, &tzp);
  1636.   basetime = tp.tv_sec + (tp.tv_usec / 1000000.0);
  1637.  
  1638.   for (i=j=1;i<*argc;i++)
  1639.     {
  1640.       if (strcmp(argv[i],"-small") == 0)
  1641.     windowsize = Small;
  1642.       else if (strcmp(argv[i],"-large") == 0)
  1643.     windowsize = Large;
  1644.       else if (strcmp(argv[i],"-huge") == 0)
  1645.     windowsize = Huge;
  1646.       else if (strcmp(argv[i],"-x11bug") == 0)
  1647.     x11bug = TRUE;
  1648.       else if (strcmp(argv[i],"-fps") == 0)
  1649.     x11_monitor = MONITOR_FPS;
  1650.       else if (strcmp(argv[i],"-sio") == 0)
  1651.     x11_monitor = MONITOR_SIO;
  1652.       else if (strcmp(argv[i],"-private_cmap") == 0)
  1653.         private_cmap = TRUE;
  1654.       else if (strcmp(argv[i],"-keypad") == 0)
  1655.         {
  1656.           if (keypad_mode == -1)
  1657.             keypad_mode = mode++;
  1658.         }
  1659.       else
  1660.     {
  1661.       if (strcmp(argv[i],"-help") == 0)
  1662.         {
  1663.           printf ("\t-small        Small window (%dx%d)\n",
  1664.               ATARI_WIDTH, ATARI_HEIGHT);
  1665.           printf ("\t-large        Large window (%dx%d)\n",
  1666.               ATARI_WIDTH*2, ATARI_HEIGHT*2);
  1667.           printf ("\t-huge         Huge window (%dx%d)\n",
  1668.               ATARI_WIDTH*3, ATARI_HEIGHT*3);
  1669.           printf ("\t-x11bug       Enable debug code in atari_x11.c\n");
  1670.         }
  1671.  
  1672.       argv[j++] = argv[i];
  1673.     }
  1674.     }
  1675.  
  1676.   *argc = j;
  1677.  
  1678. #ifdef NAS
  1679.   NAS_Initialise (argc, argv);
  1680. #endif
  1681.  
  1682. #ifdef VOXWARE
  1683.   Voxware_Initialise (argc, argv);
  1684. #endif
  1685.  
  1686. #ifdef SHM
  1687.   if (windowsize != Small)
  1688.     {
  1689.       printf ("X Shared memory version only supports small window\n");
  1690.       windowsize = Small;
  1691.     }
  1692. #endif
  1693.  
  1694.   switch (windowsize)
  1695.     {
  1696.     case Small :
  1697.       window_width = ATARI_WIDTH;
  1698.       window_height = ATARI_HEIGHT;
  1699.       break;
  1700.     case Large :
  1701.       window_width = ATARI_WIDTH * 2;
  1702.       window_height = ATARI_HEIGHT * 2;
  1703.       break;
  1704.     case Huge :
  1705.       window_width = ATARI_WIDTH * 3;
  1706.       window_height = ATARI_HEIGHT * 3;
  1707.       break;
  1708.     }
  1709.  
  1710. #ifdef LINUX_JOYSTICK
  1711.   js0 = open ("/dev/js0", O_RDONLY, 0777);
  1712.   if (js0 != -1)
  1713.     {
  1714.       int status;
  1715.  
  1716.       status = read (js0, &js_data, JS_RETURN);
  1717.       if (status != JS_RETURN)
  1718.     {
  1719.       perror ("/dev/js0");
  1720.       exit (1);
  1721.     }
  1722.  
  1723.       js0_centre_x = js_data.x;
  1724.       js0_centre_y = js_data.y;
  1725.  
  1726.       if (x11bug)
  1727.     printf ("Joystick 0: centre_x = %d, centry_y = %d\n",
  1728.         js0_centre_x, js0_centre_y);
  1729.  
  1730.       js0_mode = mode++;
  1731.     }
  1732.  
  1733.   js1 = open ("/dev/js1", O_RDONLY, 0777);
  1734.   if (js1 != -1)
  1735.     {
  1736.       int status;
  1737.  
  1738.       status = read (js1, &js_data, JS_RETURN);
  1739.       if (status != JS_RETURN)
  1740.     {
  1741.       perror ("/dev/js1");
  1742.       exit (1);
  1743.     }
  1744.  
  1745.       js1_centre_x = js_data.x;
  1746.       js1_centre_y = js_data.y;
  1747.  
  1748.       if (x11bug)
  1749.     printf ("Joystick 1: centre_x = %d, centry_y = %d\n",
  1750.         js1_centre_x, js1_centre_y);
  1751.  
  1752.       js1_mode = mode++;
  1753.     }
  1754. #endif
  1755.  
  1756.   mouse_mode = mode++;
  1757.   if (keypad_mode == -1)
  1758.     keypad_mode = mode++;
  1759.  
  1760. #ifdef XVIEW
  1761.   frame = (Frame)xv_create ((Xv_opaque)NULL, FRAME,
  1762.                 FRAME_LABEL, ATARI_TITLE,
  1763.                 FRAME_SHOW_RESIZE_CORNER, FALSE,
  1764.                 XV_WIDTH, window_width,
  1765.                 XV_HEIGHT, window_height + 27,
  1766.                 FRAME_SHOW_FOOTER, TRUE,
  1767.                 XV_SHOW, TRUE,
  1768.                 NULL);
  1769.  
  1770.   panel = (Panel)xv_create (frame, PANEL,
  1771.                 XV_HEIGHT, 25,
  1772.                 XV_SHOW, TRUE,
  1773.                 NULL);
  1774.  
  1775.   system_menu = xv_create ((Xv_opaque)NULL, MENU,
  1776.                MENU_ITEM,
  1777.                  MENU_STRING, "Boot Disk",
  1778.                  MENU_NOTIFY_PROC, boot_callback,
  1779.                  NULL,
  1780.                MENU_ITEM,
  1781.                  MENU_STRING, "Insert Disk",
  1782.                  MENU_NOTIFY_PROC, insert_callback,
  1783.                  NULL,
  1784.                MENU_ITEM,
  1785.                  MENU_STRING, "Eject Disk",
  1786.                  MENU_NOTIFY_PROC, eject_callback,
  1787.                  NULL,
  1788.                MENU_ITEM,
  1789.                  MENU_STRING, "Disable Drive",
  1790.                  MENU_NOTIFY_PROC, disable_callback,
  1791.                  NULL,
  1792.                MENU_ITEM,
  1793.                  MENU_STRING, "Insert Cartridge",
  1794.                  MENU_NOTIFY_PROC, insert_rom_callback,
  1795.                  NULL,
  1796.                MENU_ITEM,
  1797.                  MENU_STRING, "Remove Cartridge",
  1798.                  MENU_NOTIFY_PROC, remove_rom_callback,
  1799.                  NULL,
  1800.                MENU_ITEM,
  1801.                  MENU_STRING, "Enable PILL",
  1802.                  MENU_NOTIFY_PROC, enable_pill_callback,
  1803.                  NULL,
  1804.                MENU_ITEM,
  1805.                  MENU_STRING, "Atari 800 OS/A",
  1806.                  MENU_NOTIFY_PROC, coldstart_osa_callback,
  1807.                  NULL,
  1808.                MENU_ITEM,
  1809.                  MENU_STRING, "Atari 800 OS/B",
  1810.                  MENU_NOTIFY_PROC, coldstart_osb_callback,
  1811.                  NULL,
  1812.                MENU_ITEM,
  1813.                  MENU_STRING, "Atari 800XL",
  1814.                  MENU_NOTIFY_PROC, coldstart_xl_callback,
  1815.                  NULL,
  1816.                MENU_ITEM,
  1817.                  MENU_STRING, "Atari 130XE",
  1818.                  MENU_NOTIFY_PROC, coldstart_xe_callback,
  1819.                  NULL,
  1820.                MENU_ITEM,
  1821.                  MENU_STRING, "Atari 5200",
  1822.                  MENU_NOTIFY_PROC, coldstart_5200_callback,
  1823.                  NULL,
  1824.                MENU_ITEM,
  1825.                  MENU_STRING, "Exit",
  1826.                  MENU_NOTIFY_PROC, exit_callback,
  1827.                  NULL,
  1828.                NULL);
  1829.  
  1830.   xv_create (panel, PANEL_BUTTON,
  1831.          PANEL_LABEL_STRING, "System",
  1832.          PANEL_ITEM_MENU, system_menu,
  1833.          NULL);
  1834.  
  1835.   consol_menu = (Menu)xv_create ((Xv_opaque)NULL, MENU,
  1836.                  MENU_ITEM,
  1837.                    MENU_STRING, "Option",
  1838.                    MENU_NOTIFY_PROC, option_callback,
  1839.                    NULL,
  1840.                  MENU_ITEM,
  1841.                    MENU_STRING, "Select",
  1842.                    MENU_NOTIFY_PROC, select_callback,
  1843.                    NULL,
  1844.                  MENU_ITEM,
  1845.                    MENU_STRING, "Start",
  1846.                    MENU_NOTIFY_PROC, start_callback,
  1847.                    NULL,
  1848.                  MENU_ITEM,
  1849.                    MENU_STRING, "Help",
  1850.                    MENU_NOTIFY_PROC, help_callback,
  1851.                    MENU_INACTIVE, (machine == Atari),
  1852.                    NULL,
  1853.                  MENU_ITEM,
  1854.                    MENU_STRING, "Break",
  1855.                    MENU_NOTIFY_PROC, break_callback,
  1856.                    NULL,
  1857.                  MENU_ITEM,
  1858.                    MENU_STRING, "Reset",
  1859.                    MENU_NOTIFY_PROC, reset_callback,
  1860.                    NULL,
  1861.                  MENU_ITEM,
  1862.                    MENU_STRING, "Coldstart",
  1863.                    MENU_NOTIFY_PROC, coldstart_callback,
  1864.                    NULL,
  1865.                  NULL);
  1866.  
  1867.   xv_create (panel, PANEL_BUTTON,
  1868.          PANEL_LABEL_STRING, "Console",
  1869.          PANEL_ITEM_MENU, consol_menu,
  1870.          NULL);
  1871.  
  1872.   options_menu = (Menu)xv_create ((Xv_opaque)NULL, MENU,
  1873.                   MENU_ITEM,
  1874.                     MENU_STRING, "Controllers",
  1875.                     MENU_NOTIFY_PROC, controllers_callback,
  1876.                     NULL,
  1877.                   MENU_ITEM,
  1878.                     MENU_STRING, "Performance",
  1879.                     MENU_NOTIFY_PROC, performance_callback,
  1880.                     NULL,
  1881.                   NULL);
  1882.  
  1883.   xv_create (panel, PANEL_BUTTON,
  1884.          PANEL_LABEL_STRING, "Options",
  1885.          PANEL_ITEM_MENU, options_menu,
  1886.          NULL);
  1887.  
  1888.   canvas = (Canvas)xv_create (frame, CANVAS,
  1889.                   CANVAS_WIDTH, window_width,
  1890.                   CANVAS_HEIGHT, window_height,
  1891.                   NULL);
  1892. /*
  1893.    =====================================
  1894.    Create Controller Configuration Frame
  1895.    =====================================
  1896. */
  1897.   controllers_frame = (Frame)xv_create (frame, FRAME_CMD,
  1898.                        FRAME_LABEL, "Controller Configuration",
  1899.                        XV_WIDTH, 300,
  1900.                        XV_HEIGHT, 150,
  1901.                        NULL);
  1902.  
  1903.   controllers_panel = (Panel)xv_get (controllers_frame, FRAME_CMD_PANEL,
  1904.                      NULL);
  1905.  
  1906.   ypos = 10;
  1907.   keypad_item = (Panel_item)xv_create (controllers_panel, PANEL_CHOICE_STACK,
  1908.                        PANEL_VALUE_X, 150,
  1909.                        PANEL_VALUE_Y, ypos,
  1910.                        PANEL_LAYOUT, PANEL_HORIZONTAL,
  1911.                        PANEL_LABEL_STRING, "Numeric Keypad",
  1912.                        PANEL_CHOICE_STRINGS,
  1913.                          "Joystick 1",
  1914.                          "Joystick 2",
  1915.                          "Joystick 3",
  1916.                          "Joystick 4",
  1917.                          NULL,
  1918.                        PANEL_VALUE, keypad_mode,
  1919.                        PANEL_NOTIFY_PROC, keypad_callback,
  1920.                        NULL);
  1921.   ypos += 25;
  1922.  
  1923.   mouse_item = (Panel_item)xv_create (controllers_panel, PANEL_CHOICE_STACK,
  1924.                       PANEL_VALUE_X, 150,
  1925.                       PANEL_VALUE_Y, ypos,
  1926.                       PANEL_LAYOUT, PANEL_HORIZONTAL,
  1927.                       PANEL_LABEL_STRING, "Mouse",
  1928.                       PANEL_CHOICE_STRINGS,
  1929.                         "Joystick 1",
  1930.                         "Joystick 2",
  1931.                         "Joystick 3",
  1932.                         "Joystick 4",
  1933.                         "Paddle 1",
  1934.                         "Paddle 2",
  1935.                         "Paddle 3",
  1936.                         "Paddle 4",
  1937.                         "Paddle 5",
  1938.                         "Paddle 6",
  1939.                         "Paddle 7",
  1940.                         "Paddle 8",
  1941.                         "Light Pen",
  1942.                         NULL,
  1943.                       PANEL_VALUE, mouse_mode,
  1944.                       PANEL_NOTIFY_PROC, mouse_callback,
  1945.                       NULL);
  1946.   ypos += 25;
  1947.  
  1948. #ifdef LINUX_JOYSTICK
  1949.   if (js0 != -1)
  1950.     {
  1951.       js0_item = (Panel_item)xv_create (controllers_panel, PANEL_CHOICE_STACK,
  1952.                     PANEL_VALUE_X, 150,
  1953.                     PANEL_VALUE_Y, ypos,
  1954.                     PANEL_LAYOUT, PANEL_HORIZONTAL,
  1955.                     PANEL_LABEL_STRING, "/dev/js0",
  1956.                     PANEL_CHOICE_STRINGS,
  1957.                       "Joystick 1",
  1958.                       "Joystick 2",
  1959.                       "Joystick 3",
  1960.                       "Joystick 4",
  1961.                     NULL,
  1962.                     PANEL_VALUE, js0_mode,
  1963.                     PANEL_NOTIFY_PROC, js0_callback,
  1964.                     NULL);
  1965.       ypos += 25;
  1966.     }
  1967.  
  1968.   if (js1 != -1)
  1969.     {
  1970.       js1_item = (Panel_item)xv_create (controllers_panel, PANEL_CHOICE_STACK,
  1971.                     PANEL_VALUE_X, 150,
  1972.                     PANEL_VALUE_Y, ypos,
  1973.                     PANEL_LAYOUT, PANEL_HORIZONTAL,
  1974.                     PANEL_LABEL_STRING, "/dev/js1",
  1975.                     PANEL_CHOICE_STRINGS,
  1976.                       "Joystick 1",
  1977.                       "Joystick 2",
  1978.                       "Joystick 3",
  1979.                       "Joystick 4",
  1980.                     NULL,
  1981.                     PANEL_VALUE, js1_mode,
  1982.                     PANEL_NOTIFY_PROC, js1_callback,
  1983.                     NULL);
  1984.       ypos += 25;
  1985.     }
  1986. #endif
  1987.  
  1988.   xv_create (controllers_panel, PANEL_BUTTON,
  1989.          XV_X, 130,
  1990.          XV_Y, 125,
  1991.          PANEL_LABEL_STRING, "OK",
  1992.          PANEL_NOTIFY_PROC, controllers_ok_callback,
  1993.          NULL);
  1994. /*
  1995.    ======================================
  1996.    Create Performance Configuration Frame
  1997.    ======================================
  1998. */
  1999.   performance_frame = (Frame)xv_create (frame, FRAME_CMD,
  2000.                     FRAME_LABEL, "Performance Configuration",
  2001.                     XV_WIDTH, 400,
  2002.                     XV_HEIGHT, 100,
  2003.                     NULL);
  2004.  
  2005.   performance_panel = (Panel)xv_get (performance_frame, FRAME_CMD_PANEL,
  2006.                      NULL);
  2007.  
  2008.   ypos = 10;
  2009.   refresh_slider = (Panel_item)xv_create (performance_panel, PANEL_SLIDER,
  2010.                       PANEL_VALUE_X, 155,
  2011.                       PANEL_VALUE_Y, ypos,
  2012.                       PANEL_LAYOUT, PANEL_HORIZONTAL,
  2013.                       PANEL_LABEL_STRING, "Screen Refresh Rate",
  2014.                       PANEL_VALUE, refresh_rate,
  2015.                       PANEL_MIN_VALUE, 1,
  2016.                       PANEL_MAX_VALUE, 32,
  2017.                       PANEL_SLIDER_WIDTH, 100,
  2018.                       PANEL_TICKS, 32,
  2019.                       PANEL_NOTIFY_PROC, refresh_callback,
  2020.                       NULL);
  2021.   ypos += 25;
  2022.  
  2023.   xv_create (performance_panel, PANEL_BUTTON,
  2024.          XV_X, 180,
  2025.          XV_Y, 75,
  2026.          PANEL_LABEL_STRING, "OK",
  2027.          PANEL_NOTIFY_PROC, performance_ok_callback,
  2028.          NULL);
  2029. /*
  2030.    ====================
  2031.    Get X Window Objects
  2032.    ====================
  2033. */
  2034.   display = (Display*)xv_get(frame, XV_DISPLAY);
  2035.   if (!display)
  2036.     {
  2037.       printf ("Failed to open display\n");
  2038.       exit (1);
  2039.     }
  2040.  
  2041.   screen = XDefaultScreenOfDisplay (display);
  2042.   if (!screen)
  2043.     {
  2044.       printf ("Unable to get screen\n");
  2045.       exit (1);
  2046.     }
  2047.  
  2048.   visual = XDefaultVisualOfScreen (screen);
  2049.   if (!visual)
  2050.     {
  2051.       printf ("Unable to get visual\n");
  2052.       exit (1);
  2053.     }
  2054.  
  2055.   window = (Window)xv_get(canvas_paint_window(canvas), XV_XID);
  2056.   depth = XDefaultDepthOfScreen (screen);
  2057.   defcmap = XDefaultColormapOfScreen(screen);
  2058.   if (private_cmap)
  2059.     {
  2060.     cmap = XCreateColormap (display,
  2061.                             window,
  2062.                             visual,
  2063.                             AllocNone);
  2064.     XSetWindowColormap(display, window, cmap);
  2065.     XInstallColormap(display, cmap);
  2066.     }
  2067.   else
  2068.     cmap = defcmap;
  2069.  
  2070.   chooser = (Frame)xv_create (frame, FILE_CHOOSER,
  2071.                   FILE_CHOOSER_TYPE, FILE_CHOOSER_OPEN,
  2072.                   NULL);
  2073.  
  2074.   xv_set (canvas_paint_window(canvas),
  2075.       WIN_EVENT_PROC, event_proc,
  2076.       WIN_CONSUME_EVENTS, WIN_ASCII_EVENTS, WIN_MOUSE_BUTTONS, NULL,
  2077.       NULL);
  2078. #endif
  2079.  
  2080. #ifdef MOTIF
  2081.   {
  2082.     Widget menubar;
  2083.  
  2084.     XmString s_system;
  2085.     XmString s_boot_disk;
  2086.     XmString s_insert_disk;
  2087.     XmString s_eject_disk;
  2088.     XmString s_disable_drive;
  2089.     XmString s_insert_cart;
  2090.     XmString s_remove_cart;
  2091.     XmString s_enable_pill;
  2092.     XmString s_osa;
  2093.     XmString s_osb;
  2094.     XmString s_osxl;
  2095.     XmString s_osxe;
  2096.     XmString s_os5200;
  2097.     XmString s_exit;
  2098.  
  2099.     XmString s_console;
  2100.     XmString s_option;
  2101.     XmString s_select;
  2102.     XmString s_start;
  2103.     XmString s_help;
  2104.     XmString s_break;
  2105.     XmString s_warmstart;
  2106.     XmString s_coldstart;
  2107.  
  2108.     XmString s_label;
  2109.  
  2110.     XmString s_d1, s_d2, s_d3, s_d4;
  2111.     XmString s_d5, s_d6, s_d7, s_d8;
  2112.  
  2113.     char *tmpstr;
  2114.     XmString xmtmpstr;
  2115.  
  2116.     Arg args[8];
  2117.     int n;
  2118.  
  2119.     main_w = XtVaCreateManagedWidget ("main_window",
  2120.                       xmMainWindowWidgetClass, toplevel,
  2121.                       NULL);
  2122.  
  2123.     s_system = XmStringCreateSimple ("System");
  2124.     s_boot_disk = XmStringCreateSimple ("Boot Disk...");
  2125.     s_insert_disk = XmStringCreateSimple ("Insert Disk...");
  2126.     s_eject_disk = XmStringCreateSimple ("Eject Disk");
  2127.     s_disable_drive = XmStringCreateSimple ("Disable Drive");
  2128.     s_insert_cart = XmStringCreateSimple ("Insert Cartridge...");
  2129.     s_remove_cart = XmStringCreateSimple ("Remove Cartridge");
  2130.     s_enable_pill = XmStringCreateSimple ("Enable PILL");
  2131.     s_osa = XmStringCreateSimple ("Atari 800 OS/A");
  2132.     s_osb = XmStringCreateSimple ("Atari 800 OS/B");
  2133.     s_osxl = XmStringCreateSimple ("Atari 800XL");
  2134.     s_osxe = XmStringCreateSimple ("Atari 130XE");
  2135.     s_os5200 = XmStringCreateSimple ("Atari 5200");
  2136.     s_exit = XmStringCreateSimple ("Exit");
  2137.  
  2138.     s_console = XmStringCreateSimple ("Console");
  2139.     s_option = XmStringCreateSimple ("Option");
  2140.     s_select = XmStringCreateSimple ("Select");
  2141.     s_start = XmStringCreateSimple ("Start");
  2142.     s_help = XmStringCreateSimple ("Help");
  2143.     s_break = XmStringCreateSimple ("Break");
  2144.     s_warmstart = XmStringCreateSimple ("Warmstart");
  2145.     s_coldstart = XmStringCreateSimple ("Coldstart");
  2146. ;
  2147.     menubar = XmVaCreateSimpleMenuBar (main_w, "menubar",
  2148.                        XmVaCASCADEBUTTON, s_system, 'S',
  2149.                        XmVaCASCADEBUTTON, s_console, 'C',
  2150.                        NULL);
  2151.  
  2152.     system_menu =
  2153.     XmVaCreateSimplePulldownMenu (menubar, "system_menu", 0, motif_system_cback,
  2154.                   XmVaPUSHBUTTON, s_boot_disk, 'o', NULL, NULL,
  2155.                   XmVaPUSHBUTTON, s_insert_disk, 'I', NULL, NULL,
  2156.                   XmVaCASCADEBUTTON, s_eject_disk, 'j',
  2157.                   XmVaCASCADEBUTTON, s_disable_drive, 'D',
  2158.                   XmVaSEPARATOR,
  2159.                   XmVaPUSHBUTTON, s_insert_cart, 'n', NULL, NULL,
  2160.                   XmVaPUSHBUTTON, s_remove_cart, 'R', NULL, NULL,
  2161.                   XmVaPUSHBUTTON, s_enable_pill, 'P', NULL, NULL,
  2162.                   XmVaSEPARATOR,
  2163.                   XmVaPUSHBUTTON, s_osa, 'A', NULL, NULL,
  2164.                   XmVaPUSHBUTTON, s_osb, 'B', NULL, NULL,
  2165.                   XmVaPUSHBUTTON, s_osxl, 'L', NULL, NULL,
  2166.                   XmVaPUSHBUTTON, s_osxe, 'E', NULL, NULL,
  2167.                   XmVaPUSHBUTTON, s_os5200, '5', NULL, NULL,
  2168.                   XmVaSEPARATOR,
  2169.                   XmVaPUSHBUTTON, s_exit, 'x', NULL, NULL,
  2170.                   NULL);
  2171.  
  2172.     XmVaCreateSimplePulldownMenu (menubar, "console_menu", 1, motif_consol_cback,
  2173.                   XmVaPUSHBUTTON, s_option, 'O', NULL, NULL,
  2174.                   XmVaPUSHBUTTON, s_select, 't', NULL, NULL,
  2175.                   XmVaPUSHBUTTON, s_start, 'S', NULL, NULL,
  2176.                   XmVaSEPARATOR,
  2177.                   XmVaPUSHBUTTON, s_help, 'H', NULL, NULL,
  2178.                   XmVaPUSHBUTTON, s_break, 'B', NULL, NULL,
  2179.                   XmVaSEPARATOR,
  2180.                   XmVaPUSHBUTTON, s_warmstart, 'W', NULL, NULL,
  2181.                   XmVaPUSHBUTTON, s_coldstart, 'C', NULL, NULL,
  2182.                   NULL);
  2183.  
  2184.     XmStringFree (s_system);
  2185.     XmStringFree (s_boot_disk);
  2186.     XmStringFree (s_insert_disk);
  2187.     XmStringFree (s_eject_disk);
  2188.     XmStringFree (s_disable_drive);
  2189.     XmStringFree (s_insert_cart);
  2190.     XmStringFree (s_remove_cart);
  2191.     XmStringFree (s_enable_pill);
  2192.     XmStringFree (s_osa);
  2193.     XmStringFree (s_osb);
  2194.     XmStringFree (s_osxl);
  2195.     XmStringFree (s_osxe);
  2196.     XmStringFree (s_os5200);
  2197.     XmStringFree (s_exit);
  2198.  
  2199.     XmStringFree (s_console);
  2200.     XmStringFree (s_option);
  2201.     XmStringFree (s_select);
  2202.     XmStringFree (s_start);
  2203.     XmStringFree (s_help);
  2204.     XmStringFree (s_break);
  2205.     XmStringFree (s_warmstart);
  2206.     XmStringFree (s_coldstart);
  2207.  
  2208.     XtManageChild (menubar);
  2209.  
  2210.     fsel_b = XmCreateFileSelectionDialog (toplevel, "boot_disk", NULL, 0);
  2211.     XtAddCallback (fsel_b, XmNokCallback, motif_boot_disk, NULL);
  2212.     XtAddCallback (fsel_b, XmNcancelCallback, motif_fs_cancel, NULL);
  2213.  
  2214.     fsel_d = XmCreateFileSelectionDialog (toplevel, "load_disk", NULL, 0);
  2215.     XtAddCallback (fsel_d, XmNokCallback, motif_insert_disk, NULL);
  2216.     XtAddCallback (fsel_d, XmNcancelCallback, motif_fs_cancel, NULL);
  2217.  
  2218.     n = 0;
  2219.     XtSetArg(args[n], XmNradioBehavior, True); n++;
  2220.     XtSetArg(args[n], XmNradioAlwaysOne, True); n++;
  2221.     XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++;
  2222.     rbox_d = XmCreateWorkArea(fsel_d, "rbox_d", args, n);
  2223.     XtManageChild(rbox_d);
  2224.  
  2225.     s_label = XmStringCreateSimple("D1:");
  2226.     n = 0;
  2227.     XtSetArg(args[n], XmNlabelString, s_label); n++;
  2228.     XtSetArg(args[n], XmNset, True); n++;
  2229.     togg_d1 = XmCreateToggleButtonGadget(rbox_d, "togg_d1", args, n);
  2230.     XtManageChild(togg_d1);
  2231.     XmStringFree(s_label);
  2232.     XtAddCallback (togg_d1, XmNarmCallback, motif_select_disk, (XtPointer) 1);
  2233.  
  2234.     s_label = XmStringCreateSimple("D2:");
  2235.     n = 0;
  2236.     XtSetArg(args[n], XmNlabelString, s_label); n++;
  2237.     togg_d2 = XmCreateToggleButtonGadget(rbox_d, "togg_d2", args, n);
  2238.     XtManageChild(togg_d2);
  2239.     XmStringFree(s_label);
  2240.     XtAddCallback (togg_d2, XmNarmCallback, motif_select_disk, (XtPointer) 2);
  2241.  
  2242.     s_label = XmStringCreateSimple("D3:");
  2243.     n = 0;
  2244.     XtSetArg(args[n], XmNlabelString, s_label); n++;
  2245.     togg_d3 = XmCreateToggleButtonGadget(rbox_d, "togg_d3", args, n);
  2246.     XtManageChild(togg_d3);
  2247.     XmStringFree(s_label);
  2248.     XtAddCallback (togg_d3, XmNarmCallback, motif_select_disk, (XtPointer) 3);
  2249.  
  2250.     s_label = XmStringCreateSimple("D4:");
  2251.     n = 0;
  2252.     XtSetArg(args[n], XmNlabelString, s_label); n++;
  2253.     togg_d4 = XmCreateToggleButtonGadget(rbox_d, "togg_d4", args, n);
  2254.     XtManageChild(togg_d4);
  2255.     XmStringFree(s_label);
  2256.     XtAddCallback (togg_d4, XmNarmCallback, motif_select_disk, (XtPointer) 4);
  2257.  
  2258.     s_label = XmStringCreateSimple("D5:");
  2259.     n = 0;
  2260.     XtSetArg(args[n], XmNlabelString, s_label); n++;
  2261.     togg_d5 = XmCreateToggleButtonGadget(rbox_d, "togg_d5", args, n);
  2262.     XtManageChild(togg_d5);
  2263.     XmStringFree(s_label);
  2264.     XtAddCallback (togg_d5, XmNarmCallback, motif_select_disk, (XtPointer) 5);
  2265.  
  2266.     s_label = XmStringCreateSimple("D6:");
  2267.     n = 0;
  2268.     XtSetArg(args[n], XmNlabelString, s_label); n++;
  2269.     togg_d6 = XmCreateToggleButtonGadget(rbox_d, "togg_d6", args, n);
  2270.     XtManageChild(togg_d6);
  2271.     XmStringFree(s_label);
  2272.     XtAddCallback (togg_d6, XmNarmCallback, motif_select_disk, (XtPointer) 6);
  2273.  
  2274.     s_label = XmStringCreateSimple("D7:");
  2275.     n = 0;
  2276.     XtSetArg(args[n], XmNlabelString, s_label); n++;
  2277.     togg_d7 = XmCreateToggleButtonGadget(rbox_d, "togg_d7", args, n);
  2278.     XtManageChild(togg_d7);
  2279.     XmStringFree(s_label);
  2280.     XtAddCallback (togg_d7, XmNarmCallback, motif_select_disk, (XtPointer) 7);
  2281.  
  2282.     s_label = XmStringCreateSimple("D8:");
  2283.     n = 0;
  2284.     XtSetArg(args[n], XmNlabelString, s_label); n++;
  2285.     togg_d8 = XmCreateToggleButtonGadget(rbox_d, "togg_d8", args, n);
  2286.     XtManageChild(togg_d8);
  2287.     XmStringFree(s_label);
  2288.     XtAddCallback (togg_d8, XmNarmCallback, motif_select_disk, (XtPointer) 8);
  2289.  
  2290.  
  2291.     fsel_r = XmCreateFileSelectionDialog (toplevel, "load_rom", NULL, 0);
  2292.     XtAddCallback (fsel_r, XmNokCallback, motif_insert_rom, NULL);
  2293.     XtAddCallback (fsel_r, XmNcancelCallback, motif_fs_cancel, NULL);
  2294.  
  2295.     n = 0;
  2296.     XtSetArg(args[n], XmNradioBehavior, True); n++;
  2297.     XtSetArg(args[n], XmNradioAlwaysOne, True); n++;
  2298.     rbox_r = XmCreateWorkArea(fsel_r, "rbox_r", args, n);
  2299.     XtManageChild(rbox_r);
  2300.  
  2301.     s_label = XmStringCreateSimple("8K");
  2302.     n = 0;
  2303.     XtSetArg(args[n], XmNlabelString, s_label); n++;
  2304.     XtSetArg(args[n], XmNset, True); n++;
  2305.     togg_8k = XmCreateToggleButtonGadget(rbox_r, "togg_8k", args, n);
  2306.     XtManageChild(togg_8k);
  2307.     XmStringFree(s_label);
  2308.     XtAddCallback (togg_8k, XmNarmCallback, motif_select_rom, (XtPointer) 1);
  2309.  
  2310.     s_label = XmStringCreateSimple("16K");
  2311.     n = 0;
  2312.     XtSetArg(args[n], XmNlabelString, s_label); n++;
  2313.     togg_16k = XmCreateToggleButtonGadget(rbox_r, "togg_16k", args, n);
  2314.     XtManageChild(togg_16k);
  2315.     XmStringFree(s_label);
  2316.     XtAddCallback (togg_16k, XmNarmCallback, motif_select_rom, (XtPointer) 2);
  2317.  
  2318.     s_label = XmStringCreateSimple("OSS 16K Bank Switched");
  2319.     n = 0;
  2320.     XtSetArg(args[n], XmNlabelString, s_label); n++;
  2321.     togg_oss = XmCreateToggleButtonGadget(rbox_r, "togg_oss", args, n);
  2322.     XtManageChild(togg_oss);
  2323.     XmStringFree(s_label);
  2324.     XtAddCallback (togg_oss, XmNarmCallback, motif_select_rom, (XtPointer) 3);
  2325.  
  2326.     s_label = XmStringCreateSimple("DB 32K Bank Switched");
  2327.     n = 0;
  2328.     XtSetArg(args[n], XmNlabelString, s_label); n++;
  2329.     togg_32k = XmCreateToggleButtonGadget(rbox_r, "togg_32k", args, n);
  2330.     XtManageChild(togg_32k);
  2331.     XmStringFree(s_label);
  2332.     XtAddCallback (togg_32k, XmNarmCallback, motif_select_rom, (XtPointer) 4);
  2333.  
  2334.     s_label = XmStringCreateSimple("5200 32K");
  2335.     n = 0;
  2336.     XtSetArg(args[n], XmNlabelString, s_label); n++;
  2337.     togg_5200 = XmCreateToggleButtonGadget(rbox_r, "togg_5200", args, n);
  2338.     XtManageChild(togg_5200);
  2339.     XmStringFree(s_label);
  2340.     XtAddCallback (togg_5200, XmNarmCallback, motif_select_rom, (XtPointer) 5);
  2341.  
  2342.     tmpstr = (char *) XtMalloc(strlen(atari_disk_dir + 3));
  2343.     strcpy(tmpstr, atari_disk_dir);
  2344.     strcat(tmpstr, "/*");
  2345.     xmtmpstr = XmStringCreateSimple(tmpstr);
  2346.     XmFileSelectionDoSearch(fsel_b, xmtmpstr);
  2347.     XmFileSelectionDoSearch(fsel_d, xmtmpstr);
  2348.     XmStringFree(xmtmpstr);
  2349.     XtFree(tmpstr);
  2350.  
  2351.     tmpstr = (char *) XtMalloc(strlen(atari_rom_dir + 3));
  2352.     strcpy(tmpstr, atari_rom_dir);
  2353.     strcat(tmpstr, "/*");
  2354.     xmtmpstr = XmStringCreateSimple(tmpstr);
  2355.     XmFileSelectionDoSearch(fsel_r, xmtmpstr);
  2356.     XmStringFree(xmtmpstr);
  2357.     XtFree(tmpstr);
  2358.  
  2359.     s_d1 = XmStringCreateSimple("D1:");
  2360.     s_d2 = XmStringCreateSimple("D2:");
  2361.     s_d3 = XmStringCreateSimple("D3:");
  2362.     s_d4 = XmStringCreateSimple("D4:");
  2363.     s_d5 = XmStringCreateSimple("D5:");
  2364.     s_d6 = XmStringCreateSimple("D6:");
  2365.     s_d7 = XmStringCreateSimple("D7:");
  2366.     s_d8 = XmStringCreateSimple("D8:");
  2367.     eject_menu = XmVaCreateSimplePulldownMenu(system_menu,
  2368.                           "eject_disk", 2,
  2369.                           motif_eject_cback,
  2370.                        XmVaPUSHBUTTON, s_d1, '1', NULL, NULL,
  2371.                        XmVaPUSHBUTTON, s_d2, '2', NULL, NULL,
  2372.                        XmVaPUSHBUTTON, s_d3, '3', NULL, NULL,
  2373.                        XmVaPUSHBUTTON, s_d4, '4', NULL, NULL,
  2374.                        XmVaPUSHBUTTON, s_d5, '5', NULL, NULL,
  2375.                        XmVaPUSHBUTTON, s_d6, '6', NULL, NULL,
  2376.                        XmVaPUSHBUTTON, s_d7, '7', NULL, NULL,
  2377.                        XmVaPUSHBUTTON, s_d8, '8', NULL, NULL,
  2378.                        NULL);
  2379.     disable_menu = XmVaCreateSimplePulldownMenu(system_menu,
  2380.                           "disable_disk", 3,
  2381.                           motif_disable_cback,
  2382.                        XmVaPUSHBUTTON, s_d1, '1', NULL, NULL,
  2383.                        XmVaPUSHBUTTON, s_d2, '2', NULL, NULL,
  2384.                        XmVaPUSHBUTTON, s_d3, '3', NULL, NULL,
  2385.                        XmVaPUSHBUTTON, s_d4, '4', NULL, NULL,
  2386.                        XmVaPUSHBUTTON, s_d5, '5', NULL, NULL,
  2387.                        XmVaPUSHBUTTON, s_d6, '6', NULL, NULL,
  2388.                        XmVaPUSHBUTTON, s_d7, '7', NULL, NULL,
  2389.                        XmVaPUSHBUTTON, s_d8, '8', NULL, NULL,
  2390.                        NULL);
  2391.     XmStringFree(s_d1);
  2392.     XmStringFree(s_d2);
  2393.     XmStringFree(s_d3);
  2394.     XmStringFree(s_d4);
  2395.     XmStringFree(s_d5);
  2396.     XmStringFree(s_d6);
  2397.     XmStringFree(s_d7);
  2398.     XmStringFree(s_d8);
  2399.  
  2400.     drawing_area = XtVaCreateManagedWidget ("Canvas",
  2401.                         xmDrawingAreaWidgetClass, main_w,
  2402.                         XmNunitType, XmPIXELS,
  2403.                         XmNheight, window_height,
  2404.                         XmNwidth, window_width,
  2405.                         XmNresizePolicy, XmNONE,
  2406.                         NULL);
  2407.  
  2408.  
  2409.     {
  2410.     XKeyboardState state;
  2411.     XGetKeyboardControl(XtDisplay(drawing_area), &state);
  2412.  
  2413.     XCURRENTAUTOREPEAT=XTERNAUTOREPEAT=state.global_auto_repeat;
  2414.     }
  2415.  
  2416.     XtAddEventHandler (drawing_area,
  2417.                KeyPressMask | KeyReleaseMask,
  2418.                False,
  2419.                motif_keypress, NULL);
  2420.  
  2421.     XtAddEventHandler (drawing_area,
  2422.                ExposureMask, 
  2423.                False,
  2424.                motif_exposure, NULL);
  2425.  
  2426.     XtAddEventHandler (drawing_area,
  2427.                EnterWindowMask, 
  2428.                False,
  2429.                motif_enter, NULL);
  2430.  
  2431.     XtAddEventHandler (drawing_area,
  2432.                LeaveWindowMask, 
  2433.                False,
  2434.                motif_leave, NULL);
  2435.  
  2436.     XtRealizeWidget (toplevel);
  2437.   }
  2438.   display = XtDisplay (drawing_area);
  2439.  
  2440.   window = XtWindow (drawing_area);
  2441.  
  2442.   screen = XDefaultScreenOfDisplay (display);
  2443.   if (!screen)
  2444.     {
  2445.       printf ("Unable to get screen\n");
  2446.       exit (1);
  2447.     }
  2448.  
  2449.   visual = XDefaultVisualOfScreen (screen);
  2450.   if (!visual)
  2451.     {
  2452.       printf ("Unable to get visual\n");
  2453.       exit (1);
  2454.     }
  2455.  
  2456.   depth = XDefaultDepthOfScreen (screen);
  2457.  
  2458.   defcmap = XDefaultColormapOfScreen(screen);
  2459.   if (private_cmap)
  2460.     {
  2461.     cmap = XCreateColormap (display,
  2462.                             window,
  2463.                             visual,
  2464.                             AllocNone);
  2465.     XSetWindowColormap(display, window, cmap);
  2466.     XInstallColormap(display, cmap);
  2467.     }
  2468.   else
  2469.     cmap = defcmap;
  2470. #endif
  2471.  
  2472. #ifndef MOTIF
  2473. #ifndef XVIEW
  2474.   display = XOpenDisplay (NULL);
  2475.   if (!display)
  2476.     {
  2477.       printf ("Failed to open display\n");
  2478.       exit (1);
  2479.     }
  2480.  
  2481.   screen = XDefaultScreenOfDisplay (display);
  2482.   if (!screen)
  2483.     {
  2484.       printf ("Unable to get screen\n");
  2485.       exit (1);
  2486.     }
  2487.  
  2488.   visual = XDefaultVisualOfScreen (screen);
  2489.   if (!visual)
  2490.     {
  2491.       printf ("Unable to get visual\n");
  2492.       exit (1);
  2493.     }
  2494.  
  2495.   depth = XDefaultDepthOfScreen (screen);
  2496.  
  2497.   defcmap = XDefaultColormapOfScreen(screen);
  2498.   if (private_cmap)
  2499.     {
  2500.     cmap = XCreateColormap (display,
  2501.                             XRootWindowOfScreen(screen),
  2502.                             visual,
  2503.                             AllocNone);
  2504.     XInstallColormap(display, cmap);
  2505.     }
  2506.   else
  2507.     cmap = XDefaultColormapOfScreen(screen);
  2508.  
  2509.   xswda.event_mask = KeyPressMask | KeyReleaseMask | ExposureMask;
  2510.   xswda.colormap = cmap;
  2511.  
  2512.   window = XCreateWindow (display,
  2513.               XRootWindowOfScreen(screen),
  2514.               50, 50,
  2515.               window_width, window_height, 3, depth,
  2516.               InputOutput, visual,
  2517.               CWEventMask | CWBackPixel | CWColormap,
  2518.               &xswda);
  2519.  
  2520.   XStoreName (display, window, ATARI_TITLE);
  2521. #endif
  2522. #endif
  2523.  
  2524. #ifdef SHM
  2525.   {
  2526.     int major;
  2527.     int minor;
  2528.     Bool pixmaps;
  2529.     Status status;
  2530.  
  2531.     status = XShmQueryVersion (display, &major, &minor, &pixmaps);
  2532.     if (!status)
  2533.       {
  2534.     printf ("X Shared Memory extensions not available\n");
  2535.     exit (1);
  2536.       }
  2537.  
  2538.     printf ("Using X11 Shared Memory Extensions\n");
  2539.  
  2540.     image = XShmCreateImage (display, visual, depth, ZPixmap,
  2541.                  NULL, &shminfo, window_width, window_height);
  2542.  
  2543.     shminfo.shmid = shmget (IPC_PRIVATE,
  2544.                 (ATARI_HEIGHT+16) * ATARI_WIDTH,
  2545.                 IPC_CREAT | 0777);
  2546.     shminfo.shmaddr = image->data = atari_screen = shmat (shminfo.shmid, 0, 0);
  2547.     shminfo.readOnly = False;
  2548.  
  2549.     XShmAttach (display, &shminfo);
  2550.  
  2551. #ifndef NOSYNC
  2552.     XSync (display, False);
  2553. #endif
  2554.  
  2555.     shmctl (shminfo.shmid, IPC_RMID, 0);
  2556.   }
  2557. #else
  2558.   pixmap = XCreatePixmap (display, window,
  2559.               window_width, window_height, depth);
  2560. #endif
  2561.  
  2562.  
  2563.  
  2564.  
  2565. /*            ALLOCATE COLORS
  2566.     - 1st:  Allocate 128 colors to fill every second spot in the color
  2567.         grid.  Actually, that's 120, since hue 1 == hue 15
  2568.       I NEED AT LEAST THAT MUCH
  2569. */
  2570.  
  2571.  for (i=0;i<256;i+=2)
  2572.     {
  2573.       XColor    colour;
  2574.       int    rgb = colortable[i];
  2575.       int    status;
  2576.  
  2577.       colour.red = (rgb & 0x00ff0000) >> 8;
  2578.       colour.green = (rgb & 0x0000ff00);
  2579.       colour.blue = (rgb & 0x000000ff) << 8;
  2580.       
  2581.       status = XAllocColor (display,
  2582.                 cmap,
  2583.                 &colour);
  2584.  
  2585.       if (status)
  2586.     colours[i] = colour.pixel;
  2587.       else
  2588.     {
  2589.     printf("Failed to get at least 120 different colors.\n"
  2590.         "Try -private_cmap.\n");
  2591.     exit(1);
  2592.     }
  2593.     }
  2594.  
  2595.  
  2596. /*
  2597.     - 2nd:  Allocate all the rest of hue 0 (b/w) and hue 1 (brown)
  2598.       THESE ARE USED MOST OFTEN.  BUT I DON'T REALLY NEED THEM.
  2599. */
  2600.   for (i=1; i<32; i+=2)
  2601.     {
  2602.     XColor    colour;
  2603.     int       rgb = colortable[i];
  2604.     int       status;
  2605.  
  2606.     colour.red = (rgb & 0x00ff0000) >> 8;
  2607.     colour.green = (rgb & 0x0000ff00);
  2608.     colour.blue = (rgb & 0x000000ff) << 8;
  2609.  
  2610.     status = XAllocColor (display,
  2611.                             cmap,
  2612.                             &colour);
  2613.     if (status)
  2614.         colours[i]=colour.pixel;
  2615.     else
  2616.         {
  2617.         colours[i]=colours[i-1];
  2618.         missing_colors++;
  2619.         }
  2620.     }
  2621.  
  2622.  
  2623. /*
  2624.     - 3rd:    Try to allocate all the rest (odd) colors.  Darkest Colors
  2625.         first, since they are the most discernible.
  2626. */
  2627.  
  2628.   for (i=1; i<16; i+=2)
  2629.     {
  2630.     int hue;
  2631.     
  2632.     for (hue=2; hue<16; hue++)
  2633.         {
  2634.         XColor    colour;
  2635.               int    rgb = colortable[hue*16 +i];
  2636.               int    status;
  2637.  
  2638.               colour.red = (rgb & 0x00ff0000) >> 8;
  2639.               colour.green = (rgb & 0x0000ff00);
  2640.               colour.blue = (rgb & 0x000000ff) << 8;
  2641.       
  2642.               status = XAllocColor (display,
  2643.                 cmap,
  2644.                 &colour);
  2645.  
  2646.         if (status)
  2647.             colours[hue*16 + i] = colour.pixel;
  2648.         else
  2649.             {
  2650.             colours[hue*16 + i] = colours[hue*16 +i -1];
  2651.             missing_colors++;
  2652.             }
  2653.         }
  2654.     }
  2655.  
  2656.  
  2657.  
  2658. /*
  2659.     BTW:    Contrary to public (and my prior) belief, the Atari had only
  2660.         225 colors, NOT 255.  Hue 1 == Hue 15.  And Brightness 7 ==
  2661.         Brightness 8.
  2662. */
  2663.  
  2664.   if (missing_colors)
  2665.     printf("Missed %d of 225 colors.  Winging it.\n"
  2666.         "Try -private_cmap.\n",missing_colors);
  2667.  
  2668.  
  2669.  
  2670. #ifdef SHM
  2671.   for(i=0;i<256;i++)
  2672.     colour_translation_table[i] = colours[i];
  2673. #endif
  2674.  
  2675.   for (i=0;i<256;i++)
  2676.     {
  2677.       xgcvl.background = colours[0];
  2678.       xgcvl.foreground = colours[i];
  2679.  
  2680.       gc_colour[i] = XCreateGC (display, window,
  2681.                 GCForeground | GCBackground,
  2682.                 &xgcvl);
  2683.     }
  2684.  
  2685.   xgcvl.background = colours[0];
  2686.   xgcvl.foreground = colours[0];
  2687.  
  2688.   gc = XCreateGC (display, window,
  2689.           GCForeground | GCBackground,
  2690.           &xgcvl);
  2691.  
  2692. #ifndef SHM
  2693.   XFillRectangle (display, pixmap, gc, 0, 0,
  2694.           window_width, window_height);
  2695. #endif
  2696.  
  2697.   XMapWindow (display, window);
  2698.  
  2699. /* ============================
  2700.     Find NUMLOCKMASK
  2701.    ============================
  2702.  
  2703.    This is not currently needed, but it's interesting code, and could be
  2704.    used later on.  Essentially, we find the mask that tells us whether or
  2705.    not the numlock key is lit (which is transmitted with each KeyPress Event).
  2706. */
  2707.  
  2708.   {
  2709.   int symperkey;
  2710.   int keys_min, keys_max;
  2711.   KeySym *keysym;
  2712.   XModifierKeymap *modkm;
  2713.   KeyCode numlock =0x7e;         /* default for NUMLOCK on my system */
  2714.  
  2715.  
  2716.   XDisplayKeycodes(display, &keys_min, &keys_max);
  2717.  
  2718.   keysym=XGetKeyboardMapping(display, keys_min, keys_max +1 -keys_min, &symperkey);
  2719.  
  2720.   if (keysym)
  2721.     {
  2722.     int icode, isym;
  2723.     for (icode=keys_min; icode <= keys_max; icode++)
  2724.         for (isym=0; isym<symperkey; isym++)
  2725.         if (keysym[(icode -keys_min) * symperkey + isym] == XK_Num_Lock)
  2726.             numlock=icode;
  2727.     }
  2728.   XFree(keysym);
  2729.   keysym=NULL;
  2730.  
  2731.  
  2732.   modkm=XGetModifierMapping(display);
  2733.   if (modkm)
  2734.     {
  2735.     int imod, icode;
  2736.     for (imod=0; imod<8; imod++)
  2737.         for (icode=0; icode<modkm->max_keypermod; icode++)
  2738.         if ((modkm->modifiermap)[imod * modkm->max_keypermod + icode] == numlock)
  2739.             NUMLOCKMASK=(1<<imod);
  2740.     }
  2741.   XFreeModifiermap(modkm);
  2742.   modkm=NULL;
  2743.   }
  2744.  
  2745.  
  2746.  
  2747.  
  2748.  
  2749. #ifndef NOSYNC
  2750.   XSync (display, False);
  2751. #endif
  2752. /*
  2753.    ============================
  2754.    Storage for Atari 800 Screen
  2755.    ============================
  2756. */
  2757.   image_data = (UBYTE*) malloc (ATARI_WIDTH * ATARI_HEIGHT);
  2758.   if (!image_data)
  2759.     {
  2760.       printf ("Failed to allocate space for image\n");
  2761.       exit (1);
  2762.     }
  2763.  
  2764.  
  2765.   /* Preparation for Atari_Scanline_Flush() */
  2766.   switch(windowsize)
  2767.     {
  2768.     case Large:
  2769.         for(i=0; i<NPOINTS; i++)
  2770.               {
  2771.             rectangles[i].width = 2;
  2772.             rectangles[i].height = 2;
  2773.             }
  2774.         break;
  2775.     case Huge:
  2776.         for(i=0; i<NPOINTS; i++)
  2777.               {
  2778.             rectangles[i].width = 3;
  2779.             rectangles[i].height = 3;
  2780.             }
  2781.         break;
  2782.     default:
  2783.         break;
  2784.     }
  2785.  
  2786.  
  2787.  
  2788.  
  2789.  
  2790.   keyboard_consol = 7;
  2791.   menu_consol = 7;
  2792.  
  2793.   if (x11bug)
  2794.     {
  2795.       printf ("Initial X11 controller configuration\n");
  2796.       printf ("------------------------------------\n\n");
  2797.       printf ("Keypad is "); Atari_WhatIs (keypad_mode); printf ("\n");
  2798.       printf ("Mouse is "); Atari_WhatIs (mouse_mode); printf ("\n");
  2799.       printf ("/dev/js0 is "); Atari_WhatIs (js0_mode); printf ("\n");
  2800.       printf ("/dev/js1 is "); Atari_WhatIs (js1_mode); printf ("\n");
  2801.     }
  2802.  
  2803.  
  2804. }
  2805.  
  2806. int Atari_Exit (int run_monitor)
  2807. {
  2808.   int restart;
  2809.  
  2810.   if (run_monitor)
  2811.     {
  2812. #ifdef MOTIF
  2813.         /* Don't know these, just using them to call motif_*() */
  2814.     Widget w;
  2815.     XtPointer client_data;
  2816.     XEvent event;
  2817.     Boolean ctd;
  2818.  
  2819.     motif_leave(w, client_data, &event, &ctd);
  2820. #endif
  2821.  
  2822.         restart = monitor();
  2823.  
  2824. #ifdef MOTIF
  2825.     if (restart)
  2826.         motif_enter(w, client_data, &event, &ctd);
  2827. #endif
  2828.     }
  2829.   else
  2830.       restart = FALSE;
  2831.  
  2832.   if (!restart)
  2833.     {
  2834.       if (XTERNAUTOREPEAT != XCURRENTAUTOREPEAT)
  2835.     XAutoRepeatOn(display);
  2836.  
  2837.  
  2838.       free (image_data);
  2839.  
  2840.       XSync (display, True);
  2841.  
  2842.       if (private_cmap)
  2843.     {
  2844.     XUninstallColormap(display,cmap);
  2845.         XFreeColormap (display, cmap);
  2846.     }
  2847.  
  2848. #ifdef SHM
  2849.       XDestroyImage (image);
  2850. #else
  2851.       XFreePixmap (display, pixmap);
  2852. #endif
  2853.       XUnmapWindow (display, window);
  2854.       XDestroyWindow (display, window);
  2855.       XCloseDisplay (display);
  2856.       display=NULL;
  2857.  
  2858. #ifdef LINUX_JOYSTICK
  2859.       if (js0 != -1)
  2860.     close (js0);
  2861.  
  2862.       if (js1 != -1)
  2863.     close (js1);
  2864. #endif
  2865.  
  2866. #ifdef NAS
  2867.       NAS_Exit ();
  2868. #endif
  2869.  
  2870. #ifdef VOXWARE 
  2871.       Voxware_Exit ();
  2872. #endif
  2873.     }
  2874.  
  2875.   return restart;
  2876. }
  2877.  
  2878.  
  2879.  
  2880. #ifndef SHM
  2881. void Atari_ScanLine_Flush(void)
  2882. {
  2883.  
  2884.   if (npoints)
  2885.     {
  2886.     switch(windowsize)
  2887.     {
  2888.     case Small:
  2889.         XDrawPoints (display, pixmap, gc_colour[last_colour],
  2890.            points, npoints, CoordModeOrigin);
  2891.         break;
  2892.     case Large:
  2893.     case Huge:
  2894.         XFillRectangles (display, pixmap, gc_colour[last_colour],
  2895.                rectangles, npoints);
  2896.         break;
  2897.     }
  2898.     
  2899.     npoints = 0;
  2900.     modified = TRUE;
  2901.     }
  2902.   last_colour = -1;
  2903. }
  2904. #endif
  2905.  
  2906.  
  2907. void ScreenDump ()
  2908. {
  2909.   char *tmp_file_name=tempnam(NULL, "asd");
  2910.   char command[1028];
  2911.   static int frame_num = 0;
  2912.   unsigned char *ip;
  2913.   FILE *tf;
  2914.  
  2915.   if (!tmp_file_name)
  2916.     return;            /* error */
  2917.   tf=fopen(tmp_file_name, "w");
  2918.   if (!tf)
  2919.     return;            /* error */
  2920.  
  2921.     /* Write a ppm file */
  2922.   fprintf(tf, "P6\n%u %d\n255\n", ATARI_WIDTH, ATARI_HEIGHT);
  2923.   for (ip=image_data; ip< image_data + ATARI_WIDTH * ATARI_HEIGHT; ip++)
  2924.     fprintf(tf, "%c%c%c", (colortable[*ip] & 0xff0000) >> 16,
  2925.         (colortable[*ip] & 0xff00) >> 8, colortable[*ip] &0xff);
  2926.   fclose(tf);
  2927.   
  2928.   sprintf (command, "/bin/sh -pc 'ppmtogif %s > %d.gif 2>/dev/null'", tmp_file_name, frame_num++);
  2929.   system (command);
  2930.   unlink(tmp_file_name);
  2931.  
  2932.   free(tmp_file_name);
  2933. }
  2934.  
  2935.  
  2936. void RebuildScreen(register UBYTE *screen)
  2937. {
  2938. UBYTE *scanline_ptr = image_data;
  2939. register int xpos;
  2940. register int ypos;
  2941. register UBYTE colour;
  2942.  
  2943.   for (ypos=0;ypos<ATARI_HEIGHT;ypos++) {
  2944.       for (xpos=0;xpos<ATARI_WIDTH;xpos++) {
  2945.  
  2946.       colour = *screen++;
  2947.  
  2948.       if (colour != *scanline_ptr)
  2949.         {
  2950.  
  2951.           if ((npoints >= NPOINTS) || (colour != last_colour)) {
  2952.         Atari_ScanLine_Flush();
  2953.         last_colour = colour;
  2954.           }
  2955.  
  2956.           switch(windowsize) {
  2957.           case Small:
  2958.           points[npoints].x = xpos;
  2959.           points[npoints].y = ypos;
  2960.           break;
  2961.           case Large:
  2962.           rectangles[npoints].x = xpos << 1;
  2963.           rectangles[npoints].y = ypos << 1;
  2964.           break;
  2965.           case Huge:
  2966.           rectangles[npoints].x = xpos + xpos + xpos;
  2967.           rectangles[npoints].y = ypos + ypos + ypos;
  2968.           break;
  2969.           }
  2970.           npoints++;
  2971.           *scanline_ptr++ = colour;
  2972.         }
  2973.       else
  2974.         {
  2975.           scanline_ptr++;
  2976.         }
  2977.     }
  2978.         screen+=ATARI_EXTRA;
  2979.       
  2980.     }
  2981.  
  2982.   Atari_ScanLine_Flush ();
  2983.  
  2984.   if (modified) {
  2985.     XCopyArea (display, pixmap, window, gc, 0, 0,
  2986.            window_width, window_height, 0, 0);
  2987.   }
  2988.   modified = FALSE;
  2989.  
  2990. }
  2991.  
  2992. void Atari_DisplayScreen (UBYTE *screen)
  2993. {
  2994. #ifndef NOSTATUS
  2995.   static char status_line[64];
  2996.   int update_status_line;
  2997. #endif
  2998.  
  2999. #ifdef SHM
  3000.   XShmPutImage (display, window, gc, image, 0, 0, 0, 0,
  3001.         window_width, window_height, 0);
  3002.   XSync(display, FALSE);
  3003. #else
  3004.   RebuildScreen(screen);
  3005. #endif
  3006.  
  3007. #ifndef NOSTATUS
  3008.   switch (x11_monitor)
  3009.     {
  3010.     case MONITOR_SIO :
  3011.       if (sio_status[0] != '\0')
  3012.     {
  3013. #ifdef XVIEW
  3014.       strcpy (status_line, sio_status);
  3015. #else
  3016.       sprintf (status_line, "%s - %s",
  3017.            ATARI_TITLE, sio_status);
  3018. #endif
  3019.       sio_status[0] = '\0';
  3020.       update_status_line = TRUE;
  3021.     }
  3022.       else
  3023.     {
  3024.       update_status_line = FALSE;
  3025.     }
  3026.       break;
  3027.     case MONITOR_FPS :
  3028.       {
  3029.     double curtime;
  3030.  
  3031.     gettimeofday (&tp, &tzp);
  3032.     curtime = tp.tv_sec + (tp.tv_usec / 1000000.0);
  3033.  
  3034.     nframes++;
  3035.  
  3036.     if ((curtime - basetime) >= 2.0)
  3037.       {
  3038. #ifdef XVIEW
  3039.         sprintf (status_line, "%.2f FPS",
  3040.              (double)nframes / (curtime - basetime));
  3041. #else
  3042.         sprintf (status_line, " %s - %.2f FPS",
  3043.              ATARI_TITLE, (double)nframes / (curtime - basetime));
  3044. #endif
  3045.  
  3046.         nframes = 0;
  3047.         basetime = curtime;
  3048.       }
  3049.       }
  3050.       update_status_line = TRUE;
  3051.       break;
  3052.     default :
  3053.       update_status_line = FALSE;
  3054.       break;
  3055.     }
  3056.  
  3057.   if (update_status_line)
  3058.     {
  3059. #ifdef XVIEW
  3060.       xv_set (frame,
  3061.           FRAME_LEFT_FOOTER, status_line,
  3062.           NULL);
  3063. #else
  3064. #ifdef MOTIF
  3065.       XtVaSetValues(toplevel,
  3066.             XtNtitle, status_line,
  3067.             NULL);
  3068. #else
  3069.       XStoreName (display, window, status_line);
  3070. #endif
  3071. #endif
  3072.     }
  3073. #endif
  3074.  
  3075. /*             * this now moved to Atari_Keyboard () * 
  3076. #ifdef XVIEW
  3077.   notify_dispatch ();
  3078.   XFlush (display);
  3079. #endif
  3080.  
  3081. #ifdef MOTIF
  3082.   while (XtAppPending(app))
  3083.     {
  3084.       static XEvent event;
  3085.  
  3086.       XtAppNextEvent (app, &event);
  3087.       XtDispatchEvent (&event);
  3088.     }
  3089. #endif
  3090. */
  3091.  
  3092. #ifdef NAS
  3093.   NAS_UpdateSound ();
  3094. #endif
  3095.  
  3096. #ifdef VOXWARE
  3097.   Voxware_UpdateSound ();
  3098. #endif
  3099.  
  3100.   if (screen_dump)
  3101.     {
  3102.       ScreenDump ();
  3103.  
  3104.       if (screen_dump == 2)
  3105.         screen_dump = 0;
  3106.     }
  3107. }
  3108.  
  3109. int Atari_Keyboard (void)
  3110. {
  3111.   int    keycode = AKEY_NONE;
  3112.  
  3113.     /* About XSync:
  3114.        man XSync:   ... Client applications seldom need to call XSync.  ...
  3115.        In fact, calling XSync() does slow it down on some systems,
  3116.        especially if they were slow to begin with.
  3117.        However, it DOES speed things up on MY system, which is already
  3118.        fast.  It has something to do with how long the connection between
  3119.        caller and receiver is (so you should only do this if your DISPLAY
  3120.        is the local machine...)
  3121.     */
  3122. #ifndef NOSYNC
  3123.   XSync(display,False);
  3124. #endif
  3125.  
  3126.   do                /* PAUSE loop */
  3127.     {
  3128.  
  3129. #ifndef SHM
  3130.     if (modified)
  3131.     XCopyArea (display, pixmap, window, gc, 0, 0,
  3132.          window_width, window_height, 0, 0);
  3133. #endif
  3134.     modified=FALSE;
  3135.  
  3136.  
  3137. #ifdef XVIEW
  3138.     notify_dispatch ();
  3139.     XFlush (display);
  3140.  
  3141.     keycode = xview_keycode;
  3142.     xview_keycode = AKEY_NONE;
  3143. #else
  3144. #ifdef MOTIF
  3145.   while (XtAppPending(app))
  3146.     {
  3147.       static XEvent event;
  3148.  
  3149.       XtAppNextEvent (app, &event);
  3150.       XtDispatchEvent (&event);
  3151.     }
  3152.  
  3153.     keycode = xview_keycode;
  3154.     xview_keycode = AKEY_NONE;
  3155. #else
  3156.     while (XEventsQueued (display, QueuedAlready) > 0) /* QueuedAfterFlush */
  3157.     {
  3158.     XEvent    event;
  3159.  
  3160.     XNextEvent (display, &event);
  3161.     keycode = GetKeyCode (&event);
  3162.     }
  3163. #endif
  3164. #endif
  3165.  
  3166.  
  3167.  
  3168.     } while (paused);
  3169.   return keycode;
  3170. }
  3171.  
  3172. void mouse_joystick (int mode)
  3173. {
  3174.   Window root_return;
  3175.   Window child_return;
  3176.   int root_x_return;
  3177.   int root_y_return;
  3178.   int win_x_return;
  3179.   int win_y_return;
  3180.   unsigned int mask_return;
  3181.  
  3182.   mouse_stick = 0x0f;
  3183.  
  3184.   XQueryPointer (display, window, &root_return, &child_return,
  3185.          &root_x_return, &root_y_return,
  3186.          &win_x_return, &win_y_return,
  3187.          &mask_return);
  3188.  
  3189.   if (mode < 5)
  3190.     {
  3191.       int center_x;
  3192.       int center_y;
  3193.       int threshold;
  3194.  
  3195.       if (windowsize == Small)
  3196.     {
  3197.       center_x = ATARI_WIDTH / 2;
  3198.       center_y = ATARI_HEIGHT / 2;
  3199.       threshold = 32;
  3200.     }
  3201.       else if (windowsize == Large)
  3202.     {
  3203.       center_x = (ATARI_WIDTH * 2) / 2;
  3204.       center_y = (ATARI_HEIGHT * 2) / 2;
  3205.       threshold = 64;
  3206.     }
  3207.       else
  3208.     {
  3209.       center_x = (ATARI_WIDTH * 3) / 2;
  3210.       center_y = (ATARI_HEIGHT * 3) / 2;
  3211.       threshold = 96;
  3212.     }
  3213.  
  3214.       if (win_x_return < (center_x - threshold))
  3215.     mouse_stick &= 0xfb;
  3216.       if (win_x_return > (center_x + threshold))
  3217.     mouse_stick &= 0xf7;
  3218.       if (win_y_return < (center_y - threshold))
  3219.     mouse_stick &= 0xfe;
  3220.       if (win_y_return > (center_y + threshold))
  3221.     mouse_stick &= 0xfd;
  3222.     }
  3223.   else
  3224.     {
  3225.       if (mask_return)
  3226.     mouse_stick &= 0xfb;
  3227.     }
  3228. }
  3229.  
  3230. #ifdef LINUX_JOYSTICK
  3231.  
  3232. void read_joystick (int js, int centre_x, int centre_y)
  3233. {
  3234.   const int threshold = 50;
  3235.   int status;
  3236.  
  3237.   mouse_stick = 0x0f;
  3238.  
  3239.   status = read (js, &js_data, JS_RETURN);
  3240.   if (status != JS_RETURN)
  3241.     {
  3242.       perror ("/dev/js");
  3243.       exit (1);
  3244.     }
  3245.  
  3246.   if (js_data.x < (centre_x - threshold))
  3247.     mouse_stick &= 0xfb;
  3248.   if (js_data.x > (centre_x + threshold))
  3249.     mouse_stick &= 0xf7;
  3250.   if (js_data.y < (centre_y - threshold))
  3251.     mouse_stick &= 0xfe;
  3252.   if (js_data.y > (centre_y + threshold))
  3253.     mouse_stick &= 0xfd;
  3254. }
  3255. #endif
  3256.  
  3257.  
  3258.     /* The scheme is from xkobo, which has great keypad control */
  3259. unsigned char keypad_stick()
  3260. {
  3261.     static unsigned char stick=STICK_CENTRE;
  3262.  
  3263.     if (keypad_changed)
  3264.         {
  3265.         int lr;
  3266.         int ud;
  3267.  
  3268.         keypad_changed=0;
  3269.  
  3270.  
  3271.  
  3272.         lr=keypad_l +keypad_ul +keypad_dl -keypad_r -keypad_ur -keypad_dr;
  3273.         ud=keypad_u +keypad_ul +keypad_ur -keypad_d -keypad_dl -keypad_dr;
  3274.  
  3275.         if (!lr)
  3276.         {
  3277.         if (!ud)        stick=    STICK_CENTRE;
  3278.         else if (ud > 0)    stick=    STICK_FORWARD;
  3279.         else             stick=    STICK_BACK;
  3280.         }
  3281.         else if (lr > 0)
  3282.         {
  3283.         if (!ud)        stick=    STICK_LEFT;
  3284.         else if (ud > 0)    stick=    STICK_UL;
  3285.         else            stick=    STICK_LL;
  3286.         }
  3287.         else
  3288.         {
  3289.         if (!ud)        stick=    STICK_RIGHT;
  3290.         else if (ud > 0)    stick=    STICK_UR;
  3291.         else            stick=    STICK_LR;
  3292.         }
  3293.         }
  3294.     return stick;
  3295. }
  3296.  
  3297.  
  3298. int Atari_PORT (int num)
  3299. {
  3300.   int nibble_0 = 0x0f;
  3301.   int nibble_1 = 0x0f;
  3302.  
  3303.   if (num == 0)
  3304.     {
  3305.       if (keypad_mode == 0)
  3306.     nibble_0 = keypad_stick();
  3307.       else if (keypad_mode == 1)
  3308.     nibble_1 = keypad_stick();
  3309.  
  3310.       if (mouse_mode == 0)
  3311.     {
  3312.       mouse_joystick (mouse_mode);
  3313.       nibble_0 = mouse_stick;
  3314.     }
  3315.       else if (mouse_mode == 1)
  3316.     {
  3317.       mouse_joystick (mouse_mode);
  3318.       nibble_1 = mouse_stick;
  3319.     }
  3320.  
  3321. #ifdef LINUX_JOYSTICK
  3322.       if (js0_mode == 0)
  3323.     {
  3324.       read_joystick (js0, js0_centre_x, js0_centre_y);
  3325.       nibble_0 = mouse_stick;
  3326.     }
  3327.       else if (js0_mode == 1)
  3328.     {
  3329.       read_joystick (js0, js0_centre_x, js0_centre_y);
  3330.       nibble_1 = mouse_stick;
  3331.     }
  3332.  
  3333.       if (js1_mode == 0)
  3334.     {
  3335.       read_joystick (js1, js1_centre_x, js1_centre_y);
  3336.       nibble_0 = mouse_stick;
  3337.     }
  3338.       else if (js1_mode == 1)
  3339.     {
  3340.       read_joystick (js1, js1_centre_x, js1_centre_y);
  3341.       nibble_1 = mouse_stick;
  3342.     }
  3343. #endif
  3344.     }
  3345.   else
  3346.     {
  3347.       if (keypad_mode == 2)
  3348.     nibble_0 = keypad_stick();
  3349.       else if (keypad_mode == 3)
  3350.     nibble_1 = keypad_stick();
  3351.  
  3352.       if (mouse_mode == 2)
  3353.     {
  3354.       mouse_joystick (mouse_mode);
  3355.       nibble_0 = mouse_stick;
  3356.     }
  3357.       else if (mouse_mode == 3)
  3358.     {
  3359.       mouse_joystick (mouse_mode);
  3360.       nibble_1 = mouse_stick;
  3361.     }
  3362.  
  3363. #ifdef LINUX_JOYSTICK
  3364.       if (js0_mode == 2)
  3365.     {
  3366.       read_joystick (js0, js0_centre_x, js0_centre_y);
  3367.       nibble_0 = mouse_stick;
  3368.     }
  3369.       else if (js0_mode == 3)
  3370.     {
  3371.       read_joystick (js0, js0_centre_x, js0_centre_y);
  3372.       nibble_1 = mouse_stick;
  3373.     }
  3374.  
  3375.       if (js1_mode == 2)
  3376.     {
  3377.       read_joystick (js1, js1_centre_x, js1_centre_y);
  3378.       nibble_0 = mouse_stick;
  3379.     }
  3380.       else if (js1_mode == 3)
  3381.     {
  3382.       read_joystick (js1, js1_centre_x, js1_centre_y);
  3383.       nibble_1 = mouse_stick;
  3384.     }
  3385. #endif
  3386.     }
  3387.  
  3388.   return (nibble_1 << 4) | nibble_0;
  3389. }
  3390.  
  3391. int Atari_TRIG (int num)
  3392. {
  3393.   int    trig = 1;    /* Trigger not pressed */
  3394.  
  3395.   if (num == keypad_mode)
  3396.     {
  3397.       trig = keypad_trig;
  3398.     }
  3399.  
  3400.   if (num == mouse_mode)
  3401.     {
  3402.       Window    root_return;
  3403.       Window    child_return;
  3404.       int    root_x_return;
  3405.       int    root_y_return;
  3406.       int    win_x_return;
  3407.       int    win_y_return;
  3408.       unsigned int mask_return;
  3409.  
  3410.       if (XQueryPointer (display, window, &root_return, &child_return,
  3411.              &root_x_return, &root_y_return,
  3412.              &win_x_return, &win_y_return,
  3413.              &mask_return))
  3414.     {
  3415.       if (mask_return)
  3416.         trig = 0;
  3417.     }
  3418.     }
  3419.  
  3420. #ifdef LINUX_JOYSTICK
  3421.   if (num == js0_mode)
  3422.     {
  3423.       int status;
  3424.  
  3425.       status = read (js0, &js_data, JS_RETURN);
  3426.       if (status != JS_RETURN)
  3427.     {
  3428.       perror ("/dev/js0");
  3429.       exit (1);
  3430.     }
  3431.  
  3432.       if (js_data.buttons & 0x01)
  3433.     trig = 0;
  3434.       else
  3435.     trig = 1;
  3436.  
  3437.       if (js_data.buttons & 0x02)
  3438.     xview_keycode = AKEY_SPACE;
  3439.     }
  3440.  
  3441.   if (num == js1_mode)
  3442.     {
  3443.       int status;
  3444.  
  3445.       status = read (js1, &js_data, JS_RETURN);
  3446.       if (status != JS_RETURN)
  3447.     {
  3448.       perror ("/dev/js1");
  3449.       exit (1);
  3450.     }
  3451.  
  3452.       trig = (js_data.buttons & 0x0f) ? 0 : 1;
  3453.     }
  3454. #endif
  3455.  
  3456.   return trig;
  3457. }
  3458.  
  3459. int Atari_POT (int num)
  3460. {
  3461.   int    pot;
  3462.  
  3463.   if (num == (mouse_mode - 4))
  3464.     {
  3465.       Window root_return;
  3466.       Window child_return;
  3467.       int root_x_return;
  3468.       int root_y_return;
  3469.       int win_x_return;
  3470.       int win_y_return;
  3471.       unsigned int mask_return;
  3472.  
  3473.       if (XQueryPointer (display, window, &root_return,
  3474.              &child_return, &root_x_return, &root_y_return,
  3475.              &win_x_return, &win_y_return, &mask_return))
  3476.     {
  3477.       switch (windowsize)
  3478.       {
  3479.       case Small:
  3480.           pot = ((float)((ATARI_WIDTH) - win_x_return) /
  3481.              (float)(ATARI_WIDTH)) * 228;
  3482.           break;
  3483.       case Large:
  3484.           pot = ((float)((ATARI_WIDTH * 2) - win_x_return) /
  3485.              (float)(ATARI_WIDTH * 2)) * 228;
  3486.           break;
  3487.       default:
  3488.           pot = ((float)((ATARI_WIDTH * 3) - win_x_return) /
  3489.              (float)(ATARI_WIDTH * 3)) * 228;
  3490.           break;
  3491.           }
  3492.         }
  3493.       else
  3494.         {
  3495.       pot = 228;
  3496.     }
  3497.     }
  3498.   else
  3499.     {
  3500.       pot = 228;
  3501.     }
  3502.  
  3503.   return pot;
  3504. }
  3505.  
  3506. int Atari_CONSOL (void)
  3507. {
  3508.   int temp;
  3509.  
  3510.   if (menu_consol != 7)
  3511.     {
  3512.       temp = menu_consol;
  3513.       menu_consol = 0x07;
  3514.     }
  3515.   else
  3516.     {
  3517.       temp = keyboard_consol;
  3518.     }
  3519.  
  3520.   return temp;
  3521. }
  3522.  
  3523. UBYTE Atari_Keyboard_State(void)
  3524. {
  3525.     return ~((SHIFTPRESSED<<3) | (KEYPRESSED<<2));
  3526. }
  3527.  
  3528. #define USE_LED 3        /* Use 1..32.  3 might be SCROLL_LOCK */
  3529.  
  3530. void Atari_Set_LED(int on)
  3531. {
  3532.     XKeyboardControl control={0, 0, 0, 0,
  3533.             1<<(USE_LED-1), (on ? LedModeOn : LedModeOff),
  3534.             0, 0};
  3535.     
  3536.     XChangeKeyboardControl(display, KBLed | KBLedMode, &control);
  3537. }
  3538.